Update of /cvsroot/rails/18xx/rails/game In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv21151/rails/game Modified Files: StockRound.java Bank.java GameManagerI.java Game.java PlayerManager.java Round.java Player.java GameManager.java Log Message: Implemented the certificate limit change after CGR formation. Have moved the initial limits out of Player into PlayerManager. PlayerManager is now a configurable component; this has affected all Game.xml files. The above has has effects on other classes, in particular StockRound. Index: GameManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/GameManager.java,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** GameManager.java 4 May 2009 20:29:14 -0000 1.45 --- GameManager.java 3 Sep 2009 21:36:53 -0000 1.46 *************** *** 904,907 **** --- 904,911 ---- } + public PlayerManager getPlayerManager() { + return playerManager; + } + public TrainManagerI getTrainManager () { return trainManager; Index: PlayerManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/PlayerManager.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** PlayerManager.java 4 Jun 2008 19:00:32 -0000 1.7 --- PlayerManager.java 3 Sep 2009 21:36:53 -0000 1.8 *************** *** 4,15 **** import java.util.*; ! public class PlayerManager { ! int numberOfPlayers; private List<Player> players; private List<String> playerNames; private Map<String, Player> playerMap; ! public PlayerManager(List<String> playerNames) { Player player; --- 4,52 ---- import java.util.*; ! import rails.util.LocalText; ! import rails.util.Tag; ! public class PlayerManager implements ConfigurableComponentI { ! ! private int numberOfPlayers; private List<Player> players; private List<String> playerNames; private Map<String, Player> playerMap; ! public int maxPlayers; ! ! public int minPlayers; ! ! private int[] playerStartCash = new int[Player.MAX_PLAYERS]; ! ! private int[] playerCertificateLimits = new int[Player.MAX_PLAYERS]; ! ! private int playerCertificateLimit = 0; ! ! public PlayerManager() { ! ! } ! ! public void configureFromXML(Tag tag) throws ConfigurationException { ! ! int number, startCash, certLimit; ! ! List<Tag> playerTags = tag.getChildren("Players"); ! minPlayers = 99; ! maxPlayers = 0; ! for (Tag playerTag : playerTags) { ! number = playerTag.getAttributeAsInteger("number"); ! startCash = playerTag.getAttributeAsInteger("cash"); ! playerStartCash[number] = startCash; ! certLimit = playerTag.getAttributeAsInteger("certLimit"); ! playerCertificateLimits[number] = certLimit; ! ! minPlayers = Math.min(minPlayers, number); ! maxPlayers = Math.max(maxPlayers, number); ! } ! } ! ! public void setPlayers (List<String> playerNames, int startCash) { ! Player player; *************** *** 20,29 **** playerMap = new HashMap<String, Player>(numberOfPlayers); for (String playerName : playerNames) { ! player = new Player(playerName); players.add(player); playerMap.put(playerName, player); } } --- 57,75 ---- playerMap = new HashMap<String, Player>(numberOfPlayers); + int playerIndex = 0; for (String playerName : playerNames) { ! player = new Player(playerName, playerIndex++); players.add(player); playerMap.put(playerName, player); + Bank.transferCash(null, player, getStartCash()); + ReportBuffer.add(LocalText.getText("PlayerIs", + playerIndex, + player.getName() )); } + ReportBuffer.add(LocalText.getText("PlayerCash", Bank.format(startCash))); + ReportBuffer.add(LocalText.getText("BankHas", + Bank.format(Bank.getInstance().getCash()))); + playerCertificateLimit = playerCertificateLimits[numberOfPlayers]; } *************** *** 46,49 **** --- 92,107 ---- return players.get(index); } + + public int getStartCash () { + return playerStartCash[numberOfPlayers]; + } + + public int getPlayerCertificateLimit() { + return playerCertificateLimit; + } + + public void setPlayerCertificateLimit(int playerCertificateLimit) { + this.playerCertificateLimit = playerCertificateLimit; + } } Index: Bank.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Bank.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Bank.java 28 Aug 2009 20:24:39 -0000 1.10 --- Bank.java 3 Sep 2009 21:36:53 -0000 1.11 *************** *** 94,98 **** */ public void configureFromXML(Tag tag) throws ConfigurationException { - int number, startCash, certLimit; // Parse the Bank element --- 94,97 ---- *************** *** 120,138 **** format(money.getCash()))); - List<Tag> playerTags = tag.getChildren("Players"); - int minPlayers = 99; - int maxPlayers = 0; - for (Tag playerTag : playerTags) { - number = playerTag.getAttributeAsInteger("number"); - startCash = playerTag.getAttributeAsInteger("cash"); - certLimit = playerTag.getAttributeAsInteger("certLimit"); - - Player.setLimits(number, startCash, certLimit); - - minPlayers = Math.min(minPlayers, number); - maxPlayers = Math.max(maxPlayers, number); - } - Player.MIN_PLAYERS = minPlayers; - Player.MAX_PLAYERS = maxPlayers; } --- 119,122 ---- Index: Round.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Round.java,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** Round.java 19 Jul 2009 19:24:21 -0000 1.19 --- Round.java 3 Sep 2009 21:36:53 -0000 1.20 *************** *** 32,35 **** --- 32,36 ---- protected GameManagerI gameManager = null; protected CompanyManagerI companyManager = null; + protected PlayerManager playerManager = null; protected Class<? extends RoundI> roundTypeForUI = null; *************** *** 53,56 **** --- 54,58 ---- } else { companyManager = aGameManager.getCompanyManager(); + playerManager = aGameManager.getPlayerManager(); } Index: Game.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Game.java,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** Game.java 28 Aug 2009 20:25:28 -0000 1.23 --- Game.java 3 Sep 2009 21:36:53 -0000 1.24 *************** *** 35,38 **** --- 35,40 ---- protected List<String> directories = new ArrayList<String>(); protected Map<String, String> gameOptions; + + protected List<String> players; protected static Logger log = *************** *** 60,64 **** directories.add("data/" + name); ! playerManager = new PlayerManager(players); } --- 62,67 ---- directories.add("data/" + name); ! //playerManager = new PlayerManager(players); ! this.players = players; } *************** *** 94,97 **** --- 97,106 ---- componentManager.finishPreparation(); + playerManager = (PlayerManager) componentManager.findComponent("PlayerManager"); + if (playerManager == null) { + throw new ConfigurationException( + "No PlayerManager XML element found in file " + GAME_XML_FILE); + } + bank = (Bank) componentManager.findComponent("Bank"); if (bank == null) { *************** *** 99,102 **** --- 108,112 ---- "No Bank XML element found in file " + GAME_XML_FILE); } + companyManager = (CompanyManagerI) componentManager.findComponent(CompanyManagerI.COMPONENT_NAME); *************** *** 141,144 **** --- 151,156 ---- * only be done after all XML has been processed. */ + playerManager.setPlayers(players, playerManager.getStartCash()); + companyManager.initCompanies(gameManager); bank.initCertificates(); *************** *** 157,162 **** MapManager.assignHomesAndDestinations(); - Player.initPlayers(playerManager.getPlayers()); - return true; } --- 169,172 ---- Index: Player.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Player.java,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Player.java 3 Sep 2009 18:33:28 -0000 1.18 --- Player.java 3 Sep 2009 21:36:53 -0000 1.19 *************** *** 2,9 **** package rails.game; - import java.util.List; - import rails.game.model.*; - import rails.util.LocalText; /** --- 2,6 ---- *************** *** 19,29 **** public static int MIN_PLAYERS = 2; ! ! private static int[] playerStartCash = new int[MAX_PLAYERS]; ! ! private static int[] playerCertificateLimits = new int[MAX_PLAYERS]; ! ! private static int playerCertificateLimit = 0; ! private static int playerShareLimit = DEFAULT_PLAYER_SHARE_LIMIT; // May need to become an array --- 16,20 ---- public static int MIN_PLAYERS = 2; ! private static int playerShareLimit = DEFAULT_PLAYER_SHARE_LIMIT; // May need to become an array *************** *** 45,103 **** private Portfolio portfolio = null; ! public static void setLimits(int number, int cash, int certLimit) { ! if (number > 1 && number <= MAX_PLAYERS) { ! playerStartCash[number] = cash; ! playerCertificateLimits[number] = certLimit; ! } ! } ! ! /** ! * Initialises each Player's parameters which depend on the number of ! * players. To be called when all Players have been added. ! * ! */ ! public static void initPlayers(List<Player> players) { ! int numberOfPlayers = players.size(); ! int startCash = playerStartCash[numberOfPlayers]; ! ! // Give each player the initial cash amount ! int index = 0; ! for (Player player : players) { ! player.index = index++; ! Bank.transferCash(null, player, startCash); ! ReportBuffer.add(LocalText.getText("PlayerIs", ! index, ! player.getName() )); ! } ! ReportBuffer.add(LocalText.getText("PlayerCash", Bank.format(startCash))); ! ReportBuffer.add(LocalText.getText("BankHas", ! Bank.format(Bank.getInstance().getCash()))); ! ! // Set the sertificate limit ! playerCertificateLimit = playerCertificateLimits[numberOfPlayers]; ! } ! ! /** ! * @return Certificate Limit for Players ! */ ! public static int getCertLimit() { ! return playerCertificateLimit; ! } ! ! /** In some games, the cert limit can change during the game (e.g. 1856) */ ! public static void setPlayerCertificateLimit(int playerCertificateLimit) { ! Player.playerCertificateLimit = playerCertificateLimit; ! } ! ! public static void setShareLimit(int percentage) { ! playerShareLimit = percentage; ! } ! ! public static int getShareLimit() { ! return playerShareLimit; ! } ! ! public Player(String name) { this.name = name; portfolio = new Portfolio(name, this); freeCash = new CalculatedMoneyModel(this, "getFreeCash"); --- 36,42 ---- private Portfolio portfolio = null; ! public Player(String name, int index) { this.name = name; + this.index = index; portfolio = new Portfolio(name, this); freeCash = new CalculatedMoneyModel(this, "getFreeCash"); *************** *** 109,159 **** } ! public boolean isOverLimits() { ! ! // Over the total certificate hold Limit? ! if (portfolio.getCertificateCount() > playerCertificateLimit) ! return true; ! ! // Over the hold limit of any company? ! for (PublicCompanyI company : Game.getCompanyManager().getAllPublicCompanies()) { ! if (company.hasStarted() && company.hasStockPrice() ! && !mayBuyCompanyShare(company, 0)) return true; ! } ! ! return false; ! } ! ! /** ! * Check if a player may buy the given number of certificates. ! * ! * @param number Number of certificates to buy (usually 1 but not always ! * so). ! * @return True if it is allowed. ! */ ! public boolean mayBuyCertificate(PublicCompanyI comp, int number) { ! if (comp.hasFloated() && comp.getCurrentSpace().isNoCertLimit()) ! return true; ! if (portfolio.getCertificateCount() + number > playerCertificateLimit) ! return false; ! return true; ! } ! ! /** ! * Check if a player may buy the given number of shares from a given ! * company, given the "hold limit" per company, that is the percentage of ! * shares of one company that a player may hold (typically 60%). ! * ! * @param company The company from which to buy ! * @param number The number of shares (usually 1 but not always so). ! * @return True if it is allowed. ! */ ! public boolean mayBuyCompanyShare(PublicCompanyI company, int number) { ! // Check for per-company share limit ! if (portfolio.getShare(company) + number * company.getShareUnit() > playerShareLimit ! && !company.getCurrentSpace().isNoHoldLimit()) return false; ! return true; ! } ! ! /** * Return the number of <i>additional</i> shares of a certain company and * of a certain size that a player may buy, given the share "hold limit" per --- 48,52 ---- } ! /** * Return the number of <i>additional</i> shares of a certain company and * of a certain size that a player may buy, given the share "hold limit" per *************** *** 309,312 **** --- 202,212 ---- } + public static void setShareLimit(int percentage) { + playerShareLimit = percentage; + } + + public static int getShareLimit() { + return playerShareLimit; + } /** * Compare Players by their total worth, in descending order. This method Index: StockRound.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/StockRound.java,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** StockRound.java 2 Sep 2009 21:47:47 -0000 1.38 --- StockRound.java 3 Sep 2009 21:36:53 -0000 1.39 *************** *** 224,232 **** number = 1; /* Would the player exceed the per-company share hold limit? */ ! if (!currentPlayer.mayBuyCompanyShare(comp, number)) continue; /* Would the player exceed the total certificate limit? */ if (!stockSpace.isNoCertLimit() ! && !currentPlayer.mayBuyCertificate(comp, number)) continue; } --- 224,232 ---- number = 1; /* Would the player exceed the per-company share hold limit? */ ! if (!playerMayBuyCompanyShare(currentPlayer, comp, number)) continue; /* Would the player exceed the total certificate limit? */ if (!stockSpace.isNoCertLimit() ! && !playerMayBuyCertificate(currentPlayer, comp, number)) continue; } *************** *** 252,261 **** cert = certs.get(0); if (isSaleRecorded(currentPlayer, company)) continue; ! if (!currentPlayer.mayBuyCompanyShare(company, 1)) continue; if (currentPlayer.maxAllowedNumberOfSharesToBuy(company, certs.get(0).getShare()) < 1) continue; stockSpace = company.getCurrentSpace(); if (!stockSpace.isNoCertLimit() ! && !currentPlayer.mayBuyCertificate(company, 1)) continue; if (company.getMarketPrice() <= playerCash) { possibleActions.add(new BuyCertificate(cert, --- 252,261 ---- cert = certs.get(0); if (isSaleRecorded(currentPlayer, company)) continue; ! if (!playerMayBuyCompanyShare(currentPlayer, company, 1)) continue; if (currentPlayer.maxAllowedNumberOfSharesToBuy(company, certs.get(0).getShare()) < 1) continue; stockSpace = company.getCurrentSpace(); if (!stockSpace.isNoCertLimit() ! && !playerMayBuyCertificate(currentPlayer, company, 1)) continue; if (company.getMarketPrice() <= playerCash) { possibleActions.add(new BuyCertificate(cert, *************** *** 492,496 **** numberOfCertsToBuy = shares - (cert.getShares() - 1); // Check if the player may buy that many certificates. ! if (!currentPlayer.mayBuyCertificate(company, numberOfCertsToBuy)) { errMsg = LocalText.getText("CantBuyMoreCerts"); break; --- 492,496 ---- numberOfCertsToBuy = shares - (cert.getShares() - 1); // Check if the player may buy that many certificates. ! if (!playerMayBuyCertificate(currentPlayer, company, numberOfCertsToBuy)) { errMsg = LocalText.getText("CantBuyMoreCerts"); break; *************** *** 665,673 **** // (shortcut: assume 1 cert == 1 certificate) if (!currentSpace.isNoCertLimit() ! && !currentPlayer.mayBuyCertificate(company, shares)) { errMsg = currentPlayer.getName() + LocalText.getText("WouldExceedCertLimit", ! String.valueOf(Player.getCertLimit())); break; } --- 665,673 ---- // (shortcut: assume 1 cert == 1 certificate) if (!currentSpace.isNoCertLimit() ! && !playerMayBuyCertificate(currentPlayer, company, shares)) { errMsg = currentPlayer.getName() + LocalText.getText("WouldExceedCertLimit", ! String.valueOf(playerManager.getPlayerCertificateLimit())); break; } *************** *** 675,679 **** // Check if player would exceed the per-company share limit if (!currentSpace.isNoHoldLimit() ! && !currentPlayer.mayBuyCompanyShare(company, shares)) { errMsg = currentPlayer.getName() --- 675,679 ---- // Check if player would exceed the per-company share limit if (!currentSpace.isNoHoldLimit() ! && !playerMayBuyCompanyShare(currentPlayer, company, shares)) { errMsg = currentPlayer.getName() *************** *** 1034,1038 **** if (sp instanceof ExchangeForShare) { ! boolean result = ((ExchangeForShare) sp).execute(); if (result) hasActed.set(true); return result; --- 1034,1038 ---- if (sp instanceof ExchangeForShare) { ! boolean result = ((ExchangeForShare) sp).execute(this); if (result) hasActed.set(true); return result; *************** *** 1169,1176 **** */ public boolean mayCurrentPlayerBuyAnything() { ! return !currentPlayer.isOverLimits() && companyBoughtThisTurnWrapper.getObject() == null; } public static void setNoSaleInFirstSR() { noSaleInFirstSR = true; --- 1169,1223 ---- */ public boolean mayCurrentPlayerBuyAnything() { ! return !playerIsOverLimits(currentPlayer) && companyBoughtThisTurnWrapper.getObject() == null; } + protected boolean playerIsOverLimits(Player player) { + + // Over the total certificate hold Limit? + if (player.getPortfolio().getCertificateCount() > playerManager.getPlayerCertificateLimit()) + return true; + + // Over the hold limit of any company? + for (PublicCompanyI company : Game.getCompanyManager().getAllPublicCompanies()) { + if (company.hasStarted() && company.hasStockPrice() + && !playerMayBuyCompanyShare(player, company, 0)) return true; + } + + return false; + } + + /** + * Check if a player may buy the given number of certificates. + * + * @param number Number of certificates to buy (usually 1 but not always + * so). + * @return True if it is allowed. + */ + public boolean playerMayBuyCertificate(Player player, PublicCompanyI comp, int number) { + if (comp.hasFloated() && comp.getCurrentSpace().isNoCertLimit()) + return true; + if (player.getPortfolio().getCertificateCount() + number > playerManager.getPlayerCertificateLimit()) + return false; + return true; + } + + /** + * Check if a player may buy the given number of shares from a given + * company, given the "hold limit" per company, that is the percentage of + * shares of one company that a player may hold (typically 60%). + * + * @param company The company from which to buy + * @param number The number of shares (usually 1 but not always so). + * @return True if it is allowed. + */ + public boolean playerMayBuyCompanyShare(Player player, PublicCompanyI company, int number) { + // Check for per-company share limit + if (player.getPortfolio().getShare(company) + number * company.getShareUnit() > Player.getShareLimit() + && !company.getCurrentSpace().isNoHoldLimit()) return false; + return true; + } + + public static void setNoSaleInFirstSR() { noSaleInFirstSR = true; Index: GameManagerI.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/GameManagerI.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** GameManagerI.java 4 May 2009 20:29:14 -0000 1.3 --- GameManagerI.java 3 Sep 2009 21:36:53 -0000 1.4 *************** *** 144,147 **** --- 144,148 ---- public abstract TrainManagerI getTrainManager (); + public PlayerManager getPlayerManager(); |