From: Stefan F. <ste...@us...> - 2010-03-23 18:46:08
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-1.v30.ch3.sourceforge.com:/tmp/cvs-serv10916/rails/game Modified Files: Player.java Game.java Company.java TileManager.java OperatingRound.java Token.java GameManager.java PublicCompany.java ReportBuffer.java ComponentManager.java Log Message: Implementation of Rails junit testing. More details see mail to the develop list. Index: ReportBuffer.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/ReportBuffer.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** ReportBuffer.java 31 Jan 2010 22:22:28 -0000 1.9 --- ReportBuffer.java 23 Mar 2010 18:45:15 -0000 1.10 *************** *** 15,30 **** * Class to write a log, and also to maintain a log message stack for writing to * the UI. */ public final class ReportBuffer { ! protected static String reportDirectory = null; ! protected String reportPathname = null; ! protected PrintWriter report = null; ! protected static boolean wantReport = false; ! protected static List<String> initialQueue = new ArrayList<String>(); private static final String DEFAULT_DTS_PATTERN = "yyyyMMdd_HHmm"; private static final String DEFAULT_REPORT_EXTENSION = "txt"; - protected static Logger log = - Logger.getLogger(ReportBuffer.class.getPackage().getName()); static { --- 15,46 ---- * Class to write a log, and also to maintain a log message stack for writing to * the UI. + * + * Each gameManager has one unique ReportBuffer, which is used by the public static methods. + * Messages before the creation of that buffer are kept in an internal initial queue. + * + * Also used for regression testing comparing the output of the report buffer. + * */ public final class ReportBuffer { ! /** ! * A stack for displaying messages in the Log Window. Such messages are ! * intended to record the progress of the rails.game and can be used as a ! * rails.game report. ! */ ! private List<String> reportQueue = new ArrayList<String>(); ! ! /** Another stack for messages that must "wait" for other messages */ ! private List<String> waitQueue = new ArrayList<String> (); ! ! private String reportPathname = null; ! private PrintWriter report = null; ! ! /** Initial queue for all messages, before the ReportBuffer for the GameManager is created */ ! private static List<String> initialQueue = new ArrayList<String>(); + private static boolean wantReport = false; + private static String reportDirectory = null; private static final String DEFAULT_DTS_PATTERN = "yyyyMMdd_HHmm"; private static final String DEFAULT_REPORT_EXTENSION = "txt"; static { *************** *** 33,36 **** --- 49,56 ---- } + private static Logger log = + Logger.getLogger(ReportBuffer.class.getPackage().getName()); + + public ReportBuffer() { if (!initialQueue.isEmpty()) { *************** *** 42,68 **** } - /** - * A buffer for displaying messages in the Log Window. Such messages are - * intended to record the progress of the rails.game and can be used as a - * rails.game report. - */ - private StringBuffer reportBuffer = new StringBuffer(); ! /** Add a message to the log buffer (and display it on the console) */ ! public static void add(String message) { ! GameManagerI gm = GameManager.getInstance(); ! ReportBuffer instance = null; ! if (gm != null) instance = gm.getReportBuffer(); ! if (gm == null || instance == null) { ! // Queue in a static buffer until the instance is created ! initialQueue.add(message); ! } else { ! instance.addMessage(message); ! } } private void addMessage (String message) { if (message != null) { ! reportBuffer.append(message).append("\n"); /* Also log the message */ if (message.length() > 0) log.info(message); --- 62,79 ---- } ! private List<String> getReportQueue() { ! return reportQueue; } + private void clearReportQueue() { + reportQueue.clear(); + } + private void addMessage (String message) { if (message != null) { ! if (message.equals("")) ! message = "---"; // workaround for testing ! reportQueue.add(message); /* Also log the message */ if (message.length() > 0) log.info(message); *************** *** 71,87 **** } } ! ! /** Get the current log buffer, and clear it */ ! public static String get() { ! ReportBuffer instance = getInstance(); ! String result = instance.reportBuffer.toString(); ! instance.reportBuffer = new StringBuffer(); ! return result; ! } ! ! private static ReportBuffer getInstance() { ! return GameManager.getInstance().getReportBuffer(); ! } ! private void writeToReport(String message) { --- 82,86 ---- } } ! private void writeToReport(String message) { *************** *** 130,135 **** } ! /* A stack for messages that must "wait" for other messages */ ! private List<String> waitQueue = new ArrayList<String> (); public static void addWaiting (String string) { --- 129,186 ---- } ! ! /** Get the current log buffer, and clear it */ ! public static String get() { ! ReportBuffer instance = getInstance(); ! ! // convert to String ! StringBuffer result = new StringBuffer(); ! for (String msg:instance.getReportQueue()) ! result.append(msg).append("\n"); ! ! // clear current queue ! instance.clearReportQueue(); ! ! return result.toString(); ! } ! ! /** Add a message to the log buffer (and display it on the console) */ ! public static void add(String message) { ! GameManagerI gm = GameManager.getInstance(); ! ReportBuffer instance = null; ! if (gm != null) instance = gm.getReportBuffer(); ! if (gm == null || instance == null) { ! // Queue in a static buffer until the instance is created ! initialQueue.add(message); ! } else { ! instance.addMessage(message); ! } ! } ! ! /** return the current buffer as list */ ! public static List<String> getAsList() { ! ReportBuffer instance = getInstance(); ! ! if (instance == null) ! return initialQueue; ! else ! return instance.getReportQueue(); ! } ! ! /** clear the current buffer */ ! public static void clear() { ! ReportBuffer instance = getInstance(); ! ! if (instance == null) ! initialQueue.clear(); ! else ! instance.clearReportQueue(); ! } ! ! private static ReportBuffer getInstance() { ! return GameManager.getInstance().getReportBuffer(); ! } ! ! public static void addWaiting (String string) { Index: PublicCompany.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/PublicCompany.java,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** PublicCompany.java 5 Mar 2010 20:17:32 -0000 1.91 --- PublicCompany.java 23 Mar 2010 18:44:58 -0000 1.92 *************** *** 1304,1308 **** // Calculate, round up, report and add the cash ! for (CashHolder recipient : sharesPerRecipient.keySet()) { if (recipient instanceof Bank) continue; shares = (sharesPerRecipient.get(recipient)); --- 1304,1311 ---- // Calculate, round up, report and add the cash ! ! // Define a precise sequence for the reporting ! Set<CashHolder> recipientSet = sharesPerRecipient.keySet(); ! for (CashHolder recipient : SequenceUtil.sortCashHolders(recipientSet)) { if (recipient instanceof Bank) continue; shares = (sharesPerRecipient.get(recipient)); Index: TileManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/TileManager.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** TileManager.java 15 Jan 2010 19:55:59 -0000 1.14 --- TileManager.java 23 Mar 2010 18:44:38 -0000 1.15 *************** *** 1 **** ! /* $Header$ */ package rails.game; import java.util.*; import rails.util.LocalText; import rails.util.Tag; public class TileManager implements ConfigurableComponentI { protected Map<Integer, TileI> tileMap = new HashMap<Integer, TileI>(); protected List<Integer> tileIds = new ArrayList<Integer>(); private static List<String> directories = new ArrayList<String>(); /** * No-args constructor. */ public TileManager() { } /** * @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tileSetTop) throws ConfigurationException { /* * Note: prefix se is used for elements from TileSet.xml, prefix te for * elements from Tiles.xml. */ String tileDefFileName = tileSetTop.getAttributeAsString("tiles"); if (tileDefFileName == null) throw new ConfigurationException(LocalText.getText("NoTilesXML")); //directories.add("data/" + ComponentManager.getGameName()); directories.add("data/" + GameManager.getInstance().getGameName()); Tag tileDefTop = Tag.findTopTagInFile(tileDefFileName, directories, "Tiles"); if (tileDefTop == null) throw new ConfigurationException(LocalText.getText("NoTilesTag")); List<Tag> tileSetList = tileSetTop.getChildren("Tile"); List<Tag> tileDefList = tileDefTop.getChildren("Tile"); /* * The XML files TileSet.xml and Tiles.xml are read side by side, as * each one configures different tile aspects. The reason for having two * XML files is, that Tiles.xml defines per-tile aspects that are the * same for all games (such as the colour, tracks and stations; this * file is an automatically generated subset of the generic file * tiles/Tiles.xml), whereas TileSet.xml specifies the aspects that are * (or can be) specific to each rails.game (such as the possible * upgrades). <p>TileSet.xml is leading. */ int tileId; TileI tile; // Creates maps to the tile definitions in both files. Map<Integer, Tag> tileSetMap = new HashMap<Integer, Tag>(); Map<Integer, Tag> tileDefMap = new HashMap<Integer, Tag>(); for (Tag tileSetTag : tileSetList) { tileId = tileSetTag.getAttributeAsInteger("id"); /* * Check for duplicates (this also covers missing tile ids, as this * returns 0, and we always have a tile numbered 0! */ if (tileSetMap.containsKey(tileId)) { throw new ConfigurationException(LocalText.getText( "DuplicateTilesetID", String.valueOf(tileId))); } tileSetMap.put(tileId, tileSetTag); tileIds.add(tileId); } for (Tag tileDefTag : tileDefList) { tileId = tileDefTag.getAttributeAsInteger("id"); /* * Check for duplicates (this also covers missing tile ids, as this * returns 0, and we always have a tile numbered 0! */ if (tileDefMap.containsKey(tileId)) { throw new ConfigurationException(LocalText.getText( "DuplicateTileID", String.valueOf(tileId))); } else if (!tileSetMap.containsKey(tileId)) { throw new ConfigurationException(LocalText.getText( "TileMissingInTileSet", String.valueOf(tileId))); } tileDefMap.put(tileId, tileDefTag); } // Create the Tile objects (must be done before further parsing) for (Integer id : tileSetMap.keySet()) { tile = new Tile(id); tileMap.put(id, tile); } // Finally, parse the <Tile> subtags for (Integer id : tileMap.keySet()) { tile = tileMap.get(id); tile.configureFromXML(tileSetMap.get(id), tileDefMap.get(id)); } } public void finishConfiguration (GameManagerI gameManager) throws ConfigurationException { for (TileI tile : tileMap.values()) { tile.finishConfiguration(this); } } public TileI getTile(int id) { return tileMap.get(id); } /** Get the tile IDs in the XML definition sequence */ public List<Integer> getTileIds() { return tileIds; } } \ No newline at end of file --- 1 ---- ! /* $Header$ */ package rails.game; import java.util.*; import rails.util.LocalText; import rails.util.Tag; public class TileManager implements ConfigurableComponentI { protected Map<Integer, TileI> tileMap = new HashMap<Integer, TileI>(); protected List<Integer> tileIds = new ArrayList<Integer>(); // private static List<String> directories = new ArrayList<String>(); private List<String> directories = new ArrayList<String>(); /** * No-args constructor. */ public TileManager() { } /** * @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tileSetTop) throws ConfigurationException { /* * Note: prefix se is used for elements from TileSet.xml, prefix te for * elements from Tiles.xml. */ String tileDefFileName = tileSetTop.getAttributeAsString("tiles"); if (tileDefFileName == null) throw new ConfigurationException(LocalText.getText("NoTilesXML")); //directories.add("data/" + ComponentManager.getGameName()); directories.add("data/" + GameManager.getInstance().getGameName()); Tag tileDefTop = Tag.findTopTagInFile(tileDefFileName, directories, "Tiles"); if (tileDefTop == null) throw new ConfigurationException(LocalText.getText("NoTilesTag")); List<Tag> tileSetList = tileSetTop.getChildren("Tile"); List<Tag> tileDefList = tileDefTop.getChildren("Tile"); /* * The XML files TileSet.xml and Tiles.xml are read side by side, as * each one configures different tile aspects. The reason for having two * XML files is, that Tiles.xml defines per-tile aspects that are the * same for all games (such as the colour, tracks and stations; this * file is an automatically generated subset of the generic file * tiles/Tiles.xml), whereas TileSet.xml specifies the aspects that are * (or can be) specific to each rails.game (such as the possible * upgrades). <p>TileSet.xml is leading. */ int tileId; TileI tile; // Creates maps to the tile definitions in both files. Map<Integer, Tag> tileSetMap = new HashMap<Integer, Tag>(); Map<Integer, Tag> tileDefMap = new HashMap<Integer, Tag>(); for (Tag tileSetTag : tileSetList) { tileId = tileSetTag.getAttributeAsInteger("id"); /* * Check for duplicates (this also covers missing tile ids, as this * returns 0, and we always have a tile numbered 0! */ if (tileSetMap.containsKey(tileId)) { throw new ConfigurationException(LocalText.getText( "DuplicateTilesetID", String.valueOf(tileId))); } tileSetMap.put(tileId, tileSetTag); tileIds.add(tileId); } for (Tag tileDefTag : tileDefList) { tileId = tileDefTag.getAttributeAsInteger("id"); /* * Check for duplicates (this also covers missing tile ids, as this * returns 0, and we always have a tile numbered 0! */ if (tileDefMap.containsKey(tileId)) { throw new ConfigurationException(LocalText.getText( "DuplicateTileID", String.valueOf(tileId))); } else if (!tileSetMap.containsKey(tileId)) { throw new ConfigurationException(LocalText.getText( "TileMissingInTileSet", String.valueOf(tileId))); } tileDefMap.put(tileId, tileDefTag); } // Create the Tile objects (must be done before further parsing) for (Integer id : tileSetMap.keySet()) { tile = new Tile(id); tileMap.put(id, tile); } // Finally, parse the <Tile> subtags for (Integer id : tileMap.keySet()) { tile = tileMap.get(id); tile.configureFromXML(tileSetMap.get(id), tileDefMap.get(id)); } } public void finishConfiguration (GameManagerI gameManager) throws ConfigurationException { for (TileI tile : tileMap.values()) { tile.finishConfiguration(this); } } public TileI getTile(int id) { return tileMap.get(id); } /** Get the tile IDs in the XML definition sequence */ public List<Integer> getTileIds() { return tileIds; } } \ No newline at end of file Index: GameManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/GameManager.java,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** GameManager.java 16 Mar 2010 21:22:17 -0000 1.93 --- GameManager.java 23 Mar 2010 18:44:55 -0000 1.94 *************** *** 1019,1027 **** DisplayBuffer.add(message); List<String> gameReport = getGameReport(); - StringBuilder report = new StringBuilder(); for (String s:gameReport) ! report.append(s); ! ReportBuffer.add(report.toString()); // activate gameReport for UI --- 1019,1027 ---- DisplayBuffer.add(message); + ReportBuffer.add(""); + List<String> gameReport = getGameReport(); for (String s:gameReport) ! ReportBuffer.add(s); // activate gameReport for UI *************** *** 1062,1072 **** /* Report winner */ Player winner = rankedPlayers.get(0); ! b.add(LocalText.getText("EoGWinner") + winner.getName() ! + "! \n\n"+ LocalText.getText("EoGFinalRanking") + " :"); /* Report final ranking */ int i = 0; for (Player p : rankedPlayers) { ! b.add("\n" + (++i) + ". " + Bank.format(p.getWorth()) + " " + p.getName()); } --- 1062,1072 ---- /* Report winner */ Player winner = rankedPlayers.get(0); ! b.add(LocalText.getText("EoGWinner") + winner.getName()+ "!"); ! b.add(LocalText.getText("EoGFinalRanking") + " :"); /* Report final ranking */ int i = 0; for (Player p : rankedPlayers) { ! b.add((++i) + ". " + Bank.format(p.getWorth()) + " " + p.getName()); } Index: Player.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Player.java,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** Player.java 31 Jan 2010 22:22:28 -0000 1.24 --- Player.java 23 Mar 2010 18:44:30 -0000 1.25 *************** *** 177,183 **** * Compare Players by their total worth, in descending order. This method * implements the Comparable interface. */ public int compareTo(Player p) { ! return -new Integer(getWorth()).compareTo(new Integer(p.getWorth())); } } --- 177,189 ---- * Compare Players by their total worth, in descending order. This method * implements the Comparable interface. + * second level decision is by name */ public int compareTo(Player p) { ! // first by wealth ! int result = -new Integer(getWorth()).compareTo(new Integer(p.getWorth())); ! // then by name ! if (result == 0) ! result = getName().compareTo(p.getName()); ! return result; } } Index: Token.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Token.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Token.java 8 Jan 2010 21:30:46 -0000 1.7 --- Token.java 23 Mar 2010 18:44:55 -0000 1.8 *************** *** 9,12 **** --- 9,14 ---- import java.util.Map; + import org.apache.log4j.Logger; + import rails.game.move.MoveableHolder; import rails.game.move.ObjectMove; *************** *** 24,27 **** --- 26,32 ---- private static int index = 0; + protected static Logger log = + Logger.getLogger(Token.class.getPackage().getName()); + public Token() { *************** *** 30,33 **** --- 35,45 ---- } + // initialize the special properties static variables + public static void init() { + tokenMap = new HashMap<String, TokenI>(); + index = 0; + log.debug("Init token static variables"); + } + public static TokenI getByUniqueId(String id) { return tokenMap.get(id); Index: Game.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Game.java,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** Game.java 21 Mar 2010 17:30:06 -0000 1.52 --- Game.java 23 Mar 2010 18:44:37 -0000 1.53 *************** *** 8,11 **** --- 8,12 ---- import rails.game.action.PossibleAction; + import rails.game.special.SpecialProperty; import rails.util.LocalText; import rails.util.Tag; *************** *** 89,92 **** --- 90,97 ---- ReportBuffer.add(LocalText.getText("GameIs", name)); + // set special properties and token static variables + SpecialProperty.init(); + Token.init(); + // Have the ComponentManager work through the other rails.game files componentManager.finishPreparation(); Index: Company.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/Company.java,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** Company.java 16 Mar 2010 21:22:17 -0000 1.16 --- Company.java 23 Mar 2010 18:44:38 -0000 1.17 *************** *** 14,18 **** public abstract class Company implements CompanyI, ConfigurableComponentI, ! Cloneable { protected String name; --- 14,18 ---- public abstract class Company implements CompanyI, ConfigurableComponentI, ! Cloneable, Comparable<Company> { protected String name; *************** *** 231,234 **** --- 231,245 ---- return false; } + + public int compareTo(Company otherCompany){ + int result; + // compare typeNames first + result = this.getTypeName().compareTo(otherCompany.getTypeName()); + // if same typeName then name + if (result == 0) + result = this.getName().compareTo(otherCompany.getName()); + + return result; + } public static String joinNamesWithDelimiter (List<CompanyI> companies, String delimiter) { Index: OperatingRound.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/OperatingRound.java,v retrieving revision 1.118 retrieving revision 1.119 diff -C2 -d -r1.118 -r1.119 *** OperatingRound.java 19 Mar 2010 20:51:05 -0000 1.118 --- OperatingRound.java 23 Mar 2010 18:44:44 -0000 1.119 *************** *** 71,75 **** public static final int SPLIT_ROUND_DOWN = 2; // More to the treasury ! protected static GameDef.OrStep[] steps = new GameDef.OrStep[] { GameDef.OrStep.INITIAL, --- 71,76 ---- public static final int SPLIT_ROUND_DOWN = 2; // More to the treasury ! // protected static GameDef.OrStep[] steps = ! protected GameDef.OrStep[] steps = new GameDef.OrStep[] { GameDef.OrStep.INITIAL, Index: ComponentManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/ComponentManager.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** ComponentManager.java 31 Jan 2010 22:22:28 -0000 1.17 --- ComponentManager.java 23 Mar 2010 18:45:16 -0000 1.18 *************** *** 39,43 **** protected static Logger log = Logger.getLogger(ComponentManager.class.getPackage().getName()); ! protected static List<String> directories = new ArrayList<String>(); public static synchronized ComponentManager configureInstance(String gameName, Tag tag, --- 39,44 ---- protected static Logger log = Logger.getLogger(ComponentManager.class.getPackage().getName()); ! // protected static List<String> directories = new ArrayList<String>(); ! protected List<String> directories = new ArrayList<String>(); public static synchronized ComponentManager configureInstance(String gameName, Tag tag, |