You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(46) |
Dec
(57) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(51) |
Feb
(10) |
Mar
|
Apr
|
May
(14) |
Jun
|
Jul
(13) |
Aug
(30) |
Sep
(83) |
Oct
(56) |
Nov
(148) |
Dec
(107) |
2010 |
Jan
(260) |
Feb
(164) |
Mar
(183) |
Apr
(99) |
May
(160) |
Jun
(40) |
Jul
(33) |
Aug
(48) |
Sep
(22) |
Oct
(24) |
Nov
(1) |
Dec
(12) |
2011 |
Jan
(6) |
Feb
(15) |
Mar
(13) |
Apr
(37) |
May
(27) |
Jun
(29) |
Jul
(33) |
Aug
(20) |
Sep
(17) |
Oct
(20) |
Nov
(33) |
Dec
(17) |
2012 |
Jan
(39) |
Feb
(38) |
Mar
(20) |
Apr
(21) |
May
(17) |
Jun
(22) |
Jul
(16) |
Aug
(3) |
Sep
(9) |
Oct
(10) |
Nov
|
Dec
|
From: <ev...@us...> - 2010-07-04 20:51:40
|
Revision: 1332 http://rails.svn.sourceforge.net/rails/?rev=1332&view=rev Author: evos Date: 2010-07-04 20:51:33 +0000 (Sun, 04 Jul 2010) Log Message: ----------- Fixed import expansion Modified Paths: -------------- trunk/18xx/rails/game/GameManager.java trunk/18xx/rails/game/StockRound.java Modified: trunk/18xx/rails/game/GameManager.java =================================================================== --- trunk/18xx/rails/game/GameManager.java 2010-07-04 20:44:29 UTC (rev 1331) +++ trunk/18xx/rails/game/GameManager.java 2010-07-04 20:51:33 UTC (rev 1332) @@ -1,22 +1,10 @@ /* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/GameManager.java,v 1.107 2010/06/17 21:35:54 evos Exp $ */ package rails.game; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.PrintWriter; +import java.io.*; import java.lang.reflect.Constructor; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; import org.apache.log4j.Logger; import org.apache.log4j.NDC; @@ -24,28 +12,13 @@ import rails.algorithms.RevenueManager; import rails.common.GuiDef; import rails.common.GuiHints; -import rails.game.action.GameAction; -import rails.game.action.NullAction; -import rails.game.action.PossibleAction; -import rails.game.action.PossibleActions; -import rails.game.action.RepayLoans; -import rails.game.correct.CorrectionAction; -import rails.game.correct.CorrectionManagerI; -import rails.game.correct.CorrectionType; -import rails.game.move.AddToList; -import rails.game.move.CashMove; -import rails.game.move.MoveStack; -import rails.game.move.Moveable; +import rails.game.action.*; +import rails.game.correct.*; +import rails.game.move.*; import rails.game.special.SpecialPropertyI; import rails.game.special.SpecialTokenLay; -import rails.game.state.BooleanState; -import rails.game.state.IntegerState; -import rails.game.state.State; -import rails.util.BuildInfo; -import rails.util.Config; -import rails.util.LocalText; -import rails.util.Tag; -import rails.util.Util; +import rails.game.state.*; +import rails.util.*; /** * This class manages the playing rounds by supervising all implementations of Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-07-04 20:44:29 UTC (rev 1331) +++ trunk/18xx/rails/game/StockRound.java 2010-07-04 20:51:33 UTC (rev 1332) @@ -1,29 +1,12 @@ package rails.game; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import rails.common.GuiDef; -import rails.game.action.BuyCertificate; -import rails.game.action.NullAction; -import rails.game.action.PossibleAction; -import rails.game.action.RequestTurn; -import rails.game.action.SellShares; -import rails.game.action.StartCompany; -import rails.game.action.UseSpecialProperty; -import rails.game.move.AddToList; -import rails.game.move.CashMove; -import rails.game.move.DoubleMapChange; -import rails.game.special.ExchangeForShare; -import rails.game.special.SpecialProperty; -import rails.game.special.SpecialPropertyI; -import rails.game.state.BooleanState; -import rails.game.state.IntegerState; -import rails.game.state.State; +import rails.game.action.*; +import rails.game.move.*; +import rails.game.special.*; +import rails.game.state.*; import rails.util.LocalText; /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2010-07-04 20:44:36
|
Revision: 1331 http://rails.svn.sourceforge.net/rails/?rev=1331&view=rev Author: evos Date: 2010-07-04 20:44:29 +0000 (Sun, 04 Jul 2010) Log Message: ----------- Fixed price token order changes at end of SR Modified Paths: -------------- trunk/18xx/rails/game/GameManager.java trunk/18xx/rails/game/GameManagerI.java trunk/18xx/rails/game/StockRound.java Modified: trunk/18xx/rails/game/GameManager.java =================================================================== --- trunk/18xx/rails/game/GameManager.java 2010-07-04 15:17:14 UTC (rev 1330) +++ trunk/18xx/rails/game/GameManager.java 2010-07-04 20:44:29 UTC (rev 1331) @@ -1,10 +1,22 @@ /* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/GameManager.java,v 1.107 2010/06/17 21:35:54 evos Exp $ */ package rails.game; -import java.io.*; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; import org.apache.log4j.Logger; import org.apache.log4j.NDC; @@ -12,15 +24,28 @@ import rails.algorithms.RevenueManager; import rails.common.GuiDef; import rails.common.GuiHints; -import rails.game.action.*; -import rails.game.correct.*; -import rails.game.move.*; +import rails.game.action.GameAction; +import rails.game.action.NullAction; +import rails.game.action.PossibleAction; +import rails.game.action.PossibleActions; +import rails.game.action.RepayLoans; +import rails.game.correct.CorrectionAction; +import rails.game.correct.CorrectionManagerI; +import rails.game.correct.CorrectionType; +import rails.game.move.AddToList; +import rails.game.move.CashMove; +import rails.game.move.MoveStack; +import rails.game.move.Moveable; import rails.game.special.SpecialPropertyI; import rails.game.special.SpecialTokenLay; import rails.game.state.BooleanState; import rails.game.state.IntegerState; import rails.game.state.State; -import rails.util.*; +import rails.util.BuildInfo; +import rails.util.Config; +import rails.util.LocalText; +import rails.util.Tag; +import rails.util.Util; /** * This class manages the playing rounds by supervising all implementations of @@ -34,11 +59,11 @@ * action package. */ public static final long saveFileVersionID = - saveFileHeaderVersionID * PossibleAction.serialVersionUID; + saveFileHeaderVersionID * PossibleAction.serialVersionUID; protected Class<? extends StockRound> stockRoundClass = StockRound.class; protected Class<? extends OperatingRound> operatingRoundClass = - OperatingRound.class; + OperatingRound.class; // Variable UI Class names protected String gameUIManagerClassName = GuiDef.getDefaultClassName(GuiDef.ClassName.GAME_UI_MANAGER); @@ -75,7 +100,7 @@ new HashMap<String, Portfolio> (); protected IntegerState playerCertificateLimit - = new IntegerState ("PlayerCertificateLimit", 0); + = new IntegerState ("PlayerCertificateLimit", 0); protected int currentNumberOfOperatingRounds = 1; protected boolean skipFirstStockRound = false; protected boolean showCompositeORNumber = true; @@ -85,10 +110,10 @@ protected boolean gameEndsAfterSetOfORs = true; protected EnumMap<GameDef.Parm, Object> gameParameters - = new EnumMap<GameDef.Parm, Object>(GameDef.Parm.class); + = new EnumMap<GameDef.Parm, Object>(GameDef.Parm.class); -// protected EnumSet<CorrectionType> activeCorrections -// = EnumSet.noneOf(CorrectionType.class); + // protected EnumSet<CorrectionType> activeCorrections + // = EnumSet.noneOf(CorrectionType.class); /** * Current round should not be set here but from within the Round classes. @@ -103,9 +128,9 @@ protected IntegerState srNumber = new IntegerState ("SRNumber"); protected IntegerState absoluteORNumber = - new IntegerState("AbsoluteORNUmber"); + new IntegerState("AbsoluteORNUmber"); protected IntegerState relativeORNumber = - new IntegerState("RelativeORNumber"); + new IntegerState("RelativeORNumber"); protected int numOfORs; protected BooleanState gameOver = new BooleanState("GameOver" ,false); @@ -142,7 +167,7 @@ * For now, the key is a fixed string, but that may change in the future. */ protected static Map<String, GameManagerI> gameManagerMap - = new HashMap<String, GameManagerI>(); + = new HashMap<String, GameManagerI>(); /** * The temporary fixed key to the currently single GameManager instance @@ -188,10 +213,10 @@ /** A List of available game options */ protected List<GameOption> availableGameOptions = - new ArrayList<GameOption>(); + new ArrayList<GameOption>(); protected static Logger log = - Logger.getLogger(GameManager.class.getPackage().getName()); + Logger.getLogger(GameManager.class.getPackage().getName()); public GameManager() { gmName = GM_NAME; @@ -209,7 +234,7 @@ Tag gameTag = tag.getChild("Game"); if (gameTag == null) throw new ConfigurationException( - "No Game tag specified in GameManager tag"); + "No Game tag specified in GameManager tag"); gameName = gameTag.getAttributeAsString("name"); if (gameName == null) throw new ConfigurationException("No name specified in Game tag"); @@ -261,19 +286,19 @@ // StockRound class and other properties - Tag srTag = gameParmTag.getChild("StockRound"); + Tag srTag = gameParmTag.getChild("StockRound"); if (srTag != null) { String srClassName = - srTag.getAttributeAsString("class", "rails.game.StockRound"); + srTag.getAttributeAsString("class", "rails.game.StockRound"); try { stockRoundClass = - Class.forName(srClassName).asSubclass(StockRound.class); + Class.forName(srClassName).asSubclass(StockRound.class); } catch (ClassNotFoundException e) { throw new ConfigurationException("Cannot find class " - + srClassName, e); + + srClassName, e); } String stockRoundSequenceRuleString = - srTag.getAttributeAsString("sequence"); + srTag.getAttributeAsString("sequence"); if (Util.hasValue(stockRoundSequenceRuleString)) { if (stockRoundSequenceRuleString.equalsIgnoreCase("SellBuySell")) { setGameParameter(GameDef.Parm.STOCK_ROUND_SEQUENCE, @@ -288,8 +313,8 @@ } skipFirstStockRound = - srTag.getAttributeAsBoolean("skipFirst", - skipFirstStockRound); + srTag.getAttributeAsBoolean("skipFirst", + skipFirstStockRound); for (String ruleTagName : srTag.getChildren().keySet()) { if (ruleTagName.equals("NoSaleInFirstSR")) { @@ -301,21 +326,21 @@ } } - } + } // OperatingRound class Tag orTag = gameParmTag.getChild("OperatingRound"); if (orTag != null) { String orClassName = - orTag.getAttributeAsString("class", - "rails.game.OperatingRound"); + orTag.getAttributeAsString("class", + "rails.game.OperatingRound"); try { operatingRoundClass = - Class.forName(orClassName).asSubclass( - OperatingRound.class); + Class.forName(orClassName).asSubclass( + OperatingRound.class); } catch (ClassNotFoundException e) { throw new ConfigurationException("Cannot find class " - + orClassName, e); + + orClassName, e); } } @@ -354,8 +379,8 @@ Tag bankBreaksTag = endOfGameTag.getChild("BankBreaks"); if (bankBreaksTag != null) { gameEndsWhenBankHasLessOrEqual = - bankBreaksTag.getAttributeAsInteger("limit", - gameEndsWhenBankHasLessOrEqual); + bankBreaksTag.getAttributeAsInteger("limit", + gameEndsWhenBankHasLessOrEqual); String attr = bankBreaksTag.getAttributeAsString("finish"); if (attr.equalsIgnoreCase("SetOfORs")) { gameEndsAfterSetOfORs = true; @@ -372,7 +397,7 @@ Tag gameUIMgrTag = guiClassesTag.getChild("GameUIManager"); if (gameUIMgrTag != null) { gameUIManagerClassName = - gameUIMgrTag.getAttributeAsString("class", gameUIManagerClassName); + gameUIMgrTag.getAttributeAsString("class", gameUIManagerClassName); // Check instantiatability (not sure if this belongs here) canClassBeInstantiated (gameUIManagerClassName); } @@ -381,7 +406,7 @@ Tag orMgrTag = guiClassesTag.getChild("ORUIManager"); if (orMgrTag != null) { orUIManagerClassName = - orMgrTag.getAttributeAsString("class", orUIManagerClassName); + orMgrTag.getAttributeAsString("class", orUIManagerClassName); // Check instantiatability (not sure if this belongs here) canClassBeInstantiated (orUIManagerClassName); } @@ -390,7 +415,7 @@ Tag gameStatusTag = guiClassesTag.getChild("GameStatus"); if (gameStatusTag != null) { gameStatusClassName = - gameStatusTag.getAttributeAsString("class", gameStatusClassName); + gameStatusTag.getAttributeAsString("class", gameStatusClassName); // Check instantiatability (not sure if this belongs here) canClassBeInstantiated (gameStatusClassName); } @@ -399,8 +424,8 @@ Tag statusWindowTag = guiClassesTag.getChild("StatusWindow"); if (statusWindowTag != null) { statusWindowClassName = - statusWindowTag.getAttributeAsString("class", - statusWindowClassName); + statusWindowTag.getAttributeAsString("class", + statusWindowClassName); // Check instantiatability (not sure if this belongs here) canClassBeInstantiated (statusWindowClassName); } @@ -431,7 +456,7 @@ Class.forName(className); } catch (ClassNotFoundException e) { throw new ConfigurationException("Cannot find class " - + className, e); + + className, e); } } @@ -497,7 +522,7 @@ if (company.getMaxNumberOfLoans() != 0) guiParameters.put(GuiDef.Parm.HAS_ANY_COMPANY_LOANS, true); } -loop: for (PrivateCompanyI company : companyManager.getAllPrivateCompanies()) { + loop: for (PrivateCompanyI company : companyManager.getAllPrivateCompanies()) { for (SpecialPropertyI sp : company.getSpecialProperties()) { if (sp instanceof SpecialTokenLay && ((SpecialTokenLay)sp).getToken() instanceof BonusToken) { @@ -513,7 +538,7 @@ guiParameters.put(GuiDef.Parm.NO_MAP_MODE, true); guiParameters.put(GuiDef.Parm.ROUTE_HIGHLIGHT, false); guiParameters.put(GuiDef.Parm.REVENUE_SUGGEST, false); - } else { + } else { if (getGameOption("RouteAwareness").equalsIgnoreCase("Highlight")) { guiParameters.put(GuiDef.Parm.ROUTE_HIGHLIGHT, true); } @@ -561,7 +586,7 @@ startOperatingRound(false); } else if (skipFirstStockRound) { PhaseI currentPhase = - phaseManager.getCurrentPhase(); + phaseManager.getCurrentPhase(); numOfORs = currentPhase.getNumberOfOperatingRounds(); log.info("Phase=" + currentPhase.getName() + " ORs=" + numOfORs); @@ -612,7 +637,7 @@ } catch (Exception e) { log.fatal("Cannot find class " + startRoundClassName, e); - System.exit(1); + System.exit(1); } StartRound startRound = createRound (startRoundClass); startRound.start (); @@ -640,7 +665,7 @@ round = cons.newInstance(this); } catch (Exception e) { log.fatal("Cannot instantiate class " - + roundClass.getName(), e); + + roundClass.getName(), e); System.exit(1); } setRound (round); @@ -648,7 +673,7 @@ } protected <T extends RoundI, U extends RoundI> - T createRound (Class<T> roundClass, U parentRound) { + T createRound (Class<T> roundClass, U parentRound) { if (parentRound == null) { return createRound (roundClass); @@ -660,7 +685,7 @@ round = cons.newInstance(this, parentRound); } catch (Exception e) { log.fatal("Cannot instantiate class " - + roundClass.getName(), e); + + roundClass.getName(), e); System.exit(1); } setRound (round); @@ -710,7 +735,7 @@ interruptedRound = getCurrentRound(); createRound (ShareSellingRound.class, interruptedRound) - .start(player, cashToRaise, unsellableCompany); + .start(player, cashToRaise, unsellableCompany); } /* (non-Javadoc) @@ -799,7 +824,7 @@ if (result && !(action instanceof GameAction) && action.hasActed()) { new AddToList<PossibleAction>(executedActions, action, - "ExecutedActions"); + "ExecutedActions"); } } @@ -834,7 +859,7 @@ // logging of game actions activated for (PossibleAction pa : possibleActions.getList()) { log.debug(((Player) currentPlayer.getObject()).getName() + " may: " - + pa.toString()); + + pa.toString()); } return result; @@ -865,9 +890,9 @@ private boolean processCorrectionActions(PossibleAction a){ - boolean result = false; + boolean result = false; - if (a instanceof CorrectionAction) { + if (a instanceof CorrectionAction) { CorrectionAction ca= (CorrectionAction)a; CorrectionType ct = ca.getCorrectionType(); CorrectionManagerI cm = getCorrectionManager(ct); @@ -899,8 +924,8 @@ log.debug("Action ("+action.getPlayerName()+"): " + action); if (!processCorrectionActions(action) && !getCurrentRound().process(action)) { String msg = "Player "+action.getPlayerName()+"\'s action \"" - +action.toString()+"\"\n in "+getCurrentRound().getRoundName() - +" is considered invalid by the game engine"; + +action.toString()+"\"\n in "+getCurrentRound().getRoundName() + +" is considered invalid by the game engine"; log.error(msg); DisplayBuffer.add(msg); if (moveStack.isOpen()) moveStack.finish(); @@ -918,14 +943,14 @@ throw new Exception("Reload failure", e); } new AddToList<PossibleAction>(executedActions, action, - "ExecutedActions"); + "ExecutedActions"); if (moveStack.isOpen()) moveStack.finish(); - + log.debug("Turn: "+getCurrentPlayer().getName()); } -// DisplayBuffer.clear(); -// previous line removed to allow display of nextPlayerMessages + // DisplayBuffer.clear(); + // previous line removed to allow display of nextPlayerMessages guiHints.clearVisibilityHints(); return true; @@ -938,8 +963,8 @@ try { ObjectOutputStream oos = - new ObjectOutputStream(new FileOutputStream(new File( - filepath))); + new ObjectOutputStream(new FileOutputStream(new File( + filepath))); oos.writeObject(Game.version+" "+BuildInfo.buildDate); oos.writeObject(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); oos.writeObject(saveFileVersionID); @@ -973,8 +998,8 @@ for (MapHex hex:hexRow) if (hex != null) { pw.println(hex.getName() + "," + hex.getCurrentTile().getExternalId() + "," - + hex.getCurrentTileRotation() + "," - + hex.getOrientationName(hex.getCurrentTileRotation()) + + hex.getCurrentTileRotation() + "," + + hex.getOrientationName(hex.getCurrentTileRotation()) ) ; } @@ -1019,8 +1044,8 @@ public void registerBankruptcy() { endedByBankruptcy.set(true); String message = - LocalText.getText("PlayerIsBankrupt", - getCurrentPlayer().getName()); + LocalText.getText("PlayerIsBankrupt", + getCurrentPlayer().getName()); ReportBuffer.add(message); DisplayBuffer.add(message); if (gameEndsWithBankruptcy) { @@ -1044,7 +1069,7 @@ newPresident = null; maxShare = 0; for (int index=getCurrentPlayerIndex()+1; - index<getCurrentPlayerIndex()+numberOfPlayers; index++) { + index<getCurrentPlayerIndex()+numberOfPlayers; index++) { player = getPlayerByIndex(index%numberOfPlayers); share = player.getPortfolio().getShare(company); if (share >= company.getPresidentsShare().getShare() @@ -1068,7 +1093,7 @@ // Finish the share selling round if (getCurrentRound() instanceof ShareSellingRound) { - finishShareSellingRound(); + finishShareSellingRound(); } } } @@ -1142,7 +1167,7 @@ int i = 0; for (Player p : rankedPlayers) { b.add((++i) + ". " + Bank.format(p.getWorth()) + " " - + p.getName()); + + p.getName()); } return b; @@ -1167,8 +1192,8 @@ */ public void setCurrentPlayerIndex(int currentPlayerIndex) { currentPlayerIndex = currentPlayerIndex % numberOfPlayers; -// currentPlayer.set(players.get(currentPlayerIndex)); -// changed to activate nextPlayerMessages + // currentPlayer.set(players.get(currentPlayerIndex)); + // changed to activate nextPlayerMessages setCurrentPlayer(players.get(currentPlayerIndex)); } @@ -1192,7 +1217,7 @@ */ public void setPriorityPlayer() { int priorityPlayerIndex = - (getCurrentPlayer().getIndex() + 1) % numberOfPlayers; + (getCurrentPlayer().getIndex() + 1) % numberOfPlayers; setPriorityPlayer(players.get(priorityPlayerIndex)); } @@ -1203,7 +1228,7 @@ public void setPriorityPlayer(Player player) { priorityPlayer.set(player); log.debug("Priority player set to " + player.getIndex() + " " - + player.getName()); + + player.getName()); } /* (non-Javadoc) @@ -1280,7 +1305,7 @@ public void setNextPlayer() { int currentPlayerIndex = getCurrentPlayerIndex(); do { - currentPlayerIndex = ++currentPlayerIndex % numberOfPlayers; + currentPlayerIndex = ++currentPlayerIndex % numberOfPlayers; } while (players.get(currentPlayerIndex).isBankrupt()); setCurrentPlayerIndex(currentPlayerIndex); } @@ -1546,9 +1571,42 @@ cm=ct.newCorrectionManager(this); correctionManagers.put(ct, cm); log.debug("Added CorrectionManager for " + ct); -} + } return cm; } + /** Return a list of companies in operation order. + * <p>Note that, unlike Round.setOperatingCompanies(), this method does <b>not</b> check + * if the companies are actualy allowed to operate. One purpose is to check for upping the + * share price at the end of an SR un sucn a way, that the token order gets preserved. + * @return + */ + public List<PublicCompanyI> getCompaniesInRunningOrder () { + + Map<Integer, PublicCompanyI> operatingCompanies = + new TreeMap<Integer, PublicCompanyI>(); + StockSpaceI space; + int key; + int minorNo = 0; + for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { + + // Key must put companies in reverse operating order, because sort + // is ascending. + if (company.hasStockPrice() && company.hasStarted()) { + space = company.getCurrentSpace(); + key = + 1000000 * (999 - space.getPrice()) + 10000 + * (99 - space.getColumn()) + 100 + * space.getRow() + + space.getStackPosition(company); + } else { + key = ++minorNo; + } + operatingCompanies.put(new Integer(key), company); + } + + return new ArrayList<PublicCompanyI>(operatingCompanies.values()); + } + } Modified: trunk/18xx/rails/game/GameManagerI.java =================================================================== --- trunk/18xx/rails/game/GameManagerI.java 2010-07-04 15:17:14 UTC (rev 1330) +++ trunk/18xx/rails/game/GameManagerI.java 2010-07-04 20:44:29 UTC (rev 1331) @@ -1,202 +1,204 @@ -package rails.game; - -import java.util.List; -import java.util.Map; - -import rails.algorithms.RevenueManager; -import rails.common.GuiDef; -import rails.common.GuiHints; -import rails.game.action.PossibleAction; -import rails.game.correct.CorrectionManagerI; -import rails.game.correct.CorrectionType; -import rails.game.model.ModelObject; -import rails.game.move.MoveStack; -import rails.game.move.MoveableHolder; -import rails.game.special.SpecialPropertyI; - -public interface GameManagerI extends MoveableHolder, ConfigurableComponentI { - - /** - * @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) - */ - public abstract void init(String gameName, PlayerManager playerManager, - CompanyManagerI companyManager, PhaseManager phaseManager, - TrainManager trainManager, StockMarketI stockMarket, - MapManager mapManager, TileManager tileManager, - RevenueManager revenueManager, Bank bank); - public abstract void startGame(Map<String, String> gameOptions); - - public abstract CompanyManagerI getCompanyManager(); - - /** - * Should be called by each Round when it finishes. - * - * @param round The object that represents the finishing round. - */ - public abstract void nextRound(RoundI round); - - public String getORId (); - public abstract String getCompositeORNumber(); - public int getRelativeORNumber(); - - public abstract int getSRNumber(); - - public abstract void startShareSellingRound(Player sellingPlayer, - int cashToRaise, PublicCompanyI unsellableCompany); - - public abstract void startTreasuryShareTradingRound(); - - /** - * The central server-side method that takes a client-side initiated action - * and processes it. - * - * @param action A PossibleAction subclass object sent by the client. - * @return TRUE is the action was valid. - */ - public abstract boolean process(PossibleAction action); - - public abstract boolean processOnReload(List<PossibleAction> actions) - throws Exception; - - public abstract void finishShareSellingRound(); - - public abstract void finishTreasuryShareRound(); - - public abstract void registerBankruptcy(); - - public abstract void registerBrokenBank(); - - /** - * To be called by the UI to check if the rails.game is over. - * - * @return - */ - public abstract boolean isGameOver(); - - public void setGameOverReportedUI(boolean b); - - public boolean getGameOverReportedUI(); - - /** - * Create a HTML-formatted rails.game status report. - * - * @return - */ - public abstract List<String> getGameReport(); - - /** - * Should be called whenever a Phase changes. The effect on the number of - * ORs is delayed until a StockRound finishes. - * - */ - public abstract RoundI getCurrentRound(); - - /** - * @return Returns the currentPlayerIndex. - */ - public abstract int getCurrentPlayerIndex(); - - /** - * @param currentPlayerIndex The currentPlayerIndex to set. - */ - public abstract void setCurrentPlayerIndex(int currentPlayerIndex); - - public abstract void setCurrentPlayer(Player player); - - /** - * Set priority deal to the player after the current player. - * - */ - public abstract void setPriorityPlayer(); - - public abstract void setPriorityPlayer(Player player); - - /** - * @return Returns the priorityPlayer. - */ - public abstract Player getPriorityPlayer(); - - /** - * @return Returns the currentPlayer. - */ - public abstract Player getCurrentPlayer(); - - /** - * @return Returns the players. - */ - public abstract List<Player> getPlayers(); - - public abstract int getNumberOfPlayers(); - - public abstract List<String> getPlayerNames(); - - public abstract List<PublicCompanyI> getAllPublicCompanies(); - - public abstract List<PrivateCompanyI> getAllPrivateCompanies(); - - /** - * Return a player by its index in the list, modulo the number of players. - * - * @param index The player index. - * @return A player object. - */ - public abstract Player getPlayerByIndex(int index); - - public abstract void setNextPlayer(); - - public void addPortfolio (Portfolio portfolio); - public Portfolio getPortfolioByName (String name); - - /** - * @return the StartPacket - */ - public abstract StartPacket getStartPacket(); - - /** - * @return Current phase - */ - public abstract PhaseI getCurrentPhase(); - - public abstract PhaseManager getPhaseManager(); - public void initialiseNewPhase(PhaseI phase); - - public abstract TrainManager getTrainManager (); - public PlayerManager getPlayerManager(); - public TileManager getTileManager(); - public StockMarketI getStockMarket(); - public MapManager getMapManager(); - public RevenueManager getRevenueManager(); - public Bank getBank (); - - public String getGameName (); - public String getGameOption (String key); - - public int getPlayerCertificateLimit(Player player); - public void setPlayerCertificateLimit(int newLimit); - public ModelObject getPlayerCertificateLimitModel (); - - public abstract String getHelp(); - - public abstract boolean canAnyCompanyHoldShares(); - - public abstract String getClassName(GuiDef.ClassName key); - - public abstract Object getGuiParameter(GuiDef.Parm key); - public Object getGameParameter (GameDef.Parm key); - public void setGameParameter (GameDef.Parm key, Object value); - - public RoundI getInterruptedRound(); - - public List<SpecialPropertyI> getCommonSpecialProperties (); - public <T extends SpecialPropertyI> List<T> getSpecialProperties( - Class<T> clazz, boolean includeExercised); - - public String getGMKey (); - public MoveStack getMoveStack (); - public DisplayBuffer getDisplayBuffer(); - public void addToNextPlayerMessages(String s, boolean undoable); - public ReportBuffer getReportBuffer(); - public GuiHints getUIHints(); - - public CorrectionManagerI getCorrectionManager(CorrectionType ct); +package rails.game; + +import java.util.List; +import java.util.Map; + +import rails.algorithms.RevenueManager; +import rails.common.GuiDef; +import rails.common.GuiHints; +import rails.game.action.PossibleAction; +import rails.game.correct.CorrectionManagerI; +import rails.game.correct.CorrectionType; +import rails.game.model.ModelObject; +import rails.game.move.MoveStack; +import rails.game.move.MoveableHolder; +import rails.game.special.SpecialPropertyI; + +public interface GameManagerI extends MoveableHolder, ConfigurableComponentI { + + /** + * @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + */ + public abstract void init(String gameName, PlayerManager playerManager, + CompanyManagerI companyManager, PhaseManager phaseManager, + TrainManager trainManager, StockMarketI stockMarket, + MapManager mapManager, TileManager tileManager, + RevenueManager revenueManager, Bank bank); + public abstract void startGame(Map<String, String> gameOptions); + + public abstract CompanyManagerI getCompanyManager(); + + /** + * Should be called by each Round when it finishes. + * + * @param round The object that represents the finishing round. + */ + public abstract void nextRound(RoundI round); + + public String getORId (); + public abstract String getCompositeORNumber(); + public int getRelativeORNumber(); + + public abstract int getSRNumber(); + + public abstract void startShareSellingRound(Player sellingPlayer, + int cashToRaise, PublicCompanyI unsellableCompany); + + public abstract void startTreasuryShareTradingRound(); + + /** + * The central server-side method that takes a client-side initiated action + * and processes it. + * + * @param action A PossibleAction subclass object sent by the client. + * @return TRUE is the action was valid. + */ + public abstract boolean process(PossibleAction action); + + public abstract boolean processOnReload(List<PossibleAction> actions) + throws Exception; + + public abstract void finishShareSellingRound(); + + public abstract void finishTreasuryShareRound(); + + public abstract void registerBankruptcy(); + + public abstract void registerBrokenBank(); + + /** + * To be called by the UI to check if the rails.game is over. + * + * @return + */ + public abstract boolean isGameOver(); + + public void setGameOverReportedUI(boolean b); + + public boolean getGameOverReportedUI(); + + /** + * Create a HTML-formatted rails.game status report. + * + * @return + */ + public abstract List<String> getGameReport(); + + /** + * Should be called whenever a Phase changes. The effect on the number of + * ORs is delayed until a StockRound finishes. + * + */ + public abstract RoundI getCurrentRound(); + + /** + * @return Returns the currentPlayerIndex. + */ + public abstract int getCurrentPlayerIndex(); + + /** + * @param currentPlayerIndex The currentPlayerIndex to set. + */ + public abstract void setCurrentPlayerIndex(int currentPlayerIndex); + + public abstract void setCurrentPlayer(Player player); + + /** + * Set priority deal to the player after the current player. + * + */ + public abstract void setPriorityPlayer(); + + public abstract void setPriorityPlayer(Player player); + + /** + * @return Returns the priorityPlayer. + */ + public abstract Player getPriorityPlayer(); + + /** + * @return Returns the currentPlayer. + */ + public abstract Player getCurrentPlayer(); + + /** + * @return Returns the players. + */ + public abstract List<Player> getPlayers(); + + public abstract int getNumberOfPlayers(); + + public abstract List<String> getPlayerNames(); + + public abstract List<PublicCompanyI> getAllPublicCompanies(); + + public abstract List<PrivateCompanyI> getAllPrivateCompanies(); + + /** + * Return a player by its index in the list, modulo the number of players. + * + * @param index The player index. + * @return A player object. + */ + public abstract Player getPlayerByIndex(int index); + + public abstract void setNextPlayer(); + + public void addPortfolio (Portfolio portfolio); + public Portfolio getPortfolioByName (String name); + + /** + * @return the StartPacket + */ + public abstract StartPacket getStartPacket(); + + /** + * @return Current phase + */ + public abstract PhaseI getCurrentPhase(); + + public abstract PhaseManager getPhaseManager(); + public void initialiseNewPhase(PhaseI phase); + + public abstract TrainManager getTrainManager (); + public PlayerManager getPlayerManager(); + public TileManager getTileManager(); + public StockMarketI getStockMarket(); + public MapManager getMapManager(); + public RevenueManager getRevenueManager(); + public Bank getBank (); + + public String getGameName (); + public String getGameOption (String key); + + public int getPlayerCertificateLimit(Player player); + public void setPlayerCertificateLimit(int newLimit); + public ModelObject getPlayerCertificateLimitModel (); + + public abstract String getHelp(); + + public abstract boolean canAnyCompanyHoldShares(); + + public abstract String getClassName(GuiDef.ClassName key); + + public abstract Object getGuiParameter(GuiDef.Parm key); + public Object getGameParameter (GameDef.Parm key); + public void setGameParameter (GameDef.Parm key, Object value); + + public RoundI getInterruptedRound(); + + public List<SpecialPropertyI> getCommonSpecialProperties (); + public <T extends SpecialPropertyI> List<T> getSpecialProperties( + Class<T> clazz, boolean includeExercised); + + public String getGMKey (); + public MoveStack getMoveStack (); + public DisplayBuffer getDisplayBuffer(); + public void addToNextPlayerMessages(String s, boolean undoable); + public ReportBuffer getReportBuffer(); + public GuiHints getUIHints(); + + public CorrectionManagerI getCorrectionManager(CorrectionType ct); + public List<PublicCompanyI> getCompaniesInRunningOrder (); + } \ No newline at end of file Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-07-04 15:17:14 UTC (rev 1330) +++ trunk/18xx/rails/game/StockRound.java 2010-07-04 20:44:29 UTC (rev 1331) @@ -1,12 +1,29 @@ package rails.game; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import rails.common.GuiDef; -import rails.game.action.*; -import rails.game.move.*; -import rails.game.special.*; -import rails.game.state.*; +import rails.game.action.BuyCertificate; +import rails.game.action.NullAction; +import rails.game.action.PossibleAction; +import rails.game.action.RequestTurn; +import rails.game.action.SellShares; +import rails.game.action.StartCompany; +import rails.game.action.UseSpecialProperty; +import rails.game.move.AddToList; +import rails.game.move.CashMove; +import rails.game.move.DoubleMapChange; +import rails.game.special.ExchangeForShare; +import rails.game.special.SpecialProperty; +import rails.game.special.SpecialPropertyI; +import rails.game.state.BooleanState; +import rails.game.state.IntegerState; +import rails.game.state.State; import rails.util.LocalText; /** @@ -23,22 +40,22 @@ protected Player startingPlayer; protected State companyBoughtThisTurnWrapper = - new State("CompanyBoughtThisTurn", PublicCompany.class); + new State("CompanyBoughtThisTurn", PublicCompany.class); protected BooleanState hasSoldThisTurnBeforeBuying = - new BooleanState("HoldSoldBeforeBuyingThisTurn", false); + new BooleanState("HoldSoldBeforeBuyingThisTurn", false); protected BooleanState hasActed = new BooleanState("HasActed", false); // Is protected IntegerState numPasses = new IntegerState("StockRoundPasses"); protected Map<String, StockSpaceI> sellPrices = - new HashMap<String, StockSpaceI>(); + new HashMap<String, StockSpaceI>(); /* Transient data needed for rule enforcing */ /** HashMap per player containing a HashMap per company */ protected HashMap<Player, HashMap<PublicCompanyI, Object>> playersThatSoldThisRound = - new HashMap<Player, HashMap<PublicCompanyI, Object>>(); + new HashMap<Player, HashMap<PublicCompanyI, Object>>(); /* Rule constants */ static protected final int SELL_BUY_SELL = 0; @@ -74,7 +91,7 @@ public void start() { ReportBuffer.add(LocalText.getText("StartStockRound", - getStockRoundNumber())); + getStockRoundNumber())); setCurrentPlayerIndex(gameManager.getPriorityPlayer().getIndex()); startingPlayer = getCurrentPlayer(); // For the Report @@ -157,17 +174,17 @@ /* Get the next available IPO certificates */ // Never buy more than one from the IPO PublicCompanyI companyBoughtThisTurn = - (PublicCompanyI) companyBoughtThisTurnWrapper.getObject(); + (PublicCompanyI) companyBoughtThisTurnWrapper.getObject(); if (companyBoughtThisTurn == null) { from = ipo; Map<String, List<PublicCertificateI>> map = - from.getCertsPerCompanyMap(); + from.getCertsPerCompanyMap(); int shares; for (String compName : map.keySet()) { certs = map.get(compName); if (certs == null || certs.isEmpty()) continue; - + /* Only the top certificate is buyable from the IPO */ int lowestIndex = 99; cert = null; @@ -179,7 +196,7 @@ cert = c; } } - + comp = cert.getCompany(); unitsForPrice = comp.getShareUnitsForSharePrice(); if (isSaleRecorded(currentPlayer, comp)) continue; @@ -223,7 +240,7 @@ /* Get the unique Pool certificates and check which ones can be bought */ from = pool; Map<String, List<PublicCertificateI>> map = - from.getCertsPerCompanyMap(); + from.getCertsPerCompanyMap(); /* Allow for multiple share unit certificates (e.g. 1835) */ PublicCertificateI[] uniqueCerts; int[] numberOfCerts; @@ -241,7 +258,7 @@ price = stockSpace.getPrice() / unitsForPrice; shareUnit = comp.getShareUnit(); maxNumberOfSharesToBuy - = maxAllowedNumberOfSharesToBuy(currentPlayer, comp, shareUnit); + = maxAllowedNumberOfSharesToBuy(currentPlayer, comp, shareUnit); /* Checks if the player can buy any shares of this company */ if (maxNumberOfSharesToBuy < 1) continue; @@ -279,7 +296,7 @@ /* Would the player exceed the total certificate limit? */ if (!stockSpace.isNoCertLimit() - && !mayPlayerBuyCertificate(currentPlayer, comp, number)) + && !mayPlayerBuyCertificate(currentPlayer, comp, number)) continue; } @@ -301,8 +318,8 @@ for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { certs = - company.getPortfolio().getCertificatesPerCompany( - company.getName()); + company.getPortfolio().getCertificatesPerCompany( + company.getName()); if (certs == null || certs.isEmpty()) continue; cert = certs.get(0); if (isSaleRecorded(currentPlayer, company)) continue; @@ -311,7 +328,7 @@ certs.get(0).getShare()) < 1) continue; stockSpace = company.getCurrentSpace(); if (!stockSpace.isNoCertLimit() - && !mayPlayerBuyCertificate(currentPlayer, company, 1)) continue; + && !mayPlayerBuyCertificate(currentPlayer, company, 1)) continue; if (company.getMarketPrice() <= playerCash) { possibleActions.add(new BuyCertificate(cert, company.getPortfolio(), company.getMarketPrice())); @@ -347,16 +364,16 @@ // In some games, can't sell shares if not operated if (company.mustHaveOperatedToTradeShares() - && !company.hasOperated()) continue; + && !company.hasOperated()) continue; share = maxShareToSell = playerPortfolio.getShare(company); if (maxShareToSell == 0) continue; /* May not sell more than the Pool can accept */ maxShareToSell = - Math.min(maxShareToSell, - getGameParameterAsInt(GameDef.Parm.POOL_SHARE_LIMIT) - - pool.getShare(company)); + Math.min(maxShareToSell, + getGameParameterAsInt(GameDef.Parm.POOL_SHARE_LIMIT) + - pool.getShare(company)); if (maxShareToSell == 0) continue; /* @@ -365,7 +382,7 @@ */ if (company.getPresident() == currentPlayer) { int presidentShare = - company.getCertificates().get(0).getShare(); + company.getCertificates().get(0).getShare(); if (maxShareToSell > share - presidentShare) { dumpAllowed = false; int playerShare; @@ -416,14 +433,14 @@ number = shareCountPerUnit[i]; if (number == 0) continue; number = - Math.min(number, maxShareToSell - / (i * company.getShareUnit())); + Math.min(number, maxShareToSell + / (i * company.getShareUnit())); /* In some games (1856), a just bought share may not be sold */ // This code ignores the possibility of different share units if ((Boolean)gameManager.getGameParameter(GameDef.Parm.NO_SALE_OF_JUST_BOUGHT_CERT) - && company.equals(companyBoughtThisTurnWrapper.getObject())) { - number--; + && company.equals(companyBoughtThisTurnWrapper.getObject())) { + number--; } if (number <= 0) continue; @@ -436,8 +453,8 @@ protected void setSpecialActions() { List<SpecialProperty> sps = - currentPlayer.getPortfolio().getSpecialProperties( - SpecialProperty.class, false); + currentPlayer.getPortfolio().getSpecialProperties( + SpecialProperty.class, false); for (SpecialPropertyI sp : sps) { if (sp.isUsableDuringSR()) { possibleActions.add(new UseSpecialProperty(sp)); @@ -464,7 +481,7 @@ break; case NullAction.AUTOPASS: result = done(playerName, true); - break; + break; } } else if (action instanceof StartCompany) { @@ -554,7 +571,7 @@ // The company may not have started yet. if (company.hasStarted()) { errMsg = - LocalText.getText("CompanyAlreadyStarted", companyName); + LocalText.getText("CompanyAlreadyStarted", companyName); break; } @@ -581,8 +598,8 @@ // Else the given price must be a valid start price if ((startSpace = stockMarket.getStartSpace(price)) == null) { errMsg = LocalText.getText("InvalidStartPrice", - Bank.format(price), - company.getName() ); + Bank.format(price), + company.getName() ); break; } } @@ -695,9 +712,9 @@ // The player may not have sold the company this round. if (isSaleRecorded(currentPlayer, company)) { errMsg = - LocalText.getText("AlreadySoldThisTurn", - currentPlayer.getName(), - companyName ); + LocalText.getText("AlreadySoldThisTurn", + currentPlayer.getName(), + companyName ); break; } @@ -709,9 +726,9 @@ // The player may not have bought this turn, unless the company // bought before and now is in the brown area. PublicCompanyI companyBoughtThisTurn = - (PublicCompanyI) companyBoughtThisTurnWrapper.getObject(); + (PublicCompanyI) companyBoughtThisTurnWrapper.getObject(); if (companyBoughtThisTurn != null - && (companyBoughtThisTurn != company || !company.getCurrentSpace().isNoBuyLimit())) { + && (companyBoughtThisTurn != company || !company.getCurrentSpace().isNoBuyLimit())) { errMsg = LocalText.getText("AlreadyBought", playerName); break; } @@ -719,9 +736,9 @@ // Check if that many shares are available if (shares > from.getShare(company)) { errMsg = - LocalText.getText("NotAvailable", - companyName, - from.getName() ); + LocalText.getText("NotAvailable", + companyName, + from.getName() ); break; } @@ -742,20 +759,20 @@ // Check if player would not exceed the certificate limit. // (shortcut: assume 1 cert == 1 certificate) if (!currentSpace.isNoCertLimit() - && !mayPlayerBuyCertificate(currentPlayer, company, number)) { + && !mayPlayerBuyCertificate(currentPlayer, company, number)) { errMsg = - currentPlayer.getName() - + LocalText.getText("WouldExceedCertLimit", - String.valueOf(gameManager.getPlayerCertificateLimit(currentPlayer))); + currentPlayer.getName() + + LocalText.getText("WouldExceedCertLimit", + String.valueOf(gameManager.getPlayerCertificateLimit(currentPlayer))); break; } // Check if player would exceed the per-company share limit if (!currentSpace.isNoHoldLimit() - && !checkAgainstHoldLimit(currentPlayer, company, shares)) { - errMsg = LocalText.getText("WouldExceedHoldLimit", - currentPlayer.getName(), - GameDef.Parm.PLAYER_SHARE_LIMIT.defaultValueAsInt()); + && !checkAgainstHoldLimit(currentPlayer, company, shares)) { + errMsg = LocalText.getText("WouldExceedHoldLimit", + currentPlayer.getName(), + GameDef.Parm.PLAYER_SHARE_LIMIT.defaultValueAsInt()); break; } @@ -811,7 +828,7 @@ cert2 = from.findCertificate(company, cert.getShares(), false); if (cert2 == null) { log.error("Cannot find " + companyName + " " + shareUnit - + "% share in " + from.getName()); + + "% share in " + from.getName()); } cert2.moveTo(currentPlayer.getPortfolio()); } @@ -845,13 +862,13 @@ PublicCompanyI company) { } - + /** Allow different price setting in subclasses (i.e. 1835 Nationalisation) */ protected int getBuyPrice (BuyCertificate action, StockSpaceI currentSpace) { return currentSpace.getPrice(); } - /** + /** * Who receives the cash when a certificate is bought. * With incremental capitalization, this can be the company treasure. * This method must be called <i>before</i> transferring the certificate. @@ -864,8 +881,8 @@ PublicCompanyI comp; CashHolder recipient; if ((comp = (cert).getCompany()).hasFloated() - && oldHolder == ipo - && comp.getCapitalisation() == PublicCompanyI.CAPITALISE_INCREMENTAL) { + && oldHolder == ipo + && comp.getCapitalisation() == PublicCompanyI.CAPITALISE_INCREMENTAL) { recipient = comp; } else { recipient = oldHolder.getOwner(); @@ -873,7 +890,7 @@ return recipient; } - /** Make the certificates of one company available for buying + /** Make the certificates of one company available for buying * by putting these in the IPO. * @param company The company to be released. */ @@ -893,8 +910,8 @@ protected boolean isSaleRecorded(Player player, PublicCompanyI company) { return playersThatSoldThisRound.containsKey(currentPlayer) - && playersThatSoldThisRound.get(currentPlayer).containsKey( - company); + && playersThatSoldThisRound.get(currentPlayer).containsKey( + company); } public boolean sellShares(SellShares action) @@ -906,11 +923,11 @@ String errMsg = null; String companyName = action.getCompanyName(); PublicCompanyI company = - companyManager.getPublicCompany(action.getCompanyName()); + companyManager.getPublicCompany(action.getCompanyName()); PublicCertificateI cert = null; PublicCertificateI presCert = null; List<PublicCertificateI> certsToSell = - new ArrayList<PublicCertificateI>(); + new ArrayList<PublicCertificateI>(); Player dumpedPlayer = null; int presSharesToSell = 0; int numberToSell = action.getNumberSold(); @@ -957,7 +974,7 @@ // Find the certificates to sell Iterator<PublicCertificateI> it = - portfolio.getCertificatesPerCompany(companyName).iterator(); + portfolio.getCertificatesPerCompany(companyName).iterator(); while (numberToSell > 0 && it.hasNext()) { cert = it.next(); if (cert.isPresidentShare()) { @@ -1062,7 +1079,7 @@ // First swap the certificates Portfolio dumpedPortfolio = dumpedPlayer.getPortfolio(); List<PublicCertificateI> swapped = - portfolio.swapPresidentCertificate(company, dumpedPortfolio); + portfolio.swapPresidentCertificate(company, dumpedPortfolio); for (int i = 0; i < presSharesToSell; i++) { certsToSell.add(swapped.get(i)); } @@ -1106,7 +1123,7 @@ } protected void adjustSharePrice (PublicCompanyI company, int numberSold, boolean soldBefore) { - + if (company.canSharePriceVary()) { stockMarket.sell(company, numberSold); } @@ -1132,7 +1149,7 @@ public boolean executeExchangeForShare (ExchangeForShare sp) { PublicCompanyI publicCompany = - companyManager.getPublicCompany(sp.getPublicCompanyName()); + companyManager.getPublicCompany(sp.getPublicCompanyName()); CompanyI privateCompany = sp.getOriginalCompany(); Portfolio portfolio = privateCompany.getPortfolio(); Player player = null; @@ -1145,8 +1162,8 @@ /* Check if the private is owned by a player */ if (!(portfolio.getOwner() instanceof Player)) { errMsg = - LocalText.getText("PrivateIsNotOwnedByAPlayer", - privateCompany.getName()); + LocalText.getText("PrivateIsNotOwnedByAPlayer", + privateCompany.getName()); break; } @@ -1155,16 +1172,16 @@ /* Check if a share is available */ if (!ipoHasShare && !poolHasShare) { errMsg = - LocalText.getText("NoSharesAvailable", - publicCompany.getName()); + LocalText.getText("NoSharesAvailable", + publicCompany.getName()); break; } /* Check if the player has room for a share of this company */ if (!checkAgainstHoldLimit(player, publicCompany, 1)) { // TODO: Not nice to use '1' here, should be percentage. errMsg = - LocalText.getText("WouldExceedHoldLimit", - String.valueOf(getGameParameterAsInt(GameDef.Parm.PLAYER_SHARE_LIMIT))); + LocalText.getText("WouldExceedHoldLimit", + String.valueOf(getGameParameterAsInt(GameDef.Parm.PLAYER_SHARE_LIMIT))); break; } break; @@ -1172,33 +1189,33 @@ if (errMsg != null) { DisplayBuffer.add(LocalText.getText( "CannotSwapPrivateForCertificate", - player.getName(), - privateCompany.getName(), - sp.getShare(), - publicCompany.getName(), - errMsg )); + player.getName(), + privateCompany.getName(), + sp.getShare(), + publicCompany.getName(), + errMsg )); return false; } moveStack.start(true); Certificate cert = - ipoHasShare ? ipo.findCertificate(publicCompany, - false) : pool.findCertificate(publicCompany, - false); - cert.moveTo(player.getPortfolio()); - ReportBuffer.add(LocalText.getText("SwapsPrivateForCertificate", - player.getName(), - privateCompany.getName(), - sp.getShare(), - publicCompany.getName())); - sp.setExercised(); - privateCompany.setClosed(); + ipoHasShare ? ipo.findCertificate(publicCompany, + false) : pool.findCertificate(publicCompany, + false); + cert.moveTo(player.getPortfolio()); + ReportBuffer.add(LocalText.getText("SwapsPrivateForCertificate", + player.getName(), + privateCompany.getName(), + sp.getShare(), + publicCompany.getName())); + sp.setExercised(); + privateCompany.setClosed(); - // Check if the company has floated - if (!publicCompany.hasFloated()) checkFlotation(publicCompany); + // Check if the company has floated + if (!publicCompany.hasFloated()) checkFlotation(publicCompany); - return true; + return true; } /** @@ -1237,31 +1254,6 @@ if (numPasses.intValue() >= getNumberOfActivePlayers()) { - ReportBuffer.add(LocalText.getText("END_SR", - String.valueOf(getStockRoundNumber()))); - - /* Check if any companies are sold out. */ - for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { - if (company.hasStockPrice() && company.isSoldOut()) { - StockSpaceI oldSpace = company.getCurrentSpace(); - stockMarket.soldOut(company); - StockSpaceI newSpace = company.getCurrentSpace(); - if (newSpace != oldSpace) { - ReportBuffer.add(LocalText.getText("SoldOut", - company.getName(), - Bank.format(oldSpace.getPrice()), - oldSpace.getName(), - Bank.format(newSpace.getPrice()), - newSpace.getName())); - } else { - ReportBuffer.add(LocalText.getText("SoldOutNoRaise", - company.getName(), - Bank.format(newSpace.getPrice()), - newSpace.getName())); - } - } - } - finishRound(); } else { @@ -1272,6 +1264,37 @@ return true; } + @Override + protected void finishRound () { + + ReportBuffer.add(LocalText.getText("END_SR", + String.valueOf(getStockRoundNumber()))); + + /* Check if any companies are sold out. */ + for (PublicCompanyI company : gameManager.getCompaniesInRunningOrder()) { + if (company.hasStockPrice() && company.isSoldOut()) { + StockSpaceI oldSpace = company.getCurrentSpace(); + stockMarket.soldOut(company); + StockSpaceI newSpace = company.getCurrentSpace(); + if (newSpace != oldSpace) { + ReportBuffer.add(LocalText.getText("SoldOut", + company.getName(), + Bank.format(oldSpace.getPrice()), + oldSpace.getName(), + Bank.format(newSpace.getPrice()), + newSpace.getName())); + } else { + ReportBuffer.add(LocalText.getText("SoldOutNoRaise", + company.getName(), + Bank.format(newSpace.getPrice()), + newSpace.getName())); + } + } + } + + super.finishRound(); + } + protected boolean requestTurn (RequestTurn action) { Player requestingPlayer = playerManager.getPlayerByName(action.getRequestingPlayerName()); @@ -1331,6 +1354,7 @@ gameManager.setPriorityPlayer(); } + @Override public void setCurrentPlayer(Player player) { super.setCurrentPlayer(player); currentPlayer = player; @@ -1356,8 +1380,8 @@ if (getStockRoundNumber() == 1 && noSaleInFirstSR()) return false; if (companyBoughtThisTurnWrapper.getObject() != null - && (sequenceRule == SELL_BUY_OR_BUY_SELL - && hasSoldThisTurnBeforeBuying.booleanValue() || sequenceRule == SELL_BUY)) + ... [truncated message content] |
From: Erik V. <ev...@us...> - 2010-06-27 17:06:57
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv21756/rails/game Modified Files: StockRound.java Log Message: Fixed bug in buying multiple "brown" shares Index: StockRound.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/StockRound.java,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -d -r1.77 -r1.78 *** StockRound.java 25 Jun 2010 21:07:27 -0000 1.77 --- StockRound.java 27 Jun 2010 17:06:46 -0000 1.78 *************** *** 814,818 **** + "% share in " + from.getName()); } ! cert.moveTo(currentPlayer.getPortfolio()); } new CashMove (currentPlayer, priceRecipient, cost); --- 814,818 ---- + "% share in " + from.getName()); } ! cert2.moveTo(currentPlayer.getPortfolio()); } new CashMove (currentPlayer, priceRecipient, cost); |
From: Erik V. <ev...@us...> - 2010-06-25 21:07:35
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv5272/rails/game Modified Files: StockRound.java Log Message: Fixed: for the cert limit check, a bought 20% cert was counted as 2 (shares) in stead of 1 (certificate) Index: StockRound.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/StockRound.java,v retrieving revision 1.76 retrieving revision 1.77 diff -C2 -d -r1.76 -r1.77 *** StockRound.java 17 Jun 2010 21:35:54 -0000 1.76 --- StockRound.java 25 Jun 2010 21:07:27 -0000 1.77 *************** *** 743,747 **** // (shortcut: assume 1 cert == 1 certificate) if (!currentSpace.isNoCertLimit() ! && !mayPlayerBuyCertificate(currentPlayer, company, shares)) { errMsg = currentPlayer.getName() --- 743,747 ---- // (shortcut: assume 1 cert == 1 certificate) if (!currentSpace.isNoCertLimit() ! && !mayPlayerBuyCertificate(currentPlayer, company, number)) { errMsg = currentPlayer.getName() |
From: Erik V. <ev...@us...> - 2010-06-25 20:47:53
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv1611/rails/ui/swing Modified Files: UpgradesPanel.java Log Message: Replaced # by () to indicate number of available tiles in the upgrades panel Index: UpgradesPanel.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/UpgradesPanel.java,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** UpgradesPanel.java 30 May 2010 10:42:39 -0000 1.28 --- UpgradesPanel.java 25 Jun 2010 20:47:45 -0000 1.29 *************** *** 498,502 **** text.append("<HTML><BODY>" + tile.getExternalId()); if (tile.countFreeTiles() != -1) { ! text.append("<BR> #" + tile.countFreeTiles()); } text.append("</BODY></HTML>"); --- 498,502 ---- text.append("<HTML><BODY>" + tile.getExternalId()); if (tile.countFreeTiles() != -1) { ! text.append("<BR> (" + tile.countFreeTiles() + ")"); } text.append("</BODY></HTML>"); |
From: Erik V. <ev...@us...> - 2010-06-25 13:18:21
|
Update of /cvsroot/rails/18xx/tiles/svg In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv21416/tiles/svg Removed Files: tile-890031.svg Log Message: Removed redundant file --- tile-890031.svg DELETED --- |
From: Erik V. <ev...@us...> - 2010-06-25 12:52:10
|
Update of /cvsroot/rails/18xx/tiles In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv17323/tiles Removed Files: Copy of TileDictionary.xml Log Message: Removed redundant copy --- Copy of TileDictionary.xml DELETED --- |
From: Erik V. <ev...@us...> - 2010-06-25 12:48:29
|
Update of /cvsroot/rails/18xx/tiles/svg In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16640/tiles/svg Modified Files: tile439.svg Added Files: tile-890031.svg Log Message: Fixed 1889 tile 439 (value 60) Index: tile439.svg =================================================================== RCS file: /cvsroot/rails/18xx/tiles/svg/tile439.svg,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** tile439.svg 3 Feb 2010 19:57:08 -0000 1.1 --- tile439.svg 25 Jun 2010 12:48:21 -0000 1.2 *************** *** 1,2 **** <?xml version="1.0"?> ! <svg version="1.1" xmlns="http://www.w3.org/2000/svg"><path d=" M 98,0 L 294,0 L 392,170 L 294,340 L 98,340 L 0,170 Z" fill="#38AC00" stroke="#38AC00" stroke-width="1" stroke-linejoin="round"/><text x="245" y="318" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="Arial" font-size="34" font-weight="bold">439</text><polygon points="145,119 247,119 247,221 145,221" fill="#FFFFFF" stroke="#FFFFFF" stroke-width="12"/><circle cx="145" cy="170" r="51" fill="#FFFFFF" stroke="#FFFFFF" stroke-width="12"/><circle cx="247" cy="170" r="51" fill="#FFFFFF" stroke="#FFFFFF" stroke-width="12"/><path d="M 196,170 L 49,255" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 343,255" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 196,0" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 49,255" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 343,255" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 196,0" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><polygon points="145,119 247,119 247,221 145,221" fill="#FFFFFF" stroke="#000000" stroke-width="4"/><circle cx="145" cy="170" r="51" fill="#FFFFFF" stroke="#000000" stroke-width="4"/><circle cx="247" cy="170" r="51" fill="#FFFFFF" stroke="#000000" stroke-width="4"/><ellipse rx="38" ry="34" cx="49" cy="170" fill="#FFFFFF" stroke="#000000" stroke-width="2" stroke-linejoin="round"/><text x="49" y="170" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="Bookman Old Style" font-size="51">50</text><text x="196" y="43" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="TimpaniHeavy" font-size="51">Kotohira</text><path d=" M 98,0 L 294,0 L 392,170 L 294,340 L 98,340 L 0,170 Z" fill="none" stroke="black" stroke-width="1" stroke-linejoin="round"/></svg> --- 1,2 ---- <?xml version="1.0"?> ! <svg version="1.1" xmlns="http://www.w3.org/2000/svg"><path d=" M 98,0 L 294,0 L 392,170 L 294,340 L 98,340 L 0,170 Z" fill="#38AC00" stroke="#38AC00" stroke-width="1" stroke-linejoin="round"/><text x="245" y="318" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="Arial" font-size="34" font-weight="bold">439</text><polygon points="145,119 247,119 247,221 145,221" fill="#FFFFFF" stroke="#FFFFFF" stroke-width="12"/><circle cx="145" cy="170" r="51" fill="#FFFFFF" stroke="#FFFFFF" stroke-width="12"/><circle cx="247" cy="170" r="51" fill="#FFFFFF" stroke="#FFFFFF" stroke-width="12"/><path d="M 196,170 L 49,255" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 343,255" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 196,0" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 49,255" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 343,255" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,170 L 196,0" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><polygon points="145,119 247,119 247,221 145,221" fill="#FFFFFF" stroke="#000000" stroke-width="4"/><circle cx="145" cy="170" r="51" fill="#FFFFFF" stroke="#000000" stroke-width="4"/><circle cx="247" cy="170" r="51" fill="#FFFFFF" stroke="#000000" stroke-width="4"/><ellipse rx="38" ry="34" cx="123" cy="43" fill="#FFFFFF" stroke="#000000" stroke-width="2" stroke-linejoin="round"/><text x="123" y="43" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="Bookman Old Style" font-size="51">60</text><text x="196" y="255" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="TimpaniHeavy" font-size="51">Kotohira</text><path d=" M 98,0 L 294,0 L 392,170 L 294,340 L 98,340 L 0,170 Z" fill="none" stroke="black" stroke-width="1" stroke-linejoin="round"/></svg> --- NEW FILE: tile-890031.svg --- <?xml version="1.0"?> <svg version="1.1" xmlns="http://www.w3.org/2000/svg"><path d=" M 98,0 L 294,0 L 392,170 L 294,340 L 98,340 L 0,170 Z" fill="#C0C0C0" stroke="#C0C0C0" stroke-width="1" stroke-linejoin="round"/><line x1="260" y1="59" x2="230" y2="111" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt"/><path d="M 196,0 A 98,98 0 0,0 245,85" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 245,85 A 98,98 0 0,0 343,85" fill="none" stroke="#FFFFFF" stroke-width="34" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 196,0 A 98,98 0 0,0 245,85" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><path d="M 245,85 A 98,98 0 0,0 343,85" fill="none" stroke="#000000" stroke-width="26" stroke-linecap="butt" stroke-linejoin="round"/><line x1="258" y1="62" x2="232" y2="108" stroke="#000000" stroke-width="26" stroke-linecap="butt"/><ellipse rx="38" ry="34" cx="123" cy="43" fill="#FFFFFF" stroke="#000000" stroke-width="2" stroke-linejoin="round"/><text x="123" y="43" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="Bookman Old Style" font-size="51">20</text><text x="235" y="147" dy="0.3em" fill="#000000" stroke="#000000" text-anchor="middle" font-family="TimpaniHeavy" font-size="51">Muroto</text><path d=" M 98,0 L 294,0 L 392,170 L 294,340 L 98,340 L 0,170 Z" fill="none" stroke="black" stroke-width="1" stroke-linejoin="round"/></svg> |
From: Erik V. <ev...@us...> - 2010-06-25 10:25:09
|
Update of /cvsroot/rails/18xx/data/1835 In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv25296/data/1835 Modified Files: CompanyManager.xml Log Message: Added missing PR home hex Index: CompanyManager.xml =================================================================== RCS file: /cvsroot/rails/18xx/data/1835/CompanyManager.xml,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** CompanyManager.xml 8 May 2010 14:23:21 -0000 1.33 --- CompanyManager.xml 25 Jun 2010 10:25:00 -0000 1.34 *************** *** 197,200 **** --- 197,201 ---- </Company> <Company name="Pr" longname="Preußische Eisenbahn" type="Major" startspace="I4" available="no" tokens="7" fgColour="FFFFFF" bgColour="000000"> + <Home hex="E19"/> <ShareUnit percentage="5" sharePriceUnits="2"/> <Float percentage="10"/> |
From: Stefan F. <ste...@us...> - 2010-06-24 22:34:15
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv7598/rails/ui/swing Modified Files: ORUIManager.java Log Message: Fixed bug that stations with token of company were still highlighted Index: ORUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORUIManager.java,v retrieving revision 1.80 retrieving revision 1.81 diff -C2 -d -r1.80 -r1.81 *** ORUIManager.java 24 Jun 2010 21:48:08 -0000 1.80 --- ORUIManager.java 24 Jun 2010 22:34:07 -0000 1.81 *************** *** 272,280 **** if (mapHexes) { // generate network graph to indicate the token lays ! hexUpgrades = NetworkGraphBuilder.getStationHexes(getCompanyGraph(), orComp); ! for (LayToken layToken:allowedTokenLays) { ! if (layToken.getLocations() != null) ! hexUpgrades.addAll(layToken.getLocations()); ! } for (MapHex hex:hexUpgrades) { GUIHex guiHex = map.getHexByName(hex.getName()); --- 272,276 ---- if (mapHexes) { // generate network graph to indicate the token lays ! hexUpgrades.addAll(NetworkGraphBuilder.getTokenableStationHexes(getCompanyGraph(), orComp)); for (MapHex hex:hexUpgrades) { GUIHex guiHex = map.getHexByName(hex.getName()); |
From: Stefan F. <ste...@us...> - 2010-06-24 22:34:15
|
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv7598/rails/algorithms Modified Files: NetworkGraphBuilder.java Log Message: Fixed bug that stations with token of company were still highlighted Index: NetworkGraphBuilder.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkGraphBuilder.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** NetworkGraphBuilder.java 17 Jun 2010 22:10:53 -0000 1.15 --- NetworkGraphBuilder.java 24 Jun 2010 22:34:07 -0000 1.16 *************** *** 216,225 **** } ! public static List<MapHex> getStationHexes(Graph<NetworkVertex, NetworkEdge> graph, PublicCompanyI company){ List<MapHex> hexes = new ArrayList<MapHex>(); for(NetworkVertex vertex:graph.vertexSet()) { City city = vertex.getCity(); ! if (city != null && city.hasTokenSlotsLeft()) { hexes.add(vertex.getHex()); } --- 216,225 ---- } ! public static List<MapHex> getTokenableStationHexes(Graph<NetworkVertex, NetworkEdge> graph, PublicCompanyI company){ List<MapHex> hexes = new ArrayList<MapHex>(); for(NetworkVertex vertex:graph.vertexSet()) { City city = vertex.getCity(); ! if (city != null && city.hasTokenSlotsLeft() && !city.hasTokenOf(company)) { hexes.add(vertex.getHex()); } |
From: Stefan F. <ste...@us...> - 2010-06-24 21:48:19
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv25799/rails/ui/swing Modified Files: ORWindow.java GameUIManager.java ORUIManager.java MapPanel.java Log Message: Refactoring of HexMap classes to remove zoom problems Added autoscrolling support Added gamespecific config settings Index: GameUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/GameUIManager.java,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** GameUIManager.java 22 Jun 2010 18:10:14 -0000 1.47 --- GameUIManager.java 24 Jun 2010 21:48:08 -0000 1.48 *************** *** 109,118 **** configuredStockChartVisibility = "yes".equalsIgnoreCase(Config.get("stockchart.window.open")); ! // font settings ! String fontType = Config.get("font.global.name"); Font font = null; if (Util.hasValue(fontType)) { boolean boldStyle = true; ! String fontStyle = Config.get("font.global.style"); if (Util.hasValue(fontStyle)) { if (fontStyle.equalsIgnoreCase("plain")) { --- 109,118 ---- configuredStockChartVisibility = "yes".equalsIgnoreCase(Config.get("stockchart.window.open")); ! // font settings, can be game specific ! String fontType = Config.getGameSpecific("font.ui.name"); Font font = null; if (Util.hasValue(fontType)) { boolean boldStyle = true; ! String fontStyle = Config.getGameSpecific("font.ui.style"); if (Util.hasValue(fontStyle)) { if (fontStyle.equalsIgnoreCase("plain")) { *************** *** 128,132 **** } ! String fontScale = Config.get("font.global.scale"); if (Util.hasValue(fontScale)) { try { --- 128,132 ---- } ! String fontScale = Config.getGameSpecific("font.ui.scale"); if (Util.hasValue(fontScale)) { try { Index: ORUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORUIManager.java,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -d -r1.79 -r1.80 *** ORUIManager.java 17 Jun 2010 22:10:53 -0000 1.79 --- ORUIManager.java 24 Jun 2010 21:48:08 -0000 1.80 *************** *** 19,22 **** --- 19,23 ---- import rails.ui.swing.hexmap.GUIHex; import rails.ui.swing.hexmap.HexMap; + import rails.util.Config; import rails.util.LocalText; import rails.util.Util; *************** *** 220,228 **** if (mapHexes) { // generate network graph to indicate the allowed tiles ! List<MapHex> mapHexUpgrades = NetworkGraphBuilder.getMapHexes(getCompanyGraph()); for (MapHex hex:mapHexUpgrades) { if (hex.isUpgradeableNow(gameUIManager.getCurrentPhase())) hexUpgrades.add(hex); } } --- 221,237 ---- if (mapHexes) { // generate network graph to indicate the allowed tiles ! SimpleGraph<NetworkVertex, NetworkEdge> companyGraph = getCompanyGraph(); ! List<MapHex> mapHexUpgrades = NetworkGraphBuilder.getMapHexes(companyGraph); for (MapHex hex:mapHexUpgrades) { if (hex.isUpgradeableNow(gameUIManager.getCurrentPhase())) hexUpgrades.add(hex); } + String autoScroll = Config.getGameSpecific("map.autoscroll"); + if (Util.hasValue(autoScroll) && autoScroll.equalsIgnoreCase("no")) { + // do nothing + } else { + mapPanel.scrollPaneShowRectangle( + NetworkVertex.getVertexMapCoverage(map, companyGraph.vertexSet())); + } } Index: ORWindow.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORWindow.java,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** ORWindow.java 17 Feb 2010 00:21:33 -0000 1.35 --- ORWindow.java 24 Jun 2010 21:48:08 -0000 1.36 *************** *** 68,71 **** --- 68,72 ---- getContentPane().add(mapPanel, BorderLayout.CENTER); + upgradePanel = new UpgradesPanel(orUIManager); getContentPane().add(upgradePanel, BorderLayout.WEST); *************** *** 89,92 **** --- 90,96 ---- setSize(800, 600); + log.debug("OrWindow: MapPanel size = " + mapPanel.getSize()); + log.debug("OrWindow size = " + this.getSize()); + final JFrame frame = this; addWindowListener(new WindowAdapter() { Index: MapPanel.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/MapPanel.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** MapPanel.java 31 Jan 2010 22:22:34 -0000 1.14 --- MapPanel.java 24 Jun 2010 21:48:08 -0000 1.15 *************** *** 3,6 **** --- 3,8 ---- import java.awt.BorderLayout; + import java.awt.Point; + import java.awt.Rectangle; import java.awt.event.KeyEvent; import java.util.List; *************** *** 53,61 **** scrollPane.setSize(map.getPreferredSize()); ! setSize(map.getPreferredSize().width, map.getPreferredSize().height); setLocation(25, 25); } public void setAllowedTileLays(List<LayTile> allowedTileLays) { map.setAllowedTileLays(allowedTileLays); --- 55,91 ---- scrollPane.setSize(map.getPreferredSize()); ! setSize(map.getPreferredSize().width, map.getPreferredSize().height); + setLocation(25, 25); } + + public void scrollPaneShowRectangle(Rectangle rectangle) { + + JViewport viewport = scrollPane.getViewport(); + log.debug("ScrollPane viewPort =" + viewport); + + // check dimensions + log.debug("Map size =" + map.getSize()); + log.debug("ScrollPane visibleRect =" + scrollPane.getVisibleRect()); + log.debug("viewport size =" + viewport.getSize()); + + double setX, setY; + setX = Math.max(0, (rectangle.getCenterX() - viewport.getWidth() / 2)); + setY = Math.max(0, (rectangle.getCenterY() - viewport.getHeight() / 2)); + + setX = Math.min(setX, Math.max(0, map.getSize().getWidth() - viewport.getWidth())); + setY = Math.min(setY, Math.max(0, map.getSize().getHeight() - viewport.getHeight())); + + final Point viewPosition = new Point((int)setX, (int)setY); + log.debug("ViewPosition for ScrollPane = " + viewPosition); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + scrollPane.getViewport().setViewPosition(viewPosition); + } + }); + } + public void setAllowedTileLays(List<LayTile> allowedTileLays) { map.setAllowedTileLays(allowedTileLays); |
From: Stefan F. <ste...@us...> - 2010-06-24 21:48:17
|
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv25799/rails/algorithms Modified Files: NetworkVertex.java Log Message: Refactoring of HexMap classes to remove zoom problems Added autoscrolling support Added gamespecific config settings Index: NetworkVertex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkVertex.java,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** NetworkVertex.java 17 Jun 2010 22:10:53 -0000 1.18 --- NetworkVertex.java 24 Jun 2010 21:48:08 -0000 1.19 *************** *** 1,5 **** --- 1,7 ---- package rails.algorithms; + import java.awt.Rectangle; import java.awt.geom.Point2D; + import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collection; *************** *** 439,443 **** return guiHex.getCityPoint2D(vertex.getCity()); } else if (vertex.isMinor()) { ! return guiHex.getCenterPoint2D(); } else if (vertex.isSide()) { if (map instanceof EWHexMap) --- 441,446 ---- return guiHex.getCityPoint2D(vertex.getCity()); } else if (vertex.isMinor()) { ! return guiHex.getCityPoint2D(vertex.getCity()); ! // return guiHex.getCenterPoint2D(); } else if (vertex.isSide()) { if (map instanceof EWHexMap) *************** *** 449,453 **** } } ! ! } --- 452,483 ---- } } ! ! public static Rectangle getVertexMapCoverage(HexMap map, Collection<NetworkVertex> vertices) { ! ! Rectangle rectangle = null; ! ! // find coverage are of the vertices ! double minX=0,minY=0,maxX=0,maxY=0; ! for (NetworkVertex vertex:vertices) { ! Point2D point = getVertexPoint2D(map, vertex); ! if (point != null) { ! if (minX == 0) { // init ! rectangle = new Rectangle((int)point.getX(), (int)point.getY(), 0, 0); ! minX = point.getX(); ! minY = point.getY(); ! maxX = minX; maxY = minY; ! } else { ! rectangle.add(point); ! minX = Math.min(minX, point.getX()); ! minY = Math.min(minY, point.getY()); ! maxX = Math.max(maxX, point.getX()); ! maxY = Math.max(maxY, point.getY()); ! } ! } ! } ! log.info("Vertex Map Coverage minX=" + minX + ", minY=" + minY + ", maxX=" + maxX + ", maxY=" + maxY ); ! // Rectangle rectangle = new Rectangle((int)minX, (int)minY, (int)maxX, (int)maxY); ! log.info("Created rectangle=" + rectangle); ! return (rectangle); ! } } |
From: Stefan F. <ste...@us...> - 2010-06-24 21:48:16
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv25799/rails/game Modified Files: MapManager.java Log Message: Refactoring of HexMap classes to remove zoom problems Added autoscrolling support Added gamespecific config settings Index: MapManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/MapManager.java,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** MapManager.java 4 Apr 2010 22:02:53 -0000 1.22 --- MapManager.java 24 Jun 2010 21:48:08 -0000 1.23 *************** *** 29,32 **** --- 29,33 ---- protected SortedSet<Integer> possibleTileCosts; + // information to define neighbors protected static final int[] xDeltaNS = new int[] { 0, -1, -1, 0, +1, +1 }; protected static final int[] yXEvenDeltaNS = |
From: Stefan F. <ste...@us...> - 2010-06-24 21:48:16
|
Update of /cvsroot/rails/18xx/rails/util In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv25799/rails/util Modified Files: Config.java Log Message: Refactoring of HexMap classes to remove zoom problems Added autoscrolling support Added gamespecific config settings Index: Config.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/util/Config.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Config.java 15 May 2010 22:44:46 -0000 1.12 --- Config.java 24 Jun 2010 21:48:08 -0000 1.13 *************** *** 7,10 **** --- 7,12 ---- import org.apache.log4j.Logger; + import rails.game.GameManager; + /** * This is a simple utility class with a collection of static functions to load *************** *** 39,42 **** --- 41,62 ---- } + /** + * First tries to return {key}.{gameName}, if undefined returns {key} + */ + public static String getGameSpecific(String key) { + return Config.getSpecific(key, GameManager.getInstance().getGameName()); + } + + /** + * First tries to return {key}.{appendix}, if undefined returns {key} + */ + public static String getSpecific(String key, String appendix) { + String value = Config.get(key + "." + appendix); + if (value == "") { + value = Config.get(key); + } + return value; + } + public static String get(String key) { |
From: Stefan F. <ste...@us...> - 2010-06-24 21:48:16
|
Update of /cvsroot/rails/18xx In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv25799 Modified Files: my.properties Log Message: Refactoring of HexMap classes to remove zoom problems Added autoscrolling support Added gamespecific config settings Index: my.properties =================================================================== RCS file: /cvsroot/rails/18xx/my.properties,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** my.properties 22 Jun 2010 18:10:14 -0000 1.17 --- my.properties 24 Jun 2010 21:48:08 -0000 1.18 *************** *** 107,117 **** #or.number_format=simple ! ### Fonts - global settings ! # Font size scaling (1.0 = default standard size) ! #font.global.scale=1.0 ! # Font selection ! #font.global.name=Arial ! # Font style (only plain and bold supported) ! #font.global.style=bold ### Colours --- 107,129 ---- #or.number_format=simple ! ### Fonts for user interface ! ## Font size scaling (1.0 = default standard size) ! #font.ui.scale=1.5 ! ## Font selection ! #font.ui.name=Arial ! ## Font style (only plain and bold supported) ! #font.ui.style=plain ! ## all settings above can have game specific settings ! ## simply add the name of the game as appendix, Example: ! #font.ui.scale.18EU=0.8 ! ! ### Map display ! ## Zoomstep for map (10 = default) ! #map.zoomstep=10 ! ## Scrolling to show the network of acting company (yes = default) ! #map.autoscroll=yes ! ## all settings above can have game specific settings ! #map.zoomstep.18EU=8 ! ### Colours |
From: Stefan F. <ste...@us...> - 2010-06-24 21:48:16
|
Update of /cvsroot/rails/18xx/rails/ui/swing/hexmap In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv25799/rails/ui/swing/hexmap Modified Files: EWHexMap.java GUIHex.java NSHexMap.java HexMap.java Log Message: Refactoring of HexMap classes to remove zoom problems Added autoscrolling support Added gamespecific config settings Index: NSHexMap.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/hexmap/NSHexMap.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** NSHexMap.java 14 Mar 2010 09:14:04 -0000 1.14 --- NSHexMap.java 24 Jun 2010 21:48:08 -0000 1.15 *************** *** 3,10 **** import java.awt.*; - import java.util.ArrayList; - - import rails.game.MapHex; - import rails.ui.swing.Scale; /** --- 3,6 ---- *************** *** 16,129 **** public NSHexMap() { ! cx = 0; ! cy = -scale / 2; ! scale = defaultScale = Scale.get(); ! ! } ! ! @Override ! protected void setupHexesGUI() { ! hexes = new ArrayList<GUIHex>(); ! ! hexArray = mapManager.getHexes(); ! MapHex mh; ! int ii, jj; ! h = new GUIHex[hexArray.length][hexArray[0].length]; ! for (int i = minX; i < hexArray.length; i++) { ! ii = i - minX + 1; ! for (int j = minY; j < hexArray[0].length; j++) { ! jj = j - minY + 1; ! mh = hexArray[i][j]; ! if (mh != null) { ! GUIHex hex = ! new GUIHex(this, Math.round(cx + 3 * ii ! * scale), ! (int) Math.round(cy + (2 * jj + (ii & 1)) ! * GUIHex.SQRT3 * scale), ! scale, ii, jj); ! ! hex.setHexModel(mh); ! hex.originalTileId = hex.currentTileId; ! hexesByName.put(mh.getName(), hex); ! ! h[i][j] = hex; ! hexes.add(hex); ! } ! } ! } ! setSize(); } ! protected void setSize() { ! preferredSize = ! new Dimension( ! (int) Math.round((hexArray.length + 1) * 3 * scale * zoomFactor), ! (int) Math.round((hexArray[0].length + 1) * 2 ! * GUIHex.SQRT3 * scale * zoomFactor)); } ! ! @Override ! protected void scaleHexesGUI() { ! ! hexArray = mapManager.getHexes(); ! GUIHex hex; ! int ii, jj; ! ! for (int i = 0; i < hexArray.length; i++) { ! ii = i - minX + 1; ! for (int j = 0; j < hexArray[0].length; j++) { ! jj = j - minY + 1; ! hex = h[i][j]; ! if (hex != null) { ! hex.scaleHex(cx + 3 * ii * scale, ! cy + (2 * jj + (ii & 1)) * GUIHex.SQRT3 * scale, ! scale, zoomFactor); ! } ! } ! } ! setSize(); } ! @Override ! public void paint(Graphics g) { ! ! super.paint(g); ! Graphics2D g2 = (Graphics2D) g; ! String label; ! int ii, jj; ! ! boolean lettersGoHorizontal = mapManager.lettersGoHorizontal(); ! int xOffset = mapManager.letterAHasEvenNumbers() ? 1 : 0; ! int xLeft = cx + 10; ! int xRight = (cx + 5 + 3 * scale * hexArray.length); ! int yTop = 20; ! int yBottom = (int)(cy + 20 + 2 * hexArray[0].length * GUIHex.SQRT3 * scale); ! ! for (int i = 1; i < hexArray.length; i++) { ! ii = i - minX + 1; ! label = lettersGoHorizontal ! ? String.valueOf((char)('@'+i)) ! : String.valueOf(i); ! g2.drawString(label, ! (cx - 30 -3*label.length() + 3 * scale * (ii + xOffset)), ! yTop); ! g2.drawString(label, ! (cx - 30 -3*label.length() + 3 * scale * (ii + xOffset)), ! yBottom); ! } ! ! for (int j = 1; j < 2 * hexArray[0].length; j++) { ! jj = j - minY + 1; ! label = lettersGoHorizontal ! ? String.valueOf(j) ! : String.valueOf((char)('@'+j)); ! g2.drawString(label, ! xLeft, ! (int)(cy + 56 + jj * GUIHex.SQRT3 * scale)); ! g2.drawString(label, ! xRight, ! (int)(cy + 56 + jj * GUIHex.SQRT3 * scale)); ! } } } --- 12,41 ---- public NSHexMap() { ! // tile x-reference in NS is 1/3 of the baseline ! tileXOffset = -0.333; ! // tile y-reference in NS is baseline ! tileYOffset = -0.5; ! // coordinate margins ! coordinateXMargin = coordinatePeakMargin; ! coordinateYMargin = coordinateFlatMargin; } ! protected double calcXCoordinates(int col, double offset) { ! double colAdj = col - minCol + peakMargin + offset; ! // log.debug("x-Coordinate for col= " + col + " -> colAdj = " + colAdj); ! return Math.round(scale * 3 * colAdj); } ! ! protected double calcYCoordinates(int row, double offset) { ! double rowAdj = (row - minRow)/2.0 + flatMargin + offset; ! // log.debug("y-Coordinate for row= " + row + " -> rowAdj = " + rowAdj); ! return Math.round(scale * 2 * GUIHex.SQRT3 * rowAdj); } ! protected void setSize() { ! preferredSize = new Dimension( (int) calcXCoordinates(maxCol, peakMargin), ! (int) calcYCoordinates(maxRow, flatMargin)); } + } Index: EWHexMap.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/hexmap/EWHexMap.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** EWHexMap.java 21 Mar 2010 12:55:33 -0000 1.15 --- EWHexMap.java 24 Jun 2010 21:48:08 -0000 1.16 *************** *** 3,10 **** import java.awt.*; - import java.util.ArrayList; - - import rails.game.MapHex; - import rails.ui.swing.Scale; /** --- 3,6 ---- *************** *** 16,134 **** public EWHexMap() { ! scale = defaultScale = 2 * Scale.get(); ! //cx = scale / 2; ! cx = -scale/2; ! cy = scale/2; ! } ! ! @Override ! protected void setupHexesGUI() { ! ! hexes = new ArrayList<GUIHex>(); ! ! hexArray = mapManager.getHexes(); ! MapHex mh; ! int ii, jj; ! h = new GUIHex[hexArray.length][hexArray[0].length]; ! for (int i = minX; i < hexArray.length; i++) { ! ii = i - minX + 1; ! for (int j = minY; j < hexArray[0].length; j++) { ! jj = j - minY + 1; ! mh = hexArray[i][j]; ! if (mh != null) { ! GUIHex hex = ! new GUIHex( ! this, ! (cx + scale ! * ((GUIHex.SQRT3 * ii) + (GUIHex.SQRT3 / 2 * (j & 1)))), ! (cy + jj * 1.5 * scale), scale, ii, jj); ! ! hex.setHexModel(mh); ! hex.originalTileId = hex.currentTileId; ! hexesByName.put(mh.getName(), hex); ! ! h[i][j] = hex; ! hexes.add(hex); ! } ! } ! } ! setSize(); ! } ! protected void setSize() { ! preferredSize = ! new Dimension( ! (int) Math.round((maxX-minX + 3) * GUIHex.SQRT3 ! * scale * zoomFactor), ! (int) Math.round((maxY-minY + 3) * 1.5 * scale * zoomFactor)); } ! ! @Override ! protected void scaleHexesGUI () { ! ! hexArray = mapManager.getHexes(); ! GUIHex hex; ! int ii, jj; ! for (int i = minX; i < hexArray.length; i++) { ! ii = i - minX + 1; ! for (int j = minY; j < hexArray[0].length; j++) { ! jj = j - minY + 1; ! hex = h[i][j]; ! if (hex != null) { ! hex.scaleHex(cx + scale * ((GUIHex.SQRT3 * ii) + (GUIHex.SQRT3 / 2 * (j & 1))), ! cy + jj * 1.5 * scale, ! scale, zoomFactor); ! ! } ! } ! } ! ! setSize(); } ! @Override ! public void paint(Graphics g) { ! ! super.paint(g); ! Graphics2D g2 = (Graphics2D) g; ! String label; ! int ii, jj; ! ! boolean lettersGoHorizontal = mapManager.lettersGoHorizontal(); ! int xOffset = (mapManager.letterAHasEvenNumbers() ? 0 : 1) + (minCol % 2); ! int xLeft = cx + scale; ! int xRight = (int)(cx + scale * (3 + GUIHex.SQRT3/2 * (maxCol-minCol+1))); ! int yTop = cy; ! int yBottom = (int)(cy + scale + (maxRow-minRow+1) * 1.5 * scale); ! ! for (int i = minCol; i <= maxCol; i++) { ! ii = i - minCol + 1; ! label = lettersGoHorizontal ! ? String.valueOf((char)('@'+i)) ! : String.valueOf(i); ! g2.drawString(label, ! (int) (cx + (26-3*label.length()) + scale * (GUIHex.SQRT3/2 * (ii + xOffset))), ! yTop); ! g2.drawString(label, ! (int) (cx + (26-3*label.length()) + scale * (GUIHex.SQRT3/2 * (ii + xOffset))), ! yBottom); ! } ! ! for (int j = minRow; j <= maxRow; j++) { ! jj = j - minRow + 1; ! label = lettersGoHorizontal ! ? String.valueOf(j) ! : String.valueOf((char)('@'+j)); ! g2.drawString(label, ! xLeft, ! (int)(cy - 10 + jj * 1.5 * scale)); ! g2.drawString(label, ! xRight, ! (int)(cy - 10 + jj * 1.5 * scale)); ! } ! ! } --- 12,43 ---- public EWHexMap() { ! // tile x-reference in EW is left side ! tileXOffset = -0.5; ! // tile y-reference in EW is 1/3 of the baseline ! tileYOffset = 0.333; ! // coordinate margins ! coordinateXMargin = coordinateFlatMargin; ! coordinateYMargin = coordinatePeakMargin; } ! ! @Override ! protected double calcXCoordinates(int col, double offset) { ! double colAdj = (col - minCol)/2.0 + flatMargin + offset; ! // log.debug("x-Coordinate for col= " + col + " -> colAdj = " + colAdj); ! return Math.round(scale * 2 * GUIHex.SQRT3 * colAdj); } ! @Override ! protected double calcYCoordinates(int row, double offset) { ! double rowAdj = row - minRow + peakMargin+ offset; ! // log.debug("y-Coordinate for row= " + row + " -> rowAdj = " + rowAdj); ! return Math.round(scale * 3 * rowAdj); } ! @Override ! protected void setSize() { ! preferredSize = new Dimension( (int) calcXCoordinates(maxCol, flatMargin), ! (int) calcYCoordinates(maxRow, peakMargin)); } Index: HexMap.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/hexmap/HexMap.java,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** HexMap.java 15 May 2010 22:44:46 -0000 1.26 --- HexMap.java 24 Jun 2010 21:48:08 -0000 1.27 *************** *** 16,19 **** --- 16,20 ---- import rails.ui.swing.GameUIManager; import rails.ui.swing.ORUIManager; + import rails.ui.swing.Scale; import rails.util.*; *************** *** 31,38 **** protected MapManager mapManager; - // Abstract Methods - protected abstract void setupHexesGUI(); - protected abstract void scaleHexesGUI(); - // GUI hexes need to be recreated for each object, since scale varies. protected GUIHex[][] h; --- 32,35 ---- *************** *** 41,50 **** protected Map<String, GUIHex> hexesByName = new HashMap<String, GUIHex>(); protected ArrayList<GUIHex> hexes; - protected int defaultScale; protected int scale; ! protected int zoomStep = 10; ! protected double zoomFactor = 1.0; ! protected int cx; ! protected int cy; protected GUIHex selectedHex = null; protected Dimension preferredSize; --- 38,48 ---- protected Map<String, GUIHex> hexesByName = new HashMap<String, GUIHex>(); protected ArrayList<GUIHex> hexes; protected int scale; ! protected int zoomStep = 10; // can be overwritten in config ! protected double zoomFactor = 1; // defined dynamically if zoomStep changed ! protected double peakMargin = 1.0; ! protected double flatMargin = 0.80; ! protected double coordinatePeakMargin = 0.80; ! protected double coordinateFlatMargin = 0.60; protected GUIHex selectedHex = null; protected Dimension preferredSize; *************** *** 76,80 **** protected int strokeCap = BasicStroke.CAP_ROUND; protected int strokeJoin = BasicStroke.JOIN_BEVEL; ! static { try { --- 74,89 ---- protected int strokeCap = BasicStroke.CAP_ROUND; protected int strokeJoin = BasicStroke.JOIN_BEVEL; ! ! // Abstract Methods, implemented depending on the map type (EW or NS) ! protected abstract double calcXCoordinates(int col, double offset); ! protected abstract double calcYCoordinates(int row, double offset); ! protected abstract void setSize(); ! ! // ("Abstract") Variables to be initialized by map type subclasses ! protected double tileXOffset; ! protected double tileYOffset; ! protected double coordinateXMargin; ! protected double coordinateYMargin; ! static { try { *************** *** 93,98 **** --- 102,109 ---- public void init(ORUIManager orUIManager, MapManager mapManager) { + this.orUIManager = orUIManager; this.mapManager = mapManager; + minX = mapManager.getMinX(); minY = mapManager.getMinY(); *************** *** 103,111 **** maxRow = mapManager.getMaxRow(); maxCol = mapManager.getMaxCol(); ! setupHexes(); trainColors = new Color[]{colour1, colour2, colour3, colour4}; } public void setupHexes() { setupHexesGUI(); --- 114,232 ---- maxRow = mapManager.getMaxRow(); maxCol = mapManager.getMaxCol(); ! log.debug("HexMap init: minX="+ minX + ",minY=" + minY + ",maxX=" +maxX + ",maxY=" + maxY); ! log.debug("HexMap init: minCol="+ minCol + ",minRow=" + minRow + ",maxCol=" +maxCol + ",maxRow=" + maxRow); + setScale(); + setupHexes(); + + initializeSettings(); + } + + /** + * defines settings from the config files + */ + private void initializeSettings() { trainColors = new Color[]{colour1, colour2, colour3, colour4}; + + // define zoomStep from config + String zoomStepSetting = Config.getGameSpecific("map.zoomstep"); + if (Util.hasValue(zoomStepSetting)) { + try { + int newZoomStep = Integer.parseInt(zoomStepSetting); + if (zoomStep != newZoomStep) { + zoomStep = newZoomStep; + zoom(); + } + } catch (NumberFormatException e) { + // otherwise keep default defined above + } + } + } + + protected void setupHexesGUI() { + + hexes = new ArrayList<GUIHex>(); + + hexArray = mapManager.getHexes(); + MapHex mh; + + h = new GUIHex[hexArray.length][hexArray[0].length]; + for (int i = minX; i < hexArray.length; i++) { + for (int j = minY; j < hexArray[0].length; j++) { + mh = hexArray[i][j]; + if (mh != null) { + GUIHex hex = new GUIHex(this, calcXCoordinates(mh.getColumn(), tileXOffset), + calcYCoordinates(mh.getRow(), tileYOffset), + scale, i-minX+1, j-minY+1); + hex.setHexModel(mh); + hex.originalTileId = hex.currentTileId; + hexesByName.put(mh.getName(), hex); + h[i][j] = hex; + hexes.add(hex); + } + } + } + setSize(); } + + protected void scaleHexesGUI () { + hexArray = mapManager.getHexes(); + GUIHex hex; + for (int i = minX; i < hexArray.length; i++) { + for (int j = minY; j < hexArray[0].length; j++) { + hex = h[i][j]; + MapHex mh = hexArray[i][j]; + if (hex != null) { + hex.scaleHex(calcXCoordinates(mh.getColumn(), tileXOffset), calcYCoordinates(mh.getRow(), tileYOffset), + scale, zoomFactor); + } + } + } + setSize(); + } + + protected void drawLabel(Graphics2D g2, int index, int xCoordinate, int yCoordinate, boolean letter) { + String label = letter + ? String.valueOf((char)('@'+index)) + : String.valueOf(index); + xCoordinate -= 4.0*label.length(); + yCoordinate += 4.0; + g2.drawString(label, + xCoordinate, + yCoordinate); + + // log.debug("Draw Label " + label + " for " + index + " at x = " + xCoordinate + ", y = " + yCoordinate); + } + + @Override + public void paint(Graphics g) { + + super.paint(g); + Graphics2D g2 = (Graphics2D) g; + + boolean lettersGoHorizontal = mapManager.lettersGoHorizontal(); + int xLeft = (int)calcXCoordinates(minCol, - coordinateXMargin); + int xRight = (int)calcXCoordinates(maxCol, coordinateXMargin); + + int yTop = (int)calcYCoordinates(minRow, - coordinateYMargin); + int yBottom = (int)calcYCoordinates(maxRow, coordinateYMargin); + + for (int iCol = minCol; iCol <= maxCol; iCol++) { + int xCoordinate = (int)(calcXCoordinates(iCol, 0)); + drawLabel(g2, iCol, xCoordinate, yTop, lettersGoHorizontal); + drawLabel(g2, iCol, xCoordinate, yBottom, lettersGoHorizontal); + } + + for (int iRow = minRow; iRow <= maxRow; iRow++) { + int yCoordinate = (int)(calcYCoordinates(iRow, 0)); + drawLabel(g2, iRow, xLeft, yCoordinate, !lettersGoHorizontal); + drawLabel(g2, iRow, xRight, yCoordinate, !lettersGoHorizontal); + } + + + } + + public void setupHexes() { setupHexesGUI(); *************** *** 201,208 **** scaleHexesGUI(); revalidate(); } protected void setScale() { ! scale = (int)(defaultScale * zoomFactor); } --- 322,330 ---- scaleHexesGUI(); revalidate(); + // orUIManager.getMapPanel().resizeMapPanel(); } protected void setScale() { ! scale = (int)(Scale.get() * zoomFactor); } Index: GUIHex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/hexmap/GUIHex.java,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** GUIHex.java 20 Apr 2010 22:07:09 -0000 1.44 --- GUIHex.java 24 Jun 2010 21:48:08 -0000 1.45 *************** *** 82,86 **** double[] xVertex = new double[6]; double[] yVertex = new double[6]; ! double len; GeneralPath hexagon; Rectangle rectBound; --- 82,86 ---- double[] xVertex = new double[6]; double[] yVertex = new double[6]; ! // double len; GeneralPath hexagon; Rectangle rectBound; *************** *** 114,128 **** if (hexMap.getMapManager().getTileOrientation() == MapHex.EW) { ! len = scale; ! xVertex[0] = cx + SQRT3 / 2 * scale; ! yVertex[0] = cy + 0.5 * scale; ! xVertex[1] = cx + SQRT3 * scale; yVertex[1] = cy; ! xVertex[2] = cx + SQRT3 * scale; ! yVertex[2] = cy - 1 * scale; ! xVertex[3] = cx + SQRT3 / 2 * scale; ! yVertex[3] = cy - 1.5 * scale; xVertex[4] = cx; ! yVertex[4] = cy - 1 * scale; xVertex[5] = cx; yVertex[5] = cy; --- 114,128 ---- if (hexMap.getMapManager().getTileOrientation() == MapHex.EW) { ! // len = scale; ! xVertex[0] = cx + SQRT3 * scale; ! yVertex[0] = cy + scale; ! xVertex[1] = cx + 2 * SQRT3 * scale; yVertex[1] = cy; ! xVertex[2] = cx + 2 * SQRT3 * scale; ! yVertex[2] = cy - 2 * scale; ! xVertex[3] = cx + SQRT3 * scale; ! yVertex[3] = cy - 3 * scale; xVertex[4] = cx; ! yVertex[4] = cy - 2 * scale; xVertex[5] = cx; yVertex[5] = cy; *************** *** 130,134 **** baseRotation = 30; // degrees } else { ! len = scale / 3.0; xVertex[0] = cx; yVertex[0] = cy; --- 130,134 ---- baseRotation = 30; // degrees } else { ! // len = scale / 3.0; xVertex[0] = cx; yVertex[0] = cy; |
From: Stefan F. <ste...@us...> - 2010-06-22 18:10:22
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16308/rails/ui/swing Modified Files: GameUIManager.java Log Message: Added selection of font type and scaling (see feature request 2982270) Still requires some changes to adapt window sizes etc. Index: GameUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/GameUIManager.java,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** GameUIManager.java 9 Apr 2010 07:20:27 -0000 1.46 --- GameUIManager.java 22 Jun 2010 18:10:14 -0000 1.47 *************** *** 1,4 **** --- 1,5 ---- package rails.ui.swing; + import java.awt.Font; import java.io.File; import java.text.SimpleDateFormat; *************** *** 6,9 **** --- 7,11 ---- import javax.swing.*; + import javax.swing.plaf.FontUIResource; import org.apache.log4j.Logger; *************** *** 107,113 **** --- 109,144 ---- configuredStockChartVisibility = "yes".equalsIgnoreCase(Config.get("stockchart.window.open")); + // font settings + String fontType = Config.get("font.global.name"); + Font font = null; + if (Util.hasValue(fontType)) { + boolean boldStyle = true; + String fontStyle = Config.get("font.global.style"); + if (Util.hasValue(fontStyle)) { + if (fontStyle.equalsIgnoreCase("plain")) { + boldStyle = false; + } + } + if (boldStyle) { + font = new Font(fontType, Font.BOLD, 12); + } else { + font = new Font(fontType, Font.PLAIN, 12); + } + if (font != null) log.debug("Change text fonts globally to " + font.getName() + " / " + (boldStyle ? "Bold" : "Plain")); + } + + String fontScale = Config.get("font.global.scale"); + if (Util.hasValue(fontScale)) { + try { + changeGlobalFont(font, Double.parseDouble(fontScale)); + log.debug("Change text fonts to relative scale " + fontScale); + } catch (NumberFormatException e) { + // do nothing + } + } } public void gameUIInit() { + imageLoader = new ImageLoader(); stockChart = new StockChart(this); *************** *** 115,119 **** orWindow = new ORWindow(this); orUIManager = orWindow.getORUIManager(); ! String statusWindowClassName = getClassName(GuiDef.ClassName.STATUS_WINDOW); try { --- 146,150 ---- orWindow = new ORWindow(this); orUIManager = orWindow.getORUIManager(); ! String statusWindowClassName = getClassName(GuiDef.ClassName.STATUS_WINDOW); try { *************** *** 603,606 **** --- 634,664 ---- } + /** + * Change global font size + * @param scale + */ + public void changeGlobalFont(Font replaceFont, double scale) { + UIDefaults defaults = UIManager.getDefaults(); + Enumeration<Object> keys = defaults.keys(); + while(keys.hasMoreElements()) { + Object key = keys.nextElement(); + Object value = defaults.get(key); + if(value != null && value instanceof Font) { + UIManager.put(key, null); + Font font; + if (replaceFont != null) { + font = replaceFont; + } else { + font = UIManager.getFont(key); + } + if(font != null) { + float newSize = font.getSize2D() * (float)scale; + UIManager.put(key, new FontUIResource(font.deriveFont(newSize))); + } + } + } + } + + public void exportGame(GameAction exportAction) { JFileChooser jfc = new JFileChooser(); |
From: Stefan F. <ste...@us...> - 2010-06-22 18:10:22
|
Update of /cvsroot/rails/18xx In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16308 Modified Files: my.properties Log Message: Added selection of font type and scaling (see feature request 2982270) Still requires some changes to adapt window sizes etc. Index: my.properties =================================================================== RCS file: /cvsroot/rails/18xx/my.properties,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** my.properties 15 May 2010 22:44:46 -0000 1.16 --- my.properties 22 Jun 2010 18:10:14 -0000 1.17 *************** *** 107,110 **** --- 107,117 ---- #or.number_format=simple + ### Fonts - global settings + # Font size scaling (1.0 = default standard size) + #font.global.scale=1.0 + # Font selection + #font.global.name=Arial + # Font style (only plain and bold supported) + #font.global.style=bold ### Colours |
From: Stefan F. <ste...@us...> - 2010-06-21 22:58:01
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv7831/rails/game Modified Files: StartItem.java StartRound_1830.java Log Message: Fixed bug 3017632. And fixed missing unblock of cash for passing player if leave private auction option is selected in 1830 type of startround. Index: StartRound_1830.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/StartRound_1830.java,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** StartRound_1830.java 20 Apr 2010 19:21:27 -0000 1.32 --- StartRound_1830.java 21 Jun 2010 22:57:53 -0000 1.33 *************** *** 326,329 **** --- 326,330 ---- if (GameOption.OPTION_VALUE_YES.equalsIgnoreCase(getGameOption("LeaveAuctionOnPass"))) { // Game option: player to leave auction after a pass (default no). + player.unblockCash(auctionItem.getBid(player)); auctionItem.setBid(-1, player); } Index: StartItem.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/StartItem.java,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** StartItem.java 31 Jan 2010 22:22:28 -0000 1.21 --- StartItem.java 21 Jun 2010 22:57:53 -0000 1.22 *************** *** 277,280 **** --- 277,281 ---- * @param amount The bid amount. * @param bidder The bidding player. + * special amounts are 0 for 18EU as buy price, -1 as standard pass, -2 and below as pass in 18EU */ public void setBid(int amount, Player bidder) { *************** *** 290,299 **** bids[index].resetOption(MoneyModel.SUPPRESS_ZERO); bids[index].update(); ! } else { ! // Passed bids[index].set(0); bids[index].update(); } - } --- 291,299 ---- bids[index].resetOption(MoneyModel.SUPPRESS_ZERO); bids[index].update(); ! } else if (amount == -1) { ! // Passed (standard type) bids[index].set(0); bids[index].update(); } } |
From: Stefan F. <ste...@us...> - 2010-06-21 22:58:01
|
Update of /cvsroot/rails/18xx/rails/game/specific/_18EU In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv7831/rails/game/specific/_18EU Modified Files: StartRound_18EU.java Log Message: Fixed bug 3017632. And fixed missing unblock of cash for passing player if leave private auction option is selected in 1830 type of startround. Index: StartRound_18EU.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/specific/_18EU/StartRound_18EU.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** StartRound_18EU.java 27 Nov 2009 20:35:18 -0000 1.10 --- StartRound_18EU.java 21 Jun 2010 22:57:52 -0000 1.11 *************** *** 324,328 **** case BID_STEP: ! auctionedItem.setBid(-1, currentPlayer); // We are done if the next still bidding player --- 324,328 ---- case BID_STEP: ! auctionedItem.setBid(-2, currentPlayer); // We are done if the next still bidding player |
From: Stefan F. <ste...@us...> - 2010-06-21 21:35:58
|
Update of /cvsroot/rails/18xx/rails/game/action In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv18873/rails/game/action Modified Files: BuyTrain.java Log Message: Fixed missing storage of exchange train id, made save files with train exchanges unloadable beyond that point Index: BuyTrain.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/action/BuyTrain.java,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** BuyTrain.java 13 May 2010 09:51:32 -0000 1.21 --- BuyTrain.java 21 Jun 2010 21:35:50 -0000 1.22 *************** *** 65,70 **** trainsForExchangeUniqueIds = new String[trains.size()]; for (int i = 0; i < trains.size(); i++) { ! trainsForExchangeUniqueIds[i] = trains.get(i).getName(); ! // TODO: Must be replaced by unique Ids } } --- 65,70 ---- trainsForExchangeUniqueIds = new String[trains.size()]; for (int i = 0; i < trains.size(); i++) { ! trainsForExchangeUniqueIds[i] = trains.get(i).getUniqueId(); ! // Must be replaced by unique Ids - why was this a todo? } } *************** *** 202,206 **** this.exchangedTrain = exchangedTrain; if (exchangedTrain != null) ! this.exchangedTrainUniqueId = exchangedTrain.getName(); } --- 202,206 ---- this.exchangedTrain = exchangedTrain; if (exchangedTrain != null) ! this.exchangedTrainUniqueId = exchangedTrain.getUniqueId(); } |
From: Stefan F. <ste...@us...> - 2010-06-17 22:11:05
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv29142/rails/ui/swing Modified Files: ORUIManager.java ORPanel.java Log Message: First commit of the multigraph revenue calculation, still the old algorithm active Index: ORUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORUIManager.java,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** ORUIManager.java 30 May 2010 10:42:39 -0000 1.78 --- ORUIManager.java 17 Jun 2010 22:10:53 -0000 1.79 *************** *** 128,134 **** private SimpleGraph<NetworkVertex, NetworkEdge> getCompanyGraph(){ ! NetworkGraphBuilder nwGraph = NetworkGraphBuilder.createMapGraph(gameUIManager.getGameManager()); ! SimpleGraph<NetworkVertex, NetworkEdge> graph = ! nwGraph.getRailRoadGraph(orComp, true); return graph; } --- 128,134 ---- private SimpleGraph<NetworkVertex, NetworkEdge> getCompanyGraph(){ ! NetworkGraphBuilder nwGraph = NetworkGraphBuilder.create(gameUIManager.getGameManager()); ! NetworkCompanyGraph companyGraph = NetworkCompanyGraph.create(nwGraph, orComp); ! SimpleGraph<NetworkVertex, NetworkEdge> graph = companyGraph.createRouteGraph(true); return graph; } Index: ORPanel.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORPanel.java,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** ORPanel.java 30 May 2010 10:42:39 -0000 1.70 --- ORPanel.java 17 Jun 2010 22:10:53 -0000 1.71 *************** *** 11,14 **** --- 11,15 ---- import org.apache.log4j.Logger; + import org.jgrapht.graph.Multigraph; import org.jgrapht.graph.SimpleGraph; *************** *** 600,604 **** if (companyName.equals("Network")) { ! NetworkGraphBuilder nwGraph = NetworkGraphBuilder.createMapGraph(gm); SimpleGraph<NetworkVertex, NetworkEdge> mapGraph = nwGraph.getMapGraph(); --- 601,605 ---- if (companyName.equals("Network")) { ! NetworkGraphBuilder nwGraph = NetworkGraphBuilder.create(gm); SimpleGraph<NetworkVertex, NetworkEdge> mapGraph = nwGraph.getMapGraph(); *************** *** 609,621 **** CompanyManagerI cm = gm.getCompanyManager(); PublicCompanyI company = cm.getPublicCompany(companyName); List<String> addTrainList = new ArrayList<String>(); boolean anotherTrain = true; RevenueAdapter ra = null; while (anotherTrain) { ra = RevenueAdapter.createRevenueAdapter(gm, company, gm.getCurrentPhase()); for (String addTrain:addTrainList) { ra.addTrainByString(addTrain); } ! ra.initRevenueCalculator(); log.info("Revenue Adapter:" + ra); int revenueValue = ra.calculateRevenue(); --- 610,632 ---- CompanyManagerI cm = gm.getCompanyManager(); PublicCompanyI company = cm.getPublicCompany(companyName); + // + // NetworkGraphBuilder nwGraph = NetworkGraphBuilder.create(gm); + // NetworkCompanyGraph companyGraph = NetworkCompanyGraph.create(nwGraph, company); + // companyGraph.createRouteGraph(false); + // companyGraph.createRevenueGraph(new ArrayList<NetworkVertex>()); + // Multigraph<NetworkVertex, NetworkEdge> graph= companyGraph.createPhaseTwoGraph(); + // NetworkGraphBuilder.visualize(graph, "Phase Two Company Network"); + // JOptionPane.showMessageDialog(orWindow, + // "Vertices = " + graph.vertexSet().size() + ", Edges = " + graph.edgeSet().size()); List<String> addTrainList = new ArrayList<String>(); boolean anotherTrain = true; RevenueAdapter ra = null; while (anotherTrain) { + // multi ra = RevenueAdapter.createRevenueAdapter(gm, company, gm.getCurrentPhase()); for (String addTrain:addTrainList) { ra.addTrainByString(addTrain); } ! ra.initRevenueCalculator(true); log.info("Revenue Adapter:" + ra); int revenueValue = ra.calculateRevenue(); *************** *** 626,629 **** --- 637,655 ---- JOptionPane.showMessageDialog(orWindow, "RevenueValue = " + revenueValue + "\nRevenueRun = \n" + ra.getOptimalRunPrettyPrint()); + + // simple + ra = RevenueAdapter.createRevenueAdapter(gm, company, gm.getCurrentPhase()); + for (String addTrain:addTrainList) { + ra.addTrainByString(addTrain); + } + ra.initRevenueCalculator(false); + log.info("Revenue Adapter:" + ra); + revenueValue = ra.calculateRevenue(); + log.info("Revenue Value:" + revenueValue); + log.info("Revenue Run:" + ra.getOptimalRunPrettyPrint()); + ra.drawOptimalRunAsPath(orUIManager.getMap()); + orUIManager.getMap().repaint(); + JOptionPane.showMessageDialog(orWindow, "RevenueValue = " + revenueValue + + "\nRevenueRun = \n" + ra.getOptimalRunPrettyPrint()); String trainString = *************** *** 795,799 **** GameManagerI gm = orUIManager.getGameUIManager().getGameManager(); RevenueAdapter ra = RevenueAdapter.createRevenueAdapter(gm, company, gm.getCurrentPhase()); ! ra.initRevenueCalculator(); ra.addRevenueListener(this); return ra; --- 821,825 ---- GameManagerI gm = orUIManager.getGameUIManager().getGameManager(); RevenueAdapter ra = RevenueAdapter.createRevenueAdapter(gm, company, gm.getCurrentPhase()); ! ra.initRevenueCalculator(false); ra.addRevenueListener(this); return ra; |
From: Stefan F. <ste...@us...> - 2010-06-17 22:11:04
|
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv29142/rails/algorithms Modified Files: RevenueCalculator.java RevenueAdapter.java RevenueTrainRun.java NetworkEdge.java NetworkVertex.java NetworkIterator.java NetworkGraphBuilder.java Added Files: RevenueCalculatorSimple.java NetworkCompanyGraph.java RevenueCalculatorMulti.java Log Message: First commit of the multigraph revenue calculation, still the old algorithm active Index: NetworkVertex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkVertex.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** NetworkVertex.java 24 May 2010 20:37:17 -0000 1.17 --- NetworkVertex.java 17 Jun 2010 22:10:53 -0000 1.18 *************** *** 398,402 **** /** ! * Returns all vertices in a specified collection of hexes */ public static Set<NetworkVertex> getVerticesByHexes(Collection<NetworkVertex> vertices, Collection<MapHex> hexes) { --- 398,402 ---- /** ! * Filters all vertices from a collection of vertices that lay in a specified collection of hexes */ public static Set<NetworkVertex> getVerticesByHexes(Collection<NetworkVertex> vertices, Collection<MapHex> hexes) { --- NEW FILE: NetworkCompanyGraph.java --- package rails.algorithms; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.jgrapht.Graphs; import org.jgrapht.graph.Multigraph; import org.jgrapht.graph.SimpleGraph; import org.jgrapht.graph.Subgraph; import rails.algorithms.RevenueAdapter.EdgeTravel; import rails.game.PublicCompanyI; import rails.game.TokenI; /** * This class stores and creates the various graphs * defined for each company * */ public class NetworkCompanyGraph { protected static Logger log = Logger.getLogger(NetworkCompanyGraph.class.getPackage().getName()); private final NetworkGraphBuilder graphBuilder; private final PublicCompanyI company; private SimpleGraph<NetworkVertex, NetworkEdge> routeGraph; private SimpleGraph<NetworkVertex, NetworkEdge> revenueGraph; private Multigraph<NetworkVertex, NetworkEdge> phase2Graph; private Map<NetworkEdge, Set<NetworkEdge>> partial2route; private Map<NetworkEdge, Set<NetworkEdge>> route2partial; private Collection<NetworkVertex> protectedVertices; private NetworkCompanyGraph(NetworkGraphBuilder graphBuilder, PublicCompanyI company) { this.graphBuilder = graphBuilder; this.company = company; this.routeGraph = null; this.revenueGraph = null; this.phase2Graph = null; } public static NetworkCompanyGraph create(NetworkGraphBuilder graphBuilder, PublicCompanyI company) { return new NetworkCompanyGraph(graphBuilder, company); } public SimpleGraph<NetworkVertex, NetworkEdge> createRouteGraph(boolean addHQ) { // get mapgraph from builder SimpleGraph<NetworkVertex, NetworkEdge> mapGraph = graphBuilder.getMapGraph(); // set sinks on mapgraph NetworkVertex.initAllRailsVertices(mapGraph.vertexSet(), company, null); // initialized simple graph SimpleGraph<NetworkVertex, NetworkEdge> graph = new SimpleGraph<NetworkVertex, NetworkEdge>(NetworkEdge.class); // add Company HQ NetworkVertex hqVertex = new NetworkVertex(company); graph.addVertex(hqVertex); // create vertex set for subgraph List<NetworkVertex> tokenVertexes = getCompanyBaseTokenVertexes(company); Set<NetworkVertex> vertexes = new HashSet<NetworkVertex>(); for (NetworkVertex vertex:tokenVertexes){ // allow to leave tokenVertices even if those are sinks boolean storeSink = vertex.isSink(); vertex.setSink(false); vertexes.add(vertex); // add connection to graph graph.addVertex(vertex); graph.addEdge(vertex, hqVertex, new NetworkEdge(vertex, hqVertex, false)); NetworkIterator iterator = new NetworkIterator(mapGraph, vertex, company); for (;iterator.hasNext();) vertexes.add(iterator.next()); // restore sink property vertex.setSink(storeSink); } Subgraph<NetworkVertex, NetworkEdge, SimpleGraph<NetworkVertex, NetworkEdge>> subGraph = new Subgraph<NetworkVertex, NetworkEdge, SimpleGraph<NetworkVertex, NetworkEdge>> (mapGraph, vertexes); // now add all vertexes and edges to the graph Graphs.addGraph(graph, subGraph); // if addHQ is not set remove HQ vertex if (!addHQ) graph.removeVertex(hqVertex); // deactivate sinks on mapgraph NetworkVertex.initAllRailsVertices(mapGraph.vertexSet(), null, null); // store and return routeGraph = graph; return graph; } public List<NetworkVertex> getCompanyBaseTokenVertexes(PublicCompanyI company) { List<NetworkVertex> vertexes = new ArrayList<NetworkVertex>(); for (TokenI token:company.getTokens()){ NetworkVertex vertex = graphBuilder.getVertex(token); if (vertex == null) continue; vertexes.add(vertex); } return vertexes; } public SimpleGraph<NetworkVertex, NetworkEdge> createRevenueGraph(Collection<NetworkVertex> protectedVertices) { // store protected vertices this.protectedVertices = protectedVertices; // optimize graph (optimizeGraph clones the graph) revenueGraph = NetworkGraphBuilder.optimizeGraph(routeGraph, protectedVertices); return revenueGraph; } Map<NetworkEdge, EdgeTravel> getPhaseTwoEdgeSets(RevenueAdapter revenueAdapter) { Map<NetworkEdge, EdgeTravel> edgeSets = new HashMap<NetworkEdge, EdgeTravel>(); // convert route2partial and partial2route into edgesets for (NetworkEdge route:route2partial.keySet()){ EdgeTravel edgeTravel = revenueAdapter.new EdgeTravel(); for (NetworkEdge partial:route2partial.get(route)) { if (partial2route.get(partial).size() >= 2) { // only keep true sets edgeTravel.set.addAll(partial2route.get(partial)); } } edgeTravel.set.remove(route); route.setRouteCosts(edgeTravel.set.size()); // route.setRouteCosts(-(route.getSource().getValue() + route.getTarget().getValue())); // define route costs as the size of the travel set if (edgeTravel.set.size() != 0) { edgeSets.put(route, edgeTravel); } } return edgeSets; } public Multigraph<NetworkVertex, NetworkEdge> createPhaseTwoGraph() { // clone the revenueGraph SimpleGraph<NetworkVertex, NetworkEdge> graph = new SimpleGraph<NetworkVertex, NetworkEdge>(NetworkEdge.class); Graphs.addGraph(graph, revenueGraph); // the phase 2 graph is a multigraph due to the multiple routes between vertices Multigraph<NetworkVertex, NetworkEdge> graph2 = new Multigraph<NetworkVertex, NetworkEdge>(NetworkEdge.class); // define the relevant vertices: stations and protected Set<NetworkVertex> relevantVertices = new HashSet<NetworkVertex>(); if (protectedVertices != null) { // check if they are in the graph for (NetworkVertex vertex:protectedVertices) { if (graph.containsVertex(vertex)) { relevantVertices.add(vertex); } } } // add station vertices for (NetworkVertex vertex:graph.vertexSet()) { if (vertex.isStation()) { relevantVertices.add(vertex); } } // change to sink and store them List<NetworkVertex> sinkVertices = new ArrayList<NetworkVertex>(); for (NetworkVertex vertex:relevantVertices) { if (!vertex.isSink()) { vertex.setSink(true); } else { sinkVertices.add(vertex); } } // add all the relevantVertices to the phase 2 graph Graphs.addAllVertices(graph2, relevantVertices); // define the storage for the new edges to the old edges partial2route = new HashMap<NetworkEdge, Set<NetworkEdge>>(); for (NetworkEdge edge:graph.edgeSet()) { partial2route.put(edge, new HashSet<NetworkEdge>()); } route2partial = new HashMap<NetworkEdge, Set<NetworkEdge>>(); List<NetworkVertex> relevantVertices2 = new ArrayList<NetworkVertex>(relevantVertices); // Collections.sort(relevantVertices2); // run the iterator for routes for each vertex for (NetworkVertex startVertex:relevantVertices2) { startVertex.setSink(false); // deactivate sink for that vertex // define iterator to find all routes from here NetworkIterator iterator = new NetworkIterator(graph, startVertex).setRouteIterator(true); log.info("Phase 2 Graph: Start routes from " + startVertex); for (;iterator.hasNext();) { // found new route NetworkVertex nextVertex = iterator.next(); if (nextVertex.isSink() && nextVertex != startVertex) { List<NetworkVertex> route = iterator.getCurrentRoute(); log.info("Phase 2 Graph: Route found to " + nextVertex + " with route = " + route); // define routeEdge NetworkEdge routeEdge = null; Set<NetworkEdge> partialEdges = new HashSet<NetworkEdge>(); // previousVertex NetworkVertex currentVertex = null; // define new edge by going through the route edges for (NetworkVertex routeVertex:route) { if (currentVertex != null) { NetworkEdge partialEdge = graph.getEdge(currentVertex, routeVertex); if (routeEdge == null) { routeEdge = partialEdge; } else { routeEdge = NetworkEdge.mergeEdges(routeEdge, partialEdge).newEdge; } partialEdges.add(partialEdge); } currentVertex = routeVertex; } // define partial2route entries for (NetworkEdge partialEdge:partialEdges) { partial2route.get(partialEdge).add(routeEdge); } // store route2partial route2partial.put(routeEdge, partialEdges); // add new route graph2.addEdge(startVertex, currentVertex, routeEdge); } } // remove that vertex from the graph to avoid duplication of the routes graph.removeVertex(startVertex); } // restore sinkVertices for (NetworkVertex vertex:sinkVertices) { vertex.setSink(true); } log.info("Defined graph phase 2 = " + graph2); List<NetworkEdge> edges = new ArrayList<NetworkEdge>(graph2.edgeSet()); Collections.sort(edges); StringBuffer s = new StringBuffer(); for (NetworkEdge e:edges) { s.append("\n" + e.getOrderedConnection()); } log.info("Edges = " + s.toString()); // store and return phase2Graph = graph2; return graph2; } } Index: RevenueCalculator.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/RevenueCalculator.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** RevenueCalculator.java 25 May 2010 20:33:58 -0000 1.17 --- RevenueCalculator.java 17 Jun 2010 22:10:53 -0000 1.18 *************** *** 5,97 **** import org.apache.log4j.Logger; ! final class RevenueCalculator { ! private final int nbVertexes; ! private final int nbTrains; ! private final int nbEdges; ! private final int nbBonuses; // static vertex data ! private final int[][] vertexValueByTrain; // dimensions: vertexId, trainId ! private final boolean[] vertexMajor; ! private final boolean[] vertexMinor; ! private final boolean[] vertexSink; ! private final int[] vertexNbNeighbors; ! private final int[] vertexNbVisitSets; ! private final int[] vertexNbBonusSets; ! private final int[][] vertexNeighbors; ! private final int[][] vertexEdges; ! private final int[][] vertexVisitSets; // vertex belongs to a visit set, dimension: nbVertex x maxBlocks ! private final int[][] vertexBonusSets; // vertex belongs to a bonus set, dimension: nbVertex x nbBonuses // start vertexes ! private int[] startVertexes; // static edge data ! private final boolean[] edgeGreedy; ! private final int[] edgeDistance; ! ! // dynamic edge data ! private final boolean[] edgeUsed; // static train data ! private final int[] trainMaxMajors; ! private final int[] trainMaxMinors; ! private final int[] trainMaxBonuses; ! private final boolean[] trainIgnoreMinors; // dynamic train data ! private final int[] trainCurrentValue; ! private final int[] trainMajors; ! private final int[] trainMinors; ! private final int[] trainBonuses; // counts the number of bonuses received ! private final boolean[][] trainVisited; ! private final int[][] trainVertexStack; ! // private final int[][] trainEdgeStack; ! private final int[] trainStackPos; ! private final int [] trainBottomPos; ! private final int [] trainStartEdge; // static bonus data ! private final int [] bonusValue; ! private final boolean [][] bonusActiveForTrain; // dimensions: bonus x train ! private final int [] bonusRequiresVertices; // dynamic bonus data ! private final int [][] bonusTrainVertices; // run settings ! private int startTrainSet; ! private int finalTrainSet; ! private int startTrain; ! private int finalTrain; ! private boolean useRevenuePrediction; // current best run results ! private int currentBestValue; ! private final int [][] currentBestRun; // prediction data ! private int[] maxCumulatedTrainRevenues; ! private int[][] maxMajorRevenues; // dimensions trainId x nb vertex; ! private int[][] maxMinorRevenues; // dimensions trainId x nb vertex; ! private int[][] maxBonusRevenues; // dimensions trainId x nb bonuses // statistic data ! private int countVisits; ! private int countEdges; ! private int nbEdgesTravelled; ! private int nbEvaluations; ! private int nbPredictions; // revenue Adapter ! private RevenueAdapter revenueAdapter; // activate dynamic revenue modifiers ! private boolean callDynamicModifiers; // termination results ! private static enum Terminated { WithEvaluation, WithoutEvaluation, --- 5,93 ---- import org.apache.log4j.Logger; ! abstract class RevenueCalculator { ! protected final int nbVertexes; ! protected final int nbTrains; ! protected final int nbEdges; ! protected final int nbBonuses; // static vertex data ! protected final int[][] vertexValueByTrain; // dimensions: vertexId, trainId ! protected final boolean[] vertexMajor; ! protected final boolean[] vertexMinor; ! protected final boolean[] vertexSink; ! protected final int[] vertexNbNeighbors; ! protected final int[] vertexNbVisitSets; ! protected final int[] vertexNbBonusSets; ! protected final int[][] vertexNeighbors; ! protected final int[][] vertexEdges; ! protected final int[][] vertexVisitSets; // vertex belongs to a visit set, dimension: nbVertex x maxVertexSets ! protected final int[][] vertexBonusSets; // vertex belongs to a bonus set, dimension: nbVertex x nbBonuses // start vertexes ! protected int[] startVertexes; // static edge data ! protected final boolean[] edgeGreedy; ! protected final int[] edgeDistance; // static train data ! protected final int[] trainMaxMajors; ! protected final int[] trainMaxMinors; ! protected final int[] trainMaxBonuses; ! protected final boolean[] trainIgnoreMinors; // dynamic train data ! protected final int[] trainCurrentValue; ! protected final int[] trainMajors; ! protected final int[] trainMinors; ! protected final int[] trainBonuses; // counts the number of bonuses received ! protected final boolean[][] trainVisited; ! protected final int[][] trainStack; // store either vertices or edges ! protected final int[] trainStackPos; ! protected final boolean [] trainBottomActive; ! protected final int [] trainStartEdge; // static bonus data ! protected final int [] bonusValue; ! protected final boolean [][] bonusActiveForTrain; // dimensions: bonus x train ! protected final int [] bonusRequiresVertices; // dynamic bonus data ! protected final int [][] bonusTrainVertices; // run settings ! protected int startTrainSet; ! protected int finalTrainSet; ! protected int startTrain; ! protected int finalTrain; ! protected boolean useRevenuePrediction; // current best run results ! protected int currentBestValue; ! protected final int [][] currentBestRun; // prediction data ! protected int[] maxCumulatedTrainRevenues; ! protected int[][] maxMajorRevenues; // dimensions trainId x nb vertex; ! protected int[][] maxMinorRevenues; // dimensions trainId x nb vertex; ! protected int[][] maxBonusRevenues; // dimensions trainId x nb bonuses // statistic data ! protected int countVisits; ! protected int countEdges; ! protected int nbEdgesTravelled; ! protected int nbEvaluations; ! protected int nbPredictions; // revenue Adapter ! protected RevenueAdapter revenueAdapter; // activate dynamic revenue modifiers ! protected boolean callDynamicModifiers; // termination results ! protected static enum Terminated { WithEvaluation, WithoutEvaluation, *************** *** 105,112 **** public RevenueCalculator (RevenueAdapter revenueAdapter, int nbVertexes, int nbEdges, ! int maxNeighbors, int maxVertexSets, int nbTrains, int nbBonuses) { log.info("RC defined: nbVertexes = " + nbVertexes + ", nbEdges = " + nbEdges + ", maxNeighbors = " + maxNeighbors + ! ", maxVertexSets = " + maxVertexSets + ", nbTrains = " + nbTrains + ", nbBonuses = " + nbBonuses ); this.revenueAdapter = revenueAdapter; --- 101,108 ---- public RevenueCalculator (RevenueAdapter revenueAdapter, int nbVertexes, int nbEdges, ! int maxNeighbors, int maxVertexSets, int maxEdgeSets, int nbTrains, int nbBonuses) { log.info("RC defined: nbVertexes = " + nbVertexes + ", nbEdges = " + nbEdges + ", maxNeighbors = " + maxNeighbors + ! ", maxVertexSets = " + maxVertexSets + ", maxEdgeSets = " + maxEdgeSets + ", nbTrains = " + nbTrains + ", nbBonuses = " + nbBonuses ); this.revenueAdapter = revenueAdapter; *************** *** 131,135 **** edgeGreedy = new boolean[nbEdges]; edgeDistance = new int[nbEdges]; - edgeUsed = new boolean[nbEdges]; trainMaxMajors = new int[nbTrains]; --- 127,130 ---- *************** *** 143,151 **** trainBonuses = new int[nbTrains]; trainVisited = new boolean[nbTrains][nbVertexes]; - trainVertexStack = new int[nbTrains][nbVertexes + 1]; // increase necessary due to buttom train ! // trainEdgeStack = new int[nbTrains][nbVertexes + 1]; trainStackPos = new int[nbTrains]; ! trainBottomPos = new int[nbTrains]; trainStartEdge = new int[nbTrains]; --- 138,145 ---- trainBonuses = new int[nbTrains]; trainVisited = new boolean[nbTrains][nbVertexes]; // increase necessary due to buttom train ! trainStack = new int[nbTrains][nbVertexes + 1]; trainStackPos = new int[nbTrains]; ! trainBottomActive = new boolean[nbTrains]; trainStartEdge = new int[nbTrains]; *************** *** 162,166 **** } ! void setVertex(int id, boolean major, boolean minor, boolean sink) { vertexMajor[id] = major; vertexMinor[id] = minor; --- 156,160 ---- } ! final void setVertex(int id, boolean major, boolean minor, boolean sink) { vertexMajor[id] = major; vertexMinor[id] = minor; *************** *** 172,180 **** } ! void setVertexValue(int vertexId, int trainId, int value) { vertexValueByTrain[vertexId][trainId] = value; } ! void setVertexNeighbors(int id, int[] neighbors, int[] edges) { // copy neighbors for (int j=0; j < neighbors.length; j++) { --- 166,174 ---- } ! final void setVertexValue(int vertexId, int trainId, int value) { vertexValueByTrain[vertexId][trainId] = value; } ! final void setVertexNeighbors(int id, int[] neighbors, int[] edges) { // copy neighbors for (int j=0; j < neighbors.length; j++) { *************** *** 186,190 **** } ! void setStartVertexes(int[] startVertexes) { this.startVertexes = startVertexes; } --- 180,184 ---- } ! final void setStartVertexes(int[] startVertexes) { this.startVertexes = startVertexes; } *************** *** 194,200 **** edgeGreedy[edgeId] = greedy; edgeDistance[edgeId] = distance; } ! void setTrain(int id, int majors, int minors, boolean ignoreMinors) { trainMaxMajors[id] = majors; trainMaxMinors[id] = minors; --- 188,196 ---- edgeGreedy[edgeId] = greedy; edgeDistance[edgeId] = distance; + // default travel sets + // edgeNbTravelSets[edgeId] = 0; } ! final void setTrain(int id, int majors, int minors, boolean ignoreMinors) { trainMaxMajors[id] = majors; trainMaxMinors[id] = minors; *************** *** 203,207 **** } ! void setVisitSet(int[] vertices) { for (int j=0; j < vertices.length; j++) { int vertexId = vertices[j]; --- 199,203 ---- } ! final void setVisitSet(int[] vertices) { for (int j=0; j < vertices.length; j++) { int vertexId = vertices[j]; *************** *** 213,217 **** } ! void setBonus(int id, int value, int[] vertices, boolean[] bonusForTrain) { log.info("RC: define bonus value = " + value + ", vertices = " + Arrays.toString(vertices) + ", bonusForTrain = " + Arrays.toString(bonusForTrain)); --- 209,214 ---- } ! ! final void setBonus(int id, int value, int[] vertices, boolean[] bonusForTrain) { log.info("RC: define bonus value = " + value + ", vertices = " + Arrays.toString(vertices) + ", bonusForTrain = " + Arrays.toString(bonusForTrain)); *************** *** 226,244 **** } ! void setDynamicModifiers(boolean activate) { callDynamicModifiers = activate; } ! int[][] getOptimalRun() { log.info("RC: currentBestRun = " + Arrays.deepToString(currentBestRun)); return currentBestRun; } ! int[][] getCurrentRun() { int[][] currentRun = new int[nbTrains][nbVertexes+1]; for (int j = startTrainSet; j <= finalTrainSet; j++) { for (int v = 0; v < nbVertexes + 1; v++) { if (v < trainStackPos[j]) { ! currentRun[j][v] = trainVertexStack[j][v]; } else { currentRun[j][v] = -1; // terminator --- 223,241 ---- } ! final void setDynamicModifiers(boolean activate) { callDynamicModifiers = activate; } ! final int[][] getOptimalRun() { log.info("RC: currentBestRun = " + Arrays.deepToString(currentBestRun)); return currentBestRun; } ! final int[][] getCurrentRun() { int[][] currentRun = new int[nbTrains][nbVertexes+1]; for (int j = startTrainSet; j <= finalTrainSet; j++) { for (int v = 0; v < nbVertexes + 1; v++) { if (v < trainStackPos[j]) { ! currentRun[j][v] = trainStack[j][v]; } else { currentRun[j][v] = -1; // terminator *************** *** 250,258 **** } ! int getNumberOfEvaluations() { return nbEvaluations; } ! String getStatistics() { StringBuffer statistics = new StringBuffer(); statistics.append(nbEvaluations + " evaluations"); --- 247,255 ---- } ! final int getNumberOfEvaluations() { return nbEvaluations; } ! final String getStatistics() { StringBuffer statistics = new StringBuffer(); statistics.append(nbEvaluations + " evaluations"); *************** *** 263,267 **** } ! private void notifyRevenueAdapter(final int revenue, final boolean finalResult) { String modifier; if (finalResult) --- 260,264 ---- } ! final private void notifyRevenueAdapter(final int revenue, final boolean finalResult) { String modifier; if (finalResult) *************** *** 273,277 **** } ! private int[] bestRevenues(int[] values, int length) { int[] bestRevenues = new int[length + 1]; Arrays.sort(values); --- 270,274 ---- } ! final private int[] bestRevenues(final int[] values, final int length) { int[] bestRevenues = new int[length + 1]; Arrays.sort(values); *************** *** 285,289 **** } ! private void initRevenueValues(int startTrain, int finalTrain){ // intialize values --- 282,286 ---- } ! final private void initRevenueValues(final int startTrain, final int finalTrain){ // intialize values *************** *** 328,332 **** } ! void initialPredictionRuns(int startTrain, int finalTrain) { if (startTrain > finalTrain) return; --- 325,329 ---- } ! final void initialPredictionRuns(final int startTrain, final int finalTrain) { if (startTrain > finalTrain) return; *************** *** 381,385 **** } ! int calculateRevenue(int startTrain, int finalTrain) { log.info("RC: calculateRevenue trains from " + startTrain + " to " + finalTrain); --- 378,382 ---- } ! final int calculateRevenue(final int startTrain, final int finalTrain) { log.info("RC: calculateRevenue trains from " + startTrain + " to " + finalTrain); *************** *** 404,574 **** } ! private void runTrain(int trainId) { ! log.debug("RC: runTrain " + trainId); ! ! // initialize value ! trainCurrentValue[trainId] = 0; ! ! // initialize train lengths ! trainMajors[trainId] = trainMaxMajors[trainId]; ! trainMinors[trainId] = trainMaxMinors[trainId]; ! trainBonuses[trainId] = trainMaxBonuses[trainId]; ! ! // initialize the positions ! trainStackPos[trainId] = 0; ! trainBottomPos[trainId] = 0; ! ! // initialize bonuses ! for (int b=0; b < nbBonuses; b++) { ! bonusTrainVertices[b][trainId] = bonusRequiresVertices[b]; ! } ! ! // check if the revenue is enough ! if (useRevenuePrediction && predictRevenues(trainId)) ! return; ! ! // try all startVertexes ! for (int i=0; i < startVertexes.length; i++) { ! int vertexId = startVertexes[i]; ! log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); ! boolean stationVertex = encounterVertex(trainId, vertexId, true); ! if (stationVertex) { ! // train cannot terminate at start vertex ! if (useRevenuePrediction && predictRevenues(trainId)) { ! // cannot beat current best value => leave immediately ! encounterVertex(trainId, vertexId, false); ! // but keep them on the visited vertex list to avoid route duplication ! trainVisited[trainId][vertexId] = true; ! log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); ! continue; ! } ! } ! ! // then try all edges of it ! // for startVertices the sink property is ignored ! for (int j = 0; j < vertexNbNeighbors[vertexId]; j++) { ! int edgeId = vertexEdges[vertexId][j]; ! if (edgeUsed[edgeId]) continue; ! log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex"); ! int neighborId = vertexNeighbors[vertexId][j]; ! if (trainVisited[trainId][neighborId]) { ! log.debug("RC: Hex already visited"); ! continue; ! } ! if (travelEdge(trainId, edgeId, true)) { ! trainStartEdge[trainId] = j; // store start edge ! nextVertex(trainId, neighborId, edgeGreedy[edgeId]); ! returnEdge(edgeId); ! } ! } ! ! // no more edges to find ! encounterVertex(trainId, vertexId, false); ! // keep them on the visited vertex list to avoid route duplication ! trainVisited[trainId][vertexId] = true; ! log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); ! } ! ! // finished all tries ! for (int i=0; i < startVertexes.length; i++) { ! // remove all of them from the visited vertex list ! trainVisited[trainId][startVertexes[i]] = false; ! } ! ! // allow that the train does not run at all ! finalizeVertex(trainId, -1); ! ! log.debug("RC: finishTrain " + trainId); ! } ! private void runBottom(int trainId) { ! log.debug("RC: runBottom " +trainId); ! ! // use startvertex, check if it is a sink ! int vertexId = trainVertexStack[trainId][0]; ! if (vertexSink[vertexId]) { ! log.debug("RC: startvertex is sink, finished bottom of " + trainId); ! return; ! } ! ! // push to stack ! trainBottomPos[trainId] = trainStackPos[trainId]; // store the stack position where bottom starts ! trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; ! log.debug("RC: Restart at bottom at stack position " + trainBottomPos[trainId]); ! ! for (int j = trainStartEdge[trainId] + 1; j < vertexNbNeighbors[vertexId]; j++) { ! int edgeId = vertexEdges[vertexId][j]; ! if (edgeUsed[edgeId]) continue; ! int neighborId = vertexNeighbors[vertexId][j]; ! log.debug("RC: Testing Neighbor Nr. " + j + " of bottomVertex is " + neighborId); ! if (trainVisited[trainId][neighborId]) { ! log.debug(" RC: Hex already visited"); ! continue; ! } ! if (travelEdge(trainId, edgeId, true)) { ! nextVertex(trainId, neighborId, edgeGreedy[edgeId]); ! returnEdge(edgeId); ! } ! } ! ! trainStackPos[trainId]--; // pull from stack ! trainBottomPos[trainId] = 0; ! log.debug("RC: finished bottom of " + trainId); ! } ! ! /** ! * arrives at an unvisited vertex ! */ ! private void nextVertex(int trainId, int vertexId, boolean previousGreedy) { - // 1. encounterVertex adds value and returns true if value vertex - Terminated trainTerminated = Terminated.NotYet; - boolean stationVertex = encounterVertex(trainId, vertexId, true); - if (stationVertex) { - // check usual train termination - trainTerminated = trainTerminated(trainId); - if (trainTerminated == Terminated.WithoutEvaluation || - useRevenuePrediction && predictRevenues(trainId)) { - // cannot beat current best value => leave immediately - encounterVertex(trainId, vertexId, false); - // returnEdge(trainId); - return; - } - } - - // 2a. visit neighbors, if train has not terminated and vertex is not a sink - if (trainTerminated == Terminated.NotYet) { - if (!vertexSink[vertexId]) { - for (int j = 0; j < vertexNbNeighbors[vertexId]; j++) { - int edgeId = vertexEdges[vertexId][j]; - if (edgeUsed[edgeId]) continue; - int neighborId = vertexNeighbors[vertexId][j]; - log.debug("RC: Testing Neighbor Nr. " + j + " of " + vertexId + " is " + neighborId); - if (trainVisited[trainId][neighborId]) { - log.debug("RC: Hex already visited"); - continue; - } - if (travelEdge(trainId, edgeId, previousGreedy)) { - nextVertex(trainId, neighborId, edgeGreedy[edgeId]); - returnEdge(edgeId); - } - } - } - // 2b. restart at startVertex for bottom part - if (stationVertex && trainBottomPos[trainId] == 0){ - runBottom(trainId); - } - } - - // 3. no more edges to visit from here => evaluate or start new train - if (stationVertex) - finalizeVertex(trainId, vertexId); - - // 4. then leave that vertex - encounterVertex(trainId, vertexId, false); - // returnEdge(trainId); - } ! private boolean encounterVertex(int trainId, int vertexId, boolean arrive) { log.debug("RC: EncounterVertex, trainId = " + trainId + " vertexId = " + vertexId + " arrive = " + arrive); --- 401,414 ---- } ! abstract protected void runTrain(final int trainId); ! abstract protected void runBottom(final int trainId); ! // next vertex is either: ! // protected void nextVertex(int trainId, int vertexId, boolean previousGreedy); ! // protected void nextVertex(int trainId, int vertexId); ! ! protected final boolean encounterVertex(final int trainId, final int vertexId, final boolean arrive) { log.debug("RC: EncounterVertex, trainId = " + trainId + " vertexId = " + vertexId + " arrive = " + arrive); *************** *** 587,591 **** stationVertex = !trainIgnoreMinors[trainId]; } - trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack countVisits++; } else { --- 427,430 ---- *************** *** 598,602 **** stationVertex = !trainIgnoreMinors[trainId]; } - trainStackPos[trainId]--; // pull from stack countVisits--; } --- 437,440 ---- *************** *** 635,665 **** return stationVertex; } - - private boolean travelEdge(int trainId, int edgeId, boolean previousGreedy) { - if (previousGreedy || edgeGreedy[edgeId]) { - log.debug("RC: Travel edge id " + edgeId); - edgeUsed[edgeId] = true; - // trainEdgeStack[trainId][trainStackPos[trainId]] = edgeId; - countEdges++; nbEdgesTravelled++; - log.debug("RC: Count Edges = " + countEdges); - return true; - } else { - log.debug("RC: Cannot travel edge id " + edgeId + ", because of greedy rule"); - return false; - } - } ! private void returnEdge(int edgeId) { ! if (edgeUsed[edgeId]) { ! edgeUsed[edgeId] = false; ! countEdges--; ! log.debug("RC: Cleared edge id " + edgeId); ! log.debug("RC: Count Edges = " + countEdges); ! } else { ! log.debug("RC: Error return edge id used: " + edgeId); ! } ! } ! private Terminated trainTerminated(int trainId) { Terminated terminated = Terminated.NotYet; if (trainIgnoreMinors[trainId]) { --- 473,484 ---- return stationVertex; } ! // travel edge is either: ! // protected boolean travelEdge(int trainId, int edgeId, boolean previousGreedy); ! // protected boolean travelEdge(int trainId, int edgeId); ! ! abstract protected void returnEdge(final int edgeId); ! protected final Terminated trainTerminated(final int trainId) { Terminated terminated = Terminated.NotYet; if (trainIgnoreMinors[trainId]) { *************** *** 680,684 **** } ! private void finalizeVertex(int trainId, int vertexId) { log.debug("RC: Finalize Vertex id " + vertexId + " for train " + trainId); --- 499,503 ---- } ! protected final void finalizeVertex(final int trainId, final int vertexId) { log.debug("RC: Finalize Vertex id " + vertexId + " for train " + trainId); *************** *** 690,694 **** } ! private void evaluateResults() { // sum to total value int totalValue = 0; --- 509,513 ---- } ! protected final void evaluateResults() { // sum to total value int totalValue = 0; *************** *** 717,721 **** for (int v = 0; v < nbVertexes + 1; v++) { if (v < trainStackPos[j]) { ! currentBestRun[j][v] = trainVertexStack[j][v]; } else { currentBestRun[j][v] = -1; // terminator --- 536,540 ---- for (int v = 0; v < nbVertexes + 1; v++) { if (v < trainStackPos[j]) { ! currentBestRun[j][v] = trainStack[j][v]; } else { currentBestRun[j][v] = -1; // terminator *************** *** 731,735 **** // predict revenues and returns true if best value can still be exceeded ! private boolean predictRevenues(int trainId){ // the potential revenues of the future trains int totalValue = 0; --- 550,554 ---- // predict revenues and returns true if best value can still be exceeded ! protected final boolean predictRevenues(final int trainId){ // the potential revenues of the future trains int totalValue = 0; *************** *** 799,802 **** --- 618,623 ---- buffer.append("edgeGreedy:" + Arrays.toString(edgeGreedy) + "\n"); buffer.append("edgeDistance:" + Arrays.toString(edgeDistance) + "\n"); + // buffer.append("edgeTravelSets:" + Arrays.deepToString(edgeTravelSets) + "\n"); + // buffer.append("egdeNbTravelSets:" + Arrays.toString(edgeNbTravelSets) + "\n"); buffer.append("startVertexes:" + Arrays.toString(startVertexes) + "\n"); buffer.append("trainMaxMajors:" + Arrays.toString(trainMaxMajors) + "\n"); Index: NetworkIterator.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkIterator.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** NetworkIterator.java 11 May 2010 21:47:21 -0000 1.6 --- NetworkIterator.java 17 Jun 2010 22:10:53 -0000 1.7 *************** *** 23,30 **** --- 23,36 ---- } + // settings private NetworkVertex startVertex; + private boolean startVertexVisited; + private boolean routeIterator; + + // internal data private List<NetworkVertex> stack = new ArrayList<NetworkVertex>(); private List<Boolean> greedyStack = new ArrayList<Boolean>(); private Map<NetworkVertex, greedyState> seen = new HashMap<NetworkVertex, greedyState>(); + private final Graph<NetworkVertex, NetworkEdge> graph; *************** *** 54,59 **** --- 60,71 ---- this.graph = graph; this.startVertex = startVertex; + this.startVertexVisited = false; + this.routeIterator = false; } + NetworkIterator setRouteIterator(boolean routeIterator) { + this.routeIterator = routeIterator; + return this; + } /** *************** *** 64,72 **** return graph; } /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { ! if (startVertex != null) { encounterStartVertex(); } --- 76,98 ---- return graph; } + + public List<NetworkVertex> getCurrentRoute() { + // extract all networkvertices just before a null + List<NetworkVertex> route = new ArrayList<NetworkVertex>(); + NetworkVertex previousVertex = null; + for (NetworkVertex vertex:stack) { + if (previousVertex != null && vertex == null) { + route.add(previousVertex); + } + previousVertex = vertex; + } + return route; + } + /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { ! if (!startVertexVisited) { encounterStartVertex(); } *************** *** 87,91 **** public NetworkVertex next() { ! if (startVertex != null) { encounterStartVertex(); } --- 113,117 ---- public NetworkVertex next() { ! if (!startVertexVisited) { encounterStartVertex(); } *************** *** 150,157 **** --- 176,186 ---- if (vertex.isSink()) return; + log.debug("Iterator: Add unseen children of " + vertex); for (NetworkEdge edge : graph.edgesOf(vertex)) { + log.debug("Iterator: Check edge for neighbor in edge " + edge.toFullInfoString()); if (!greedy || edge.isGreedy()) { NetworkVertex oppositeV = Graphs.getOppositeVertex(graph, edge, vertex); + log.debug("Iterator: Neighbor is " + oppositeV); encounterVertex(oppositeV, edge); } *************** *** 160,179 **** private void encounterStartVertex() { ! putSeenData(startVertex, true); stack.add(startVertex); greedyStack.add(false); log.debug("Iterator: Added to stack " + startVertex + " with greedy set to false"); ! startVertex = null; } private void encounterVertex(NetworkVertex v, NetworkEdge e){ ! if (stack.contains(v)) return; ! if (v.isSide() && seen.containsKey(v) && (seen.get(v) == greedyState.done || (e.isGreedy() && seen.get(v) == greedyState.nonGreedy) ! || (!e.isGreedy() && seen.get(v) == greedyState.greedy) )) { ! log.debug("Leave vertex " + v + " due to greedState rules"); ! return; } - stack.add(v); greedyStack.add(v.isSide() && !e.isGreedy()); --- 189,222 ---- private void encounterStartVertex() { ! putSeenData(startVertex, false); stack.add(startVertex); greedyStack.add(false); log.debug("Iterator: Added to stack " + startVertex + " with greedy set to false"); ! startVertexVisited = true; } private void encounterVertex(NetworkVertex v, NetworkEdge e){ ! ! if (routeIterator) { ! // if (v == startVertex) return; ! // check the stack ! if (getCurrentRoute().contains(v)) ! return; ! // check the seen components ! // if (seen.containsKey(v) && (seen.get(v) == greedyState.seen && !v.isSink() ! // || seen.get(v) == greedyState.done || (e.isGreedy() && seen.get(v) == greedyState.nonGreedy) ! // || (!e.isGreedy() && seen.get(v) == greedyState.greedy) )) { ! // log.debug("Do not add vertex " + v + " to stack"); ! // return; ! // } ! } else { ! if (stack.contains(v)) return; ! if (v.isSide() && seen.containsKey(v) && (seen.get(v) == greedyState.done || (e.isGreedy() && seen.get(v) == greedyState.nonGreedy) ! || (!e.isGreedy() && seen.get(v) == greedyState.greedy) )) { ! log.debug("Leave vertex " + v + " due to greedState rules"); ! return; ! } } stack.add(v); greedyStack.add(v.isSide() && !e.isGreedy()); *************** *** 181,185 **** } - - } --- 224,226 ---- --- NEW FILE: RevenueCalculatorSimple.java --- package rails.algorithms; final class RevenueCalculatorSimple extends RevenueCalculator { // dynamic edge data private final boolean[] edgeUsed; public RevenueCalculatorSimple (RevenueAdapter revenueAdapter, int nbVertexes, int nbEdges, int maxNeighbors, int maxVertexSets, int nbTrains, int nbBonuses) { // maxEdgeSet set to zero super(revenueAdapter, nbVertexes, nbEdges, maxNeighbors, maxVertexSets, 0, nbTrains, nbBonuses); // edge used is boolean here edgeUsed = new boolean[nbEdges]; } @Override protected final void runTrain(final int trainId) { log.debug("RC: runTrain " + trainId); // initialize value trainCurrentValue[trainId] = 0; // initialize train lengths trainMajors[trainId] = trainMaxMajors[trainId]; trainMinors[trainId] = trainMaxMinors[trainId]; trainBonuses[trainId] = trainMaxBonuses[trainId]; // initialize the positions trainStackPos[trainId] = 0; trainBottomActive[trainId] = false; // initialize bonuses for (int b=0; b < nbBonuses; b++) { bonusTrainVertices[b][trainId] = bonusRequiresVertices[b]; } // check if the revenue is enough if (useRevenuePrediction && predictRevenues(trainId)) return; // try all startVertexes for (int i=0; i < startVertexes.length; i++) { int vertexId = startVertexes[i]; log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); boolean stationVertex = encounterVertex(trainId, vertexId, true); trainStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack if (stationVertex) { // train cannot terminate at start vertex if (useRevenuePrediction && predictRevenues(trainId)) { // cannot beat current best value => leave immediately encounterVertex(trainId, vertexId, false); trainStackPos[trainId]--; // pull from stack // but keep them on the visited vertex list to avoid route duplication trainVisited[trainId][vertexId] = true; log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); continue; } } // then try all edges of it // for startVertices the sink property is ignored for (int j = 0; j < vertexNbNeighbors[vertexId]; j++) { int edgeId = vertexEdges[vertexId][j]; if (edgeUsed[edgeId]) continue; log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex"); int neighborId = vertexNeighbors[vertexId][j]; if (trainVisited[trainId][neighborId]) { log.debug("RC: Hex already visited"); continue; } if (travelEdge(trainId, edgeId, true)) { trainStartEdge[trainId] = j; // store start edge nextVertex(trainId, neighborId, edgeGreedy[edgeId]); returnEdge(edgeId); } } // no more edges to find encounterVertex(trainId, vertexId, false); trainStackPos[trainId]--; // pull from stack // keep them on the visited vertex list to avoid route duplication trainVisited[trainId][vertexId] = true; log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); } // finished all tries for (int i=0; i < startVertexes.length; i++) { // remove all of them from the visited vertex list trainVisited[trainId][startVertexes[i]] = false; } // allow that the train does not run at all finalizeVertex(trainId, -1); log.debug("RC: finishTrain " + trainId); } @Override protected final void runBottom(final int trainId) { log.debug("RC: runBottom " +trainId); // use startvertex, check if it is a sink int vertexId = trainStack[trainId][0]; if (vertexSink[vertexId]) { log.debug("RC: startvertex is sink, finished bottom of " + trainId); return; } trainBottomActive[trainId] = true; // push to stack log.debug("RC: Restart at bottom at stack position " + trainStackPos[trainId]); trainStack[trainId][trainStackPos[trainId]++] = vertexId; for (int j = trainStartEdge[trainId] + 1; j < vertexNbNeighbors[vertexId]; j++) { int edgeId = vertexEdges[vertexId][j]; if (edgeUsed[edgeId]) continue; int neighborId = vertexNeighbors[vertexId][j]; log.debug("RC: Testing Neighbor Nr. " + j + " of bottomVertex is " + neighborId); if (trainVisited[trainId][neighborId]) { log.debug(" RC: Hex already visited"); continue; } if (travelEdge(trainId, edgeId, true)) { nextVertex(trainId, neighborId, edgeGreedy[edgeId]); returnEdge(edgeId); } } trainStackPos[trainId]--; // pull from stack trainBottomActive[trainId] = false; log.debug("RC: finished bottom of " + trainId); } final private void nextVertex(final int trainId, final int vertexId, final boolean previousGreedy) { // 1. encounterVertex adds value and returns true if value vertex Terminated trainTerminated = Terminated.NotYet; boolean stationVertex = encounterVertex(trainId, vertexId, true); trainStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack if (stationVertex) { // check usual train termination trainTerminated = trainTerminated(trainId); if (trainTerminated == Terminated.WithoutEvaluation || useRevenuePrediction && predictRevenues(trainId)) { // cannot beat current best value => leave immediately encounterVertex(trainId, vertexId, false); trainStackPos[trainId]--; // pull from stack return; } } // 2a. visit neighbors, if train has not terminated and vertex is not a sink if (trainTerminated == Terminated.NotYet) { if (!vertexSink[vertexId]) { for (int j = 0; j < vertexNbNeighbors[vertexId]; j++) { int edgeId = vertexEdges[vertexId][j]; if (edgeUsed[edgeId]) continue; int neighborId = vertexNeighbors[vertexId][j]; log.debug("RC: Testing Neighbor Nr. " + j + " of " + vertexId + " is " + neighborId); if (trainVisited[trainId][neighborId]) { log.debug("RC: Hex already visited"); continue; } if (travelEdge(trainId, edgeId, previousGreedy)) { nextVertex(trainId, neighborId, edgeGreedy[edgeId]); returnEdge(edgeId); } } } // 2b. restart at startVertex for bottom part if (stationVertex && !trainBottomActive[trainId]){ runBottom(trainId); } } // 3. no more edges to visit from here => evaluate or start new train if (stationVertex) finalizeVertex(trainId, vertexId); // 4. then leave that vertex encounterVertex(trainId, vertexId, false); trainStackPos[trainId]--; // pull from stack } protected final boolean travelEdge(final int trainId, final int edgeId, final boolean previousGreedy) { if (previousGreedy || edgeGreedy[edgeId]) { log.debug("RC: Travel edge id " + edgeId); edgeUsed[edgeId] = true; // edgeUsed[edgeId]++; // trainEdgeStack[trainId][trainStackPos[trainId]] = edgeId; countEdges++; nbEdgesTravelled++; log.debug("RC: Count Edges = " + countEdges); // check edge sets // for (int j=0; j < edgeNbTravelSets[edgeId]; j++) { // edgeUsed[edgeTravelSets[edgeId][j]]++; // log.debug("RC: travelled edge " + edgeTravelSets[edgeId][j] + " due to edge set."); // } return true; } else { log.debug("RC: Cannot travel edge id " + edgeId + ", because of greedy rule"); return false; } } @Override protected final void returnEdge(final int edgeId) { if (edgeUsed[edgeId]) { edgeUsed[edgeId] = false; countEdges--; log.debug("RC: Cleared edge id " + edgeId); log.debug("RC: Count Edges = " + countEdges); } else { log.debug("RC: Error return edge id used: " + edgeId); } } } --- NEW FILE: RevenueCalculatorMulti.java --- package rails.algorithms; import rails.algorithms.RevenueCalculator.Terminated; final class RevenueCalculatorMulti extends RevenueCalculator { protected final int[] edgeNbTravelSets; protected final int[][] edgeTravelSets; // edge belongs to a travel set, dimension: nbEdges x nbTravelSets // dynamic edge data private final int[] edgeUsed; // dynamic train data private final int[] startVertexActive; public RevenueCalculatorMulti (RevenueAdapter revenueAdapter, int nbVertexes, int nbEdges, int maxNeighbors, int maxVertexSets, int maxEdgeSets, int nbTrains, int nbBonuses) { // maxEdgeSet set to zero super(revenueAdapter, nbVertexes, nbEdges, maxNeighbors, maxVertexSets, maxEdgeSets, nbTrains, nbBonuses); edgeNbTravelSets = new int[nbEdges]; edgeTravelSets = new int[nbEdges][maxEdgeSets]; // edge used is integer here edgeUsed = new int[nbEdges]; startVertexActive = new int[nbTrains]; } @Override void setEdge(int edgeId, boolean greedy, int distance) { super.setEdge(edgeId, greedy, distance); // default number for travel sets edgeNbTravelSets[edgeId] = 0; } // define edgeTravelSets void setTravelSet(int edgeId, int[] edges) { for (int j=0; j < edges.length; j++) { edgeTravelSets[edgeId][edgeNbTravelSets[edgeId]++] = edges[j]; } } @Override protected final void runTrain(final int trainId) { log.debug("RC: runTrain " + trainId); // initialize value trainCurrentValue[trainId] = 0; // initialize train lengths trainMajors[trainId] = trainMaxMajors[trainId]; trainMinors[trainId] = trainMaxMinors[trainId]; trainBonuses[trainId] = trainMaxBonuses[trainId]; // initialize the positions trainStackPos[trainId] = 0; trainBottomActive[trainId] = false; // initialize bonuses for (int b=0; b < nbBonuses; b++) { bonusTrainVertices[b][trainId] = bonusRequiresVertices[b]; } // check if the revenue is enough if (useRevenuePrediction && predictRevenues(trainId)) return; // try all startVertexes for (int i=0; i < startVertexes.length; i++) { int vertexId = startVertexes[i]; log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); boolean stationVertex = encounterVertex(trainId, vertexId, true); if (stationVertex) { // train cannot terminate at start vertex if (useRevenuePrediction && predictRevenues(trainId)) { // cannot beat current best value => leave immediately encounterVertex(trainId, vertexId, false); // but keep them on the visited vertex list to avoid route duplication trainVisited[trainId][vertexId] = true; log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); continue; } } // then try all edges of it startVertexActive[trainId] = vertexId; // for startVertices the sink property is ignored for (int j = 0; j < vertexNbNeighbors[vertexId]; j++) { int edgeId = vertexEdges[vertexId][j]; if (edgeUsed[edgeId] != 0) continue; log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex"); int neighborId = vertexNeighbors[vertexId][j]; if (trainVisited[trainId][neighborId]) { log.debug("RC: Hex already visited"); continue; } travelEdge(trainId, edgeId); trainStartEdge[trainId] = j; // store start edge nextVertex(trainId, neighborId); returnEdge(edgeId); trainStackPos[trainId]--; // pull from stack } // no more edges to find encounterVertex(trainId, vertexId, false); // keep them on the visited vertex list to avoid route duplication trainVisited[trainId][vertexId] = true; log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); } // finished all tries for (int i=0; i < startVertexes.length; i++) { // remove all of them from the visited vertex list trainVisited[trainId][startVertexes[i]] = false; } // allow that the train does not run at all finalizeVertex(trainId, -1); log.debug("RC: finishTrain " + trainId); } @Override final protected void runBottom(final int trainId) { log.debug("RC: runBottom " + trainId); // use startvertex, check if it is a sink int vertexId = startVertexActive[trainId]; if (vertexSink[vertexId]) { ... [truncated message content] |
From: Stefan F. <ste...@us...> - 2010-06-17 22:03:13
|
Update of /cvsroot/rails/18xx/rails/game/specific/_18AL In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv28571/rails/game/specific/_18AL Modified Files: NamedTrainRevenueModifier.java Log Message: Fixed 18AL bug with named trains (3017592) Index: NamedTrainRevenueModifier.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/specific/_18AL/NamedTrainRevenueModifier.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NamedTrainRevenueModifier.java 26 May 2010 19:48:57 -0000 1.2 --- NamedTrainRevenueModifier.java 17 Jun 2010 22:03:05 -0000 1.3 *************** *** 2,6 **** --- 2,8 ---- import java.util.ArrayList; + import java.util.Collection; import java.util.List; + import java.util.Set; import rails.algorithms.NetworkTrain; *************** *** 14,17 **** --- 16,20 ---- import rails.game.ConfigurationException; import rails.game.GameManagerI; + import rails.game.MapHex; import rails.game.TrainI; import rails.util.Tag; *************** *** 32,35 **** --- 35,63 ---- } + private RevenueBonus defineBonus(RevenueAdapter revenueAdapter, NamedTrainToken token, boolean useLongname) { + RevenueBonus bonus; + if (useLongname) { + bonus = new RevenueBonus(token.getValue(), token.getLongName()); + } else { + bonus = new RevenueBonus(token.getValue(), token.getName()); + } + + for (MapHex hex:token.getHexesToPass()) { + boolean stationWasFound = false; + for (NetworkVertex vertex:NetworkVertex.getVerticesByHex(revenueAdapter.getVertices(), hex)) { + if (!vertex.isStation()) continue; + bonus.addVertex(vertex); + stationWasFound = true; + } + // if for one vertex no station is found then the bonus is set null + if (!stationWasFound) { + bonus = null; + break; + } + } + return bonus; + } + + public void modifyCalculator(RevenueAdapter revenueAdapter) { // static modifier *************** *** 43,52 **** if (token == null) continue; // 2. define revenue bonus ! RevenueBonus bonus = new RevenueBonus(token.getValue(), token.getName()); bonus.addTrain(train); - for (NetworkVertex vertex:NetworkVertex.getVerticesByHexes(revenueAdapter.getVertices(), token.getHexesToPass())) { - if (!vertex.isStation()) continue; - bonus.addVertex(vertex); - } revenueAdapter.addRevenueBonus(bonus); } --- 71,77 ---- if (token == null) continue; // 2. define revenue bonus ! RevenueBonus bonus = defineBonus(revenueAdapter, token, false); ! if (bonus == null) continue; bonus.addTrain(train); revenueAdapter.addRevenueBonus(bonus); } *************** *** 66,75 **** // 3. there is only one special property in 18AL, thus get tokens from it for (NamedTrainToken token:sp.get(0).getTokens()) { ! RevenueBonus bonus = new RevenueBonus(token.getValue(), token.getLongName()); ! // 4. define vertices ! for (NetworkVertex vertex:NetworkVertex.getVerticesByHexes(revenueAdapter.getVertices(), token.getHexesToPass())) { ! if (!vertex.isStation()) continue; ! bonus.addVertex(vertex); ! } bonuses.add(bonus); bonusMaximum += token.getValue(); --- 91,96 ---- // 3. there is only one special property in 18AL, thus get tokens from it for (NamedTrainToken token:sp.get(0).getTokens()) { ! RevenueBonus bonus = defineBonus(revenueAdapter, token, true); ! if (bonus == null) continue; bonuses.add(bonus); bonusMaximum += token.getValue(); |