From: Stefan F. <ste...@us...> - 2012-08-22 12:15:49
|
src/rails/algorithms/NetworkCompanyGraph.java | 4 src/rails/algorithms/NetworkGraphBuilder.java | 4 src/rails/algorithms/RevenueBonusTemplate.java | 4 src/rails/algorithms/RevenueManager.java | 21 src/rails/common/parser/ComponentManager.java | 54 - src/rails/common/parser/ConfigurableComponent.java | 37 - src/rails/common/parser/GameFileParser.java | 5 src/rails/game/Bank.java | 23 src/rails/game/BaseToken.java | 10 src/rails/game/BonusToken.java | 14 src/rails/game/Company.java | 66 -- src/rails/game/CompanyManager.java | 11 src/rails/game/CompanyType.java | 9 src/rails/game/EndOfGameRound.java | 9 src/rails/game/GameManager.java | 66 -- src/rails/game/GameRoot.java | 306 ---------- src/rails/game/MapHex.java | 134 +--- src/rails/game/MapManager.java | 15 src/rails/game/OperatingRound.java | 8 src/rails/game/Phase.java | 4 src/rails/game/PhaseManager.java | 14 src/rails/game/Player.java | 20 src/rails/game/PlayerManager.java | 13 src/rails/game/PrivateCompany.java | 42 + src/rails/game/PublicCertificate.java | 46 - src/rails/game/PublicCompany.java | 60 -- src/rails/game/RailsItem.java | 44 + src/rails/game/RailsManager.java | 26 src/rails/game/RailsRoot.java | 310 +++++++++++ src/rails/game/ReportBuffer.java | 7 src/rails/game/Round.java | 22 src/rails/game/ShareSellingRound.java | 14 src/rails/game/StartItem.java | 23 src/rails/game/StartRound_1830.java | 11 src/rails/game/StartRound_1835.java | 11 src/rails/game/StockMarket.java | 22 src/rails/game/StockRound.java | 16 src/rails/game/StockSpace.java | 2 src/rails/game/Stop.java | 11 src/rails/game/TileManager.java | 14 src/rails/game/Token.java | 14 src/rails/game/Train.java | 25 src/rails/game/TrainCertificateType.java | 37 - src/rails/game/TrainManager.java | 21 src/rails/game/TrainType.java | 2 src/rails/game/TreasuryShareRound.java | 25 src/rails/game/action/LayBonusToken.java | 2 src/rails/game/correct/MapCorrectionManager.java | 12 src/rails/game/model/BaseTokensModel.java | 41 - src/rails/game/model/BonusModel.java | 2 src/rails/game/model/CertificateCountModel.java | 2 src/rails/game/model/CertificatesModel.java | 41 - src/rails/game/model/MoneyModel.java | 2 src/rails/game/model/PortfolioModel.java | 33 - src/rails/game/model/PresidentModel.java | 2 src/rails/game/model/PriceModel.java | 4 src/rails/game/model/PrivatesModel.java | 3 src/rails/game/model/ShareModel.java | 34 + src/rails/game/model/TrainsModel.java | 3 src/rails/game/special/ExchangeForShare.java | 22 src/rails/game/special/LocatedBonus.java | 21 src/rails/game/special/SellBonusToken.java | 22 src/rails/game/special/SpecialProperty.java | 40 - src/rails/game/special/SpecialRight.java | 27 src/rails/game/special/SpecialTileLay.java | 24 src/rails/game/special/SpecialTokenLay.java | 37 - src/rails/game/special/SpecialTrainBuy.java | 19 src/rails/game/specific/_1825/OperatingRound_1825.java | 11 src/rails/game/specific/_1825/StartRound_1825.java | 9 src/rails/game/specific/_1825/StockRound_1825.java | 11 src/rails/game/specific/_1835/GameManager_1835.java | 7 src/rails/game/specific/_1835/OperatingRound_1835.java | 11 src/rails/game/specific/_1835/PrussianFormationRound.java | 15 src/rails/game/specific/_1835/StockRound_1835.java | 11 src/rails/game/specific/_1851/StartRound_1851.java | 9 src/rails/game/specific/_1856/CGRFormationRound.java | 41 - src/rails/game/specific/_1856/GameManager_1856.java | 8 src/rails/game/specific/_1856/OperatingRound_1856.java | 7 src/rails/game/specific/_1856/ShareSellingRound_1856.java | 13 src/rails/game/specific/_1856/StockRound_1856.java | 15 src/rails/game/specific/_1880/StartRound_1880.java | 9 src/rails/game/specific/_1880/StockRound_1880.java | 11 src/rails/game/specific/_1889/OperatingRound_1889.java | 11 src/rails/game/specific/_18AL/NameTrains.java | 19 src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java | 4 src/rails/game/specific/_18AL/NamedTrainToken.java | 6 src/rails/game/specific/_18AL/OperatingRound_18AL.java | 11 src/rails/game/specific/_18EU/GameManager_18EU.java | 13 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 9 src/rails/game/specific/_18EU/StartRound_18EU.java | 11 src/rails/game/specific/_18EU/StockRound_18EU.java | 12 src/rails/game/specific/_18GA/OperatingRound_18GA.java | 11 src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java | 4 src/rails/game/specific/_18TN/OperatingRound_18TN.java | 7 src/rails/game/state/AbstractItem.java | 15 src/rails/game/state/ChangeStack.java | 4 src/rails/game/state/Configurable.java | 38 + src/rails/game/state/Configure.java | 62 ++ src/rails/game/state/Context.java | 26 src/rails/game/state/Creatable.java | 8 src/rails/game/state/GameRoot.java | 23 src/rails/game/state/Item.java | 2 src/rails/game/state/Manager.java | 10 src/rails/game/state/Observable.java | 19 src/rails/game/state/Ownable.java | 7 src/rails/game/state/OwnableItem.java | 10 src/rails/game/state/Portfolio.java | 56 + src/rails/game/state/Root.java | 19 src/rails/game/state/StateManager.java | 2 src/rails/ui/swing/GameSetupWindow.java | 8 src/rails/ui/swing/ORPanel.java | 4 src/rails/ui/swing/ORUIManager.java | 4 src/rails/ui/swing/UpgradesPanel.java | 6 src/rails/ui/swing/elements/Field.java | 1 src/rails/ui/swing/hexmap/GUIHex.java | 43 - src/rails/util/GameFileIO.java | 14 src/rails/util/RunGame.java | 6 src/test/TestGame.java | 4 src/test/TestGameBuilder.java | 6 119 files changed, 1393 insertions(+), 1359 deletions(-) New commits: commit 1d5a09d3d9b5da6dbdf1bf643f4362835529fba0 Author: Stefan Frey <ste...@we...> Date: Mon Aug 20 11:35:25 2012 +0200 Milestone: Startup of 1830 works Lots of small fixes Separate Portfolios for BaseToken and BonusToken Some refactoring of Round creation started diff --git a/src/rails/algorithms/NetworkCompanyGraph.java b/src/rails/algorithms/NetworkCompanyGraph.java index 0379db6..f8361ba 100644 --- a/src/rails/algorithms/NetworkCompanyGraph.java +++ b/src/rails/algorithms/NetworkCompanyGraph.java @@ -17,8 +17,8 @@ import org.jgrapht.graph.SimpleGraph; import org.jgrapht.graph.Subgraph; import rails.algorithms.RevenueAdapter.EdgeTravel; +import rails.game.BaseToken; import rails.game.PublicCompany; -import rails.game.Token; /** * This class stores and creates the various graphs @@ -115,7 +115,7 @@ public class NetworkCompanyGraph { public List<NetworkVertex> getCompanyBaseTokenVertexes(PublicCompany company) { List<NetworkVertex> vertexes = new ArrayList<NetworkVertex>(); - for (Token token:company.getLaidBaseTokens()){ + for (BaseToken token:company.getLaidBaseTokens()){ NetworkVertex vertex = graphBuilder.getVertex(token); if (vertex == null) continue; vertexes.add(vertex); diff --git a/src/rails/algorithms/NetworkGraphBuilder.java b/src/rails/algorithms/NetworkGraphBuilder.java index 3501905..9a98563 100644 --- a/src/rails/algorithms/NetworkGraphBuilder.java +++ b/src/rails/algorithms/NetworkGraphBuilder.java @@ -34,7 +34,6 @@ import rails.game.MapManager; import rails.game.PublicCompany; import rails.game.Station; import rails.game.Tile; -import rails.game.Token; import rails.game.Track; import rails.game.state.Owner; @@ -176,8 +175,7 @@ public final class NetworkGraphBuilder implements Iterable<NetworkVertex> { return mapVertexes.get(identVertex); } - public NetworkVertex getVertex(Token token) { - if (!(token instanceof BaseToken)) return null; + public NetworkVertex getVertex(BaseToken token) { Owner owner = token.getOwner(); // TODO: Check if this still works if (!(owner instanceof Stop)) return null; diff --git a/src/rails/algorithms/RevenueBonusTemplate.java b/src/rails/algorithms/RevenueBonusTemplate.java index 69b535f..2da0504 100644 --- a/src/rails/algorithms/RevenueBonusTemplate.java +++ b/src/rails/algorithms/RevenueBonusTemplate.java @@ -6,7 +6,6 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; @@ -15,13 +14,14 @@ import rails.game.Phase; import rails.game.PhaseManager; import rails.game.TrainManager; import rails.game.TrainType; +import rails.game.state.Configurable; /** * defines a template for a revenue bonus at creation time of rails objects * will be converted to a true RevenueBonus object during each revenue calculation * @author freystef */ -public final class RevenueBonusTemplate implements ConfigurableComponent { +public final class RevenueBonusTemplate implements Configurable { protected static Logger log = LoggerFactory.getLogger(RevenueBonusTemplate.class.getPackage().getName()); diff --git a/src/rails/algorithms/RevenueManager.java b/src/rails/algorithms/RevenueManager.java index 6c70b91..409102a 100644 --- a/src/rails/algorithms/RevenueManager.java +++ b/src/rails/algorithms/RevenueManager.java @@ -9,12 +9,12 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; import rails.game.state.AbstractItem; import rails.game.state.ArrayListState; +import rails.game.state.Configurable; import rails.game.state.Item; /** @@ -23,12 +23,12 @@ import rails.game.state.Item; * The conversion of Rails elements is in the responsibility of the RevenueAdapter. * For each GameManager instance only one RevenueManager is created. */ -public final class RevenueManager extends AbstractItem implements ConfigurableComponent { +public final class RevenueManager extends AbstractItem implements Configurable { protected static Logger log = LoggerFactory.getLogger(RevenueManager.class.getPackage().getName()); - private final HashSet<ConfigurableComponent> configurableModifiers = new HashSet<ConfigurableComponent>(); + private final HashSet<Configurable> configurableModifiers = new HashSet<Configurable>(); private final ArrayListState<NetworkGraphModifier> graphModifiers = ArrayListState.create(this, "graphModifiers"); private final ArrayListState<RevenueStaticModifier> staticModifiers = ArrayListState.create(this, "staticModifiers"); @@ -38,14 +38,13 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo private final ArrayList<RevenueDynamicModifier> activeDynamicModifiers = new ArrayList<RevenueDynamicModifier>(); private RevenueDynamicModifier activeCalculator; - private RevenueManager(Item parent, String id) { + /** + * Used by Configure (via reflection) only + */ + public RevenueManager(Item parent, String id) { super(parent, id); } - public static RevenueManager create(Item parent, String id){ - return new RevenueManager(parent, id); - } - public void configureFromXML(Tag tag) throws ConfigurationException { // define modifiers @@ -88,8 +87,8 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo throw new ConfigurationException(LocalText.getText( "ClassIsNotAModifier", className)); } - if (isModifier && modifier instanceof ConfigurableComponent) { - configurableModifiers.add((ConfigurableComponent)modifier); + if (isModifier && modifier instanceof Configurable) { + configurableModifiers.add((Configurable)modifier); } } } @@ -98,7 +97,7 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo public void finishConfiguration(GameManager parent) throws ConfigurationException { - for (ConfigurableComponent modifier:configurableModifiers) { + for (Configurable modifier:configurableModifiers) { modifier.finishConfiguration(parent); } } diff --git a/src/rails/common/parser/ComponentManager.java b/src/rails/common/parser/ComponentManager.java index f2607e0..89b2561 100644 --- a/src/rails/common/parser/ComponentManager.java +++ b/src/rails/common/parser/ComponentManager.java @@ -1,34 +1,35 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/ComponentManager.java,v 1.19 2010/05/18 04:12:23 stefanfrey Exp $ */ package rails.common.parser; -import java.lang.reflect.Constructor; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rails.common.LocalText; +import rails.common.parser.ConfigurationException; +import rails.common.parser.Tag; import rails.common.parser.XMLTags; -import rails.game.state.GameRoot; +import rails.game.state.Configurable; +import rails.game.state.Configure; +import rails.game.state.Context; -/** - * ComponentManage - an implementation of ComponentManagerI, which handles the - * creation and configuration of rails.game components, and acts as a discovery - * point for other components to find them. - */ public class ComponentManager { + final static Logger log = LoggerFactory.getLogger(ComponentManager.class); + private String gameName; private List<Tag> componentTags; - protected Logger log = LoggerFactory.getLogger(ComponentManager.class.getPackage().getName()); protected List<String> directories = new ArrayList<String>(); - private Map<String, ConfigurableComponent> mComponentMap = - new HashMap<String, ConfigurableComponent>(); + private Map<String, Configurable> mComponentMap = + new HashMap<String, Configurable>(); - public ComponentManager(GameRoot root, String gameName, Tag tag, Map<String, String> gameOptions) + public ComponentManager(Context context, String gameName, Tag tag, Map<String, String> gameOptions) throws ConfigurationException { this.gameName = gameName; @@ -36,12 +37,12 @@ public class ComponentManager { for (Tag component : componentTags) { String compName = component.getAttributeAsString("name"); log.debug("Found component " + compName); - configureComponent(root, component); + configureComponent(context, component); component.setGameOptions(gameOptions); } } - private void configureComponent(GameRoot root, Tag componentTag) + private void configureComponent(Context context, Tag componentTag) throws ConfigurationException { // Extract the attributes of the Component @@ -64,24 +65,7 @@ public class ComponentManager { } // Now construct the component - ConfigurableComponent component; - try { - Class<? extends ConfigurableComponent> compClass; - compClass = - Class.forName(clazz).asSubclass( - ConfigurableComponent.class); - Constructor<? extends ConfigurableComponent> compCons = - compClass.getConstructor(new Class[0]); - component = compCons.newInstance(new Object[0]); - } catch (Exception ex) { - // There are MANY things that could go wrong here. - // They all just mean that the configuration and code - // do not combine to make a well-formed system. - // Debugging aided by chaining the caught exception. - throw new ConfigurationException(LocalText.getText( - "ComponentHasNoClass", clazz), ex); - - } + Configurable component = Configure.create(Configurable.class, clazz, context, name); // Configure the component, from a file, or the embedded XML. Tag configElement = componentTag; @@ -110,8 +94,8 @@ public class ComponentManager { * @param componentName the of the component sought. * @return the component sought, or null if it has not been configured. */ - public ConfigurableComponent findComponent(String componentName) throws ConfigurationException { - ConfigurableComponent comp = mComponentMap.get(componentName); + public Configurable findComponent(String componentName) throws ConfigurationException { + Configurable comp = mComponentMap.get(componentName); //FIXME: Revenue Manager is currently optional. if (comp == null && componentName != "RevenueManager") { diff --git a/src/rails/common/parser/ConfigurableComponent.java b/src/rails/common/parser/ConfigurableComponent.java deleted file mode 100644 index 02e67f1..0000000 --- a/src/rails/common/parser/ConfigurableComponent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/ConfigurableComponentI.java,v 1.7 2009/10/31 17:08:26 evos Exp $ */ -package rails.common.parser; - -import rails.game.GameManager; - -/** - * Interface for rails.game components which can be configured from an XML - * element. - */ -public interface ConfigurableComponent { - - /** - * Instructs the component to configure itself from the provided XML - * element. - * - * @param element the XML element containing the configuration - * @throws ConfigurationException - */ - void configureFromXML(Tag tag) throws ConfigurationException; - - /** - * This method is intended to be called for each configurable - * component, to perforn any initialisation activities that - * require any other components to be initialised first. - * This includes creating any required relationships to other - * configured components and objects. - * <p>This method should be called where necessary after all - * XML file parsing has completed, so that all objects that - * need to be related to do exist. - * @param parent The 'parent' configurable component is passed to allow - * the 'child' to access any other object without the need to resort to - * static calls where possible. - */ - void finishConfiguration (GameManager parent) - throws ConfigurationException; - -} diff --git a/src/rails/common/parser/GameFileParser.java b/src/rails/common/parser/GameFileParser.java index d59b9aa..eea0f0f 100644 --- a/src/rails/common/parser/GameFileParser.java +++ b/src/rails/common/parser/GameFileParser.java @@ -3,11 +3,10 @@ package rails.common.parser; import java.util.Map; import rails.algorithms.RevenueManager; -import rails.common.parser.ComponentManager; import rails.game.Bank; import rails.game.CompanyManager; import rails.game.GameManager; -import rails.game.GameRoot; +import rails.game.RailsRoot; import rails.game.MapManager; import rails.game.PhaseManager; import rails.game.PlayerManager; @@ -32,7 +31,7 @@ public class GameFileParser extends XMLParser { private final RevenueManager revenueManager; private final Bank bank; - public GameFileParser(GameRoot root, String name, Map<String, String> gameOptions) + public GameFileParser(RailsRoot root, String name, Map<String, String> gameOptions) throws ConfigurationException { directories.add("data/" + name); diff --git a/src/rails/game/Bank.java b/src/rails/game/Bank.java index 5646bff..4f479fd 100644 --- a/src/rails/game/Bank.java +++ b/src/rails/game/Bank.java @@ -7,17 +7,17 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; import rails.common.parser.Config; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.model.CashMoneyModel; import rails.game.model.CashOwner; import rails.game.state.AbstractItem; import rails.game.state.BooleanState; +import rails.game.state.Configurable; import rails.game.state.Item; import rails.util.*; -public class Bank extends AbstractItem implements CashOwner, ConfigurableComponent { +public class Bank extends AbstractItem implements CashOwner, Configurable { private static Bank instance = null; @@ -55,7 +55,10 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone protected static Logger log = LoggerFactory.getLogger(Bank.class.getPackage().getName()); - protected Bank(Item parent, String id) { + /** + * Used by Configure (via reflection) only + */ + public Bank(Item parent, String id) { super(parent, id); instance = this; @@ -65,12 +68,8 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone } } - public static Bank create(Item parent, String id) { - return new Bank(parent, id); - } - /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { @@ -116,10 +115,9 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone for (PublicCompany comp : companies) { for (PublicCertificate cert : comp.getCertificates()) { if (cert.isInitiallyAvailable()) { - // TODO: Make this shorter - ipo.getPortfolioModel().getShareModel(comp).getPortfolio().moveInto(cert); + cert.moveTo(ipo); } else { - unavailable.getPortfolioModel().getShareModel(comp).getPortfolio().moveInto(cert); + cert.moveTo(unavailable); } } } @@ -187,8 +185,7 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone } public CashMoneyModel getCashModel() { - // TODO Auto-generated method stub - return null; + return cash; } } diff --git a/src/rails/game/BaseToken.java b/src/rails/game/BaseToken.java index d2ccde2..d1c5142 100644 --- a/src/rails/game/BaseToken.java +++ b/src/rails/game/BaseToken.java @@ -10,10 +10,10 @@ package rails.game; */ // FIXME: Check if PublicCompany is the parent of a token -public final class BaseToken extends Token { +public class BaseToken extends Token<BaseToken> { private BaseToken(PublicCompany parent, String id) { - super(parent, id); + super(parent, id, BaseToken.class); } public static BaseToken create(PublicCompany company) { @@ -34,11 +34,5 @@ public final class BaseToken extends Token { public String getId() { return getParent().getId(); } - - @Override - public String toString() { - return getId(); - } - } diff --git a/src/rails/game/BonusToken.java b/src/rails/game/BonusToken.java index a68a3d2..5341cf2 100644 --- a/src/rails/game/BonusToken.java +++ b/src/rails/game/BonusToken.java @@ -1,8 +1,9 @@ package rails.game; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; +import rails.game.state.Configurable; +import rails.game.state.Item; import rails.util.Util; /** @@ -12,8 +13,7 @@ import rails.util.Util; * which are intended for base tokens, but on some unoccupied part of a tile. */ -//FIXME: Check if PublicCompany is the parent of a token -public final class BonusToken extends Token implements Closeable, ConfigurableComponent { +public class BonusToken extends Token<BonusToken> implements Closeable, Configurable { private int value; private String name; @@ -21,13 +21,13 @@ public final class BonusToken extends Token implements Closeable, ConfigurableCo private Object removingObject = null; private PublicCompany user = null; - private BonusToken(PublicCompany parent, String id) { - super(parent, id); + private BonusToken(Item parent, String id) { + super(parent, id, BonusToken.class); } - public static BonusToken create(PublicCompany company) { + public static BonusToken create(Item parent) { String uniqueId = Token.createUniqueId(); - BonusToken token = new BonusToken(company, uniqueId); + BonusToken token = new BonusToken(parent, uniqueId); return token; } diff --git a/src/rails/game/Company.java b/src/rails/game/Company.java index 4815807..99ac8fe 100644 --- a/src/rails/game/Company.java +++ b/src/rails/game/Company.java @@ -7,18 +7,18 @@ import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableSet; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.special.SpecialProperty; import rails.game.state.BooleanState; import rails.game.state.AbstractItem; +import rails.game.state.Configurable; +import rails.game.state.Configure; import rails.game.state.Item; import rails.game.state.Owner; -import rails.game.state.PortfolioSet; import rails.util.Util; -public abstract class Company extends AbstractItem implements Owner, ConfigurableComponent, +public abstract class Company extends AbstractItem implements Owner, Configurable, Cloneable, Comparable<Company> { /** The name of the XML tag used to configure a company. */ @@ -52,10 +52,6 @@ Cloneable, Comparable<Company> { /** Closed state */ protected final BooleanState closedObject = BooleanState.create(this, "closed", false); - // Moved here from PrivayeCOmpany on behalf of 1835 - protected final PortfolioSet<SpecialProperty> specialProperties = - PortfolioSet.create(this, "specialProperties", SpecialProperty.class); - protected static Logger log = LoggerFactory.getLogger(Company.class.getPackage().getName()); @@ -81,42 +77,17 @@ Cloneable, Comparable<Company> { if (!Util.hasValue(className)) throw new ConfigurationException( "Missing class in private special property"); - SpecialProperty sp = null; - try { - sp = (SpecialProperty) Class.forName(className).newInstance(); - } catch (Exception e) { - log.error ("Cannot instantiate "+className, e); - System.exit(-1); - } + String uniqueId = SpecialProperty.createUniqueId(); + SpecialProperty sp = Configure.create(SpecialProperty.class, className, this, uniqueId); + sp.setOriginalCompany(this); sp.configureFromXML(spTag); - specialProperties.moveInto(sp); + sp.moveTo(this); parentInfoText += "<br>" + sp.getInfo(); } } } /** - * @return Set of all special properties we have. - */ - public ImmutableSet<SpecialProperty> getSpecialProperties() { - return specialProperties.items(); - } - - /** - * Do we have any special properties? - * - * @return Boolean - */ - public boolean hasSpecialProperties() { - return specialProperties != null && !specialProperties.isEmpty(); - } - - public boolean hasPortfolio() { - return true; - } - - - /** * * @return This company's number */ @@ -199,27 +170,11 @@ Cloneable, Comparable<Company> { value = i; } - // TODO: Check if this is still required, moved to subclasses -/* public Portfolio getHolder() { - return portfolio; - } -*/ - @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } - /** - * Stub method implemented to comply with HolderModel<Token>I interface. Always - * returns false. - * - * Use addToken(MapHex hex) method instead. - */ - public boolean addToken(Company company, int position) { - return false; - } - @Override public String toString() { return getTypeName() + ": " + getCompanyNumber() + ". " + getId() @@ -255,4 +210,11 @@ Cloneable, Comparable<Company> { } return b.toString(); } + + // Since 1835 required for both private and public companies + /** + * @return Set of all special properties we have. + */ + public abstract ImmutableSet<SpecialProperty> getSpecialProperties(); + } diff --git a/src/rails/game/CompanyManager.java b/src/rails/game/CompanyManager.java index 64c820a..70b173d 100644 --- a/src/rails/game/CompanyManager.java +++ b/src/rails/game/CompanyManager.java @@ -9,13 +9,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; +import rails.game.state.Configurable; import rails.game.state.Item; -public class CompanyManager extends AbstractItem implements ConfigurableComponent { +public class CompanyManager extends AbstractItem implements Configurable { /** * This is the name by which the CompanyManager should be registered with @@ -63,7 +63,10 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen protected GameManager gameManager; - protected CompanyManager(Item parent, String id) { + /** + * Used by Configure (via reflection) only + */ + public CompanyManager(Item parent, String id) { super(parent, id); } @@ -75,7 +78,7 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen */ /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { diff --git a/src/rails/game/CompanyType.java b/src/rails/game/CompanyType.java index 8025848..96d86f1 100644 --- a/src/rails/game/CompanyType.java +++ b/src/rails/game/CompanyType.java @@ -7,6 +7,7 @@ import rails.common.LocalText; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; +import rails.game.state.Configure; import rails.game.state.Item; /** @@ -58,7 +59,7 @@ public class CompanyType extends AbstractItem { } /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { //No longer needed. @@ -68,16 +69,16 @@ public class CompanyType extends AbstractItem { } - public Company createCompany(String name, Tag typeTag, Tag tag) + public Company createCompany(String id, Tag typeTag, Tag tag) throws ConfigurationException { Company newCompany = null; try { - newCompany = (Company) Class.forName(className).newInstance(); + newCompany = Configure.create(Company.class, className, this, id); } catch (Exception e) { throw new ConfigurationException(LocalText.getText( "ClassCannotBeInstantiated", className), e); } - // newCompany.init(this, name); + newCompany.initType(this); newCompany.configureFromXML(typeTag); newCompany.configureFromXML(tag); companies.add(newCompany); diff --git a/src/rails/game/EndOfGameRound.java b/src/rails/game/EndOfGameRound.java index aa4773d..8b5fd34 100644 --- a/src/rails/game/EndOfGameRound.java +++ b/src/rails/game/EndOfGameRound.java @@ -13,16 +13,15 @@ import rails.common.LocalText; public final class EndOfGameRound extends Round { - public EndOfGameRound(GameManager parent, String id) { + /** + * Constructed via Configure + */ + public EndOfGameRound(GameManager parent, String id) { super(parent, id); guiHints.setVisibilityHint(GuiDef.Panel.MAP, true); guiHints.setActivePanel(GuiDef.Panel.STATUS); } - public static EndOfGameRound create(GameManager parent, String id) { - return new EndOfGameRound(parent, id); - } - @Override public boolean setPossibleActions() { possibleActions.clear(); diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index b196d46..dd0e3e9 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -19,15 +19,11 @@ import rails.game.state.*; import rails.util.GameFileIO; import rails.util.Util; -/* - * FIXME: Removed NDC mechanism - */ - /** * This class manages the playing rounds by supervising all implementations of * Round. Currently everything is hardcoded à la 1830. */ -public class GameManager extends AbstractItem implements ConfigurableComponent, Owner { +public class GameManager extends Manager implements Configurable, Owner { /** Version ID of the Save file header, as written in save() */ private static final long saveFileHeaderVersionID = 3L; /** @@ -229,13 +225,10 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, protected static Logger log = LoggerFactory.getLogger(GameManager.class.getPackage().getName()); - // FIXME: This has to be rewritten - public GameManager() { - super(null, GM_NAME); // TODO: fix that + public GameManager(Item parent, String id) { + super(parent, id); gmName = GM_NAME; gmKey = GM_KEY; -// NDC.clear(); -// NDC.push (GM_KEY); gameManagerMap.put(GM_KEY, this); displayBuffer = new DisplayBuffer(); reportBuffer = new ReportBuffer(); @@ -618,7 +611,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, */ public static GameManager getInstance () { // return gameManagerMap.get(NDC.peek()); - return null; + return gameManagerMap.get(GM_KEY); } /* (non-Javadoc) @@ -692,20 +685,12 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, protected void startStartRound() { String startRoundClassName = startPacket.getRoundClassName(); - Class<? extends StartRound> startRoundClass = null; - try { - startRoundClass = Class.forName (startRoundClassName).asSubclass(StartRound.class); - } catch (Exception e) { - log.error("Cannot find class " - + startRoundClassName, e); - System.exit(1); - } - StartRound startRound = createRound (startRoundClass); - startRound.start (); + StartRound startRound = createRound(StartRound.class, startRoundClassName, "startRound"); + startRound.start(); } protected void startStockRound() { - StockRound sr = createRound (stockRoundClass); + StockRound sr = createRound(stockRoundClass, "SR_" + srNumber.value()); srNumber.add(1); sr.start(); } @@ -713,17 +698,16 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, protected void startOperatingRound(boolean operate) { log.debug("Operating round started with operate-flag=" + operate); - OperatingRound or = createRound(operatingRoundClass); + OperatingRound or = createRound(operatingRoundClass, "OR_" + absoluteORNumber.value()); if (operate) absoluteORNumber.add(1); or.start(); } - protected <T extends Round> T createRound (Class<T> roundClass) { - + // FIXME: We need an ID! + protected <T extends Round> T createRound (Class<T> roundClass, String roundClassName, String id) { T round = null; try { - Constructor<T> cons = roundClass.getConstructor(GameManager.class); - round = cons.newInstance(this); + round = Configure.create(roundClass, roundClassName, GameManager.class, this, id); } catch (Exception e) { log.error("Cannot instantiate class " + roundClass.getName(), e); @@ -732,18 +716,12 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, setRound (round); return round; } - - protected <T extends Round, U extends Round> - T createRound (Class<T> roundClass, U parentRound) { - - if (parentRound == null) { - return createRound (roundClass); - } - + + // FIXME: We need an ID! + protected <T extends Round> T createRound(Class<T> roundClass, String id) { T round = null; try { - Constructor<T> cons = roundClass.getConstructor(GameManager.class, Round.class); - round = cons.newInstance(this, parentRound); + round = Configure.create(roundClass, GameManager.class, this, id); } catch (Exception e) { log.error("Cannot instantiate class " + roundClass.getName(), e); @@ -801,20 +779,17 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, interruptedRound = getCurrentRound(); // check if other companies can be dumped - createRound (shareSellingRoundClass, interruptedRound) - .start(player, cashToRaise, cashNeedingCompany, + // FIXME: This ID will not work, as it will create duplication + createRound(shareSellingRoundClass, "ShareSellingRound").start( + interruptedRound, player, cashToRaise, cashNeedingCompany, !problemDumpOtherCompanies || forcedSellingCompanyDump); // the last parameter indicates if the dump of other companies is allowed, either this is explicit or // the action does not require that check } - /* (non-Javadoc) - * @see rails.game.GameManager#startTreasuryShareTradingRound(rails.game.OperatingRound, rails.game.PublicCompany) - */ public void startTreasuryShareTradingRound() { - interruptedRound = getCurrentRound(); - createRound (TreasuryShareRound.class, interruptedRound).start(); + createRound (TreasuryShareRound.class, "TreasuryShareRound").start(interruptedRound); } /* (non-Javadoc) @@ -1351,7 +1326,8 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, // activate gameReport for UI setGameOverReportedUI(false); - createRound(EndOfGameRound.class); + // FIXME: This will not work, as it will create duplicated IDs + createRound(EndOfGameRound.class, "EndOfGameRound"); } diff --git a/src/rails/game/GameRoot.java b/src/rails/game/GameRoot.java deleted file mode 100644 index d186dad..0000000 --- a/src/rails/game/GameRoot.java +++ /dev/null @@ -1,306 +0,0 @@ -package rails.game; - -import java.io.*; -import java.util.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import rails.algorithms.RevenueManager; -import rails.common.DisplayBuffer; -import rails.common.LocalText; -import rails.common.parser.*; -import rails.game.action.PossibleAction; -import rails.game.state.Root; -import rails.util.GameFileIO; - -public class GameRoot extends Root { - public static final String version = "1.5"; - - /** The component Manager */ - protected GameManager gameManager; - protected CompanyManager companyManager; - protected PlayerManager playerManager; - protected PhaseManager phaseManager; - protected TrainManager trainManager; - protected StockMarket stockMarket; - protected MapManager mapManager; - protected TileManager tileManager; - protected RevenueManager revenueManager; - protected Bank bank; - protected String name; - - protected List<String> directories = new ArrayList<String>(); - protected List<String> players; - - protected Map<String, String> gameOptions; - - protected static Logger log = - LoggerFactory.getLogger(GameRoot.class.getPackage().getName()); - - public GameRoot(String name, List<String> players, Map<String, String> options) { - super(); // initialize root - - this.name = name; - this.gameOptions = options; - - gameOptions.put(GameOption.NUMBER_OF_PLAYERS, - String.valueOf(players.size())); - - for (String playerName : players) { - log.debug("Player: " + playerName); - } - for (String optionName : gameOptions.keySet()) { - log.debug("Option: " + optionName + "=" - + gameOptions.get(optionName)); - } - - - this.players = players; - - log.info("========== Start of rails.game " + name + " =========="); - log.info("Rails version "+version); - ReportBuffer.add(LocalText.getText("GameIs", name)); - } - - public String start() { - - if (players.size() < playerManager.minPlayers - || players.size() > playerManager.maxPlayers) { - return name+" is not configured to be played with "+players.size()+" players\n" - + "Please enter a valid number of players, or add a <Players> entry to data/"+name+"/Game.xml"; - } - - gameManager.startGame(gameOptions); - return null; - } - - public boolean setup() { - GameFileParser gfp; - try{ - gfp = new GameFileParser(this, name, gameOptions); - } catch (Exception e) { - String message = - LocalText.getText("GameSetupFailed", GameFileParser.GAME_XML_FILE); - log.error(message, e); - System.out.println(e.getMessage()); - e.printStackTrace(); - DisplayBuffer.add(message + ":\n " + e.getMessage()); - return false; - } - - playerManager = gfp.getPlayerManager(); - companyManager = gfp.getCompanyManager(); - trainManager = gfp.getTrainManager(); - phaseManager = gfp.getPhaseManager(); - stockMarket = gfp.getStockMarket(); - mapManager = gfp.getMapManager(); - tileManager = gfp.getTileManager(); - revenueManager = gfp.getRevenueManager(); - bank = gfp.getBank(); - gameManager = gfp.getGameManager(); - - /* - * Initializations that involve relations between components can - * only be done after all XML has been processed. - */ - playerManager.setPlayers(players, bank); - gameManager.init(name, playerManager, companyManager, - phaseManager, trainManager, stockMarket, mapManager, - tileManager, revenueManager, bank); - - try { - companyManager.finishConfiguration(gameManager); - trainManager.finishConfiguration(gameManager); - phaseManager.finishConfiguration(gameManager); - tileManager.finishConfiguration(gameManager); - mapManager.finishConfiguration(gameManager); - bank.finishConfiguration(gameManager); - stockMarket.finishConfiguration(gameManager); - - if (revenueManager != null) - revenueManager.finishConfiguration(gameManager); - } catch (ConfigurationException e) { - log.error(e.getMessage()); - System.out.println(e.getMessage()); - e.printStackTrace(); - DisplayBuffer.add(e.getMessage()); - return false; - } - - return true; - } - - - public static GameRoot load(String filepath) { - - // use GameLoader object to load game - GameFileIO gameLoader = new GameFileIO(); - gameLoader.loadGameData(filepath); - try{ - gameLoader.initGame(); - gameLoader.loadActionsAndComments(); - } catch (ConfigurationException e) { - log.error("Load failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - try{ - gameLoader.replayGame(); - } catch (Exception e) { - log.error("Replay failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - - return gameLoader.getGame(); - } - - @SuppressWarnings("unchecked") - public static GameRoot load_old(String filepath) { - - GameRoot game = null; - - log.debug("Loading game from file " + filepath); - String filename = filepath.replaceAll(".*[/\\\\]", ""); - - /*--- Remember to keep GameManager.reload() in sync with this code! ---*/ - try { - ObjectInputStream ois = - new ObjectInputStream(new FileInputStream( - new File(filepath))); - - // New in 1.0.7: Rails version & save date/time. - // Allow for older saved file versions. - Object object = ois.readObject(); - if (object instanceof String) { - log.info("Reading Rails "+(String)object+" saved file "+filename); - object = ois.readObject(); - } else { - log.info("Reading Rails (pre-1.0.7) saved file "+filename); - } - if (object instanceof String) { - log.info("File was saved at "+(String)object); - object = ois.readObject(); - } - - long versionID = (Long) object; - log.debug("Saved versionID="+versionID+" (object="+object+")"); - long saveFileVersionID = GameManager.saveFileVersionID; - if (versionID != saveFileVersionID) { - throw new Exception("Save version " + versionID - + " is incompatible with current version " - + saveFileVersionID); - } - String name = (String) ois.readObject(); - log.debug("Saved game="+name); - Map<String, String> selectedGameOptions = - (Map<String, String>) ois.readObject(); - List<String> playerNames = (List<String>) ois.readObject(); - - game = new GameRoot(name, playerNames, selectedGameOptions); - - if (!game.setup()) { - throw new ConfigurationException("Error in setting up " + name); - } - - String startError = game.start(); - if (startError != null) { - DisplayBuffer.add(startError); - return null; - } - GameManager gameManager = game.getGameManager(); - - log.debug("Starting to execute loaded actions"); - - gameManager.setReloading(true); - - Object actionObject = null; - int actionIndex = 0; - - while (true) { // Single-pass loop. - try { - actionObject = ois.readObject(); - } catch (EOFException e) { - // Allow saved file at start of game (with no actions). - break; - } - if (actionObject instanceof List) { - // Old-style: one List of PossibleActions - List<PossibleAction> executedActions = - (List<PossibleAction>) actionObject; - for (PossibleAction action : executedActions) { - ++actionIndex; - try { - if (!gameManager.processOnReload(action)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted")); - break; - } - } catch (Exception e) { - log.error("Action "+actionIndex+" '"+action+"' reload exception", e); - throw new Exception ("Reload exception", e); - } - } - } else if (actionObject instanceof PossibleAction) { - // New style: separate PossibleActionsObjects, since Rails 1.3.1 - while (actionObject instanceof PossibleAction) { - ++actionIndex; - try { - if (!gameManager.processOnReload((PossibleAction)actionObject)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted")); - break; - } - } catch (Exception e) { - log.error("Action "+actionIndex+" '"+((PossibleAction)actionObject).toString() - +"' reload exception", e); - throw new Exception ("Reload exception", e); - } - try { - actionObject = ois.readObject(); - } catch (EOFException e) { - break; - } - } - } - break; - } - - // load user comments (is the last - if (actionObject instanceof SortedMap) { - ReportBuffer.setCommentItems((SortedMap<Integer, String>) actionObject); - log.debug("Found sorted map"); - } else { - try { - object = ois.readObject(); - if (object instanceof SortedMap) { - ReportBuffer.setCommentItems((SortedMap<Integer, String>) object); - } - } catch (IOException e) { - // continue without comments, if any IOException occurs - // sometimes not only the EOF Exception is raised - // but also the java.io.StreamCorruptedException: invalid type code - } - } - - ois.close(); - ois = null; - - gameManager.setReloading(false); - gameManager.finishLoading(); - return game; - - } catch (Exception e) { - log.error("Load failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - - return null; - } - - /*----- Getters -----*/ - - public GameManager getGameManager() { - return gameManager; - } - -} diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 17e3c65..b20fa42 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -7,7 +7,10 @@ import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; import rails.algorithms.RevenueBonusTemplate; import rails.common.LocalText; @@ -22,9 +25,9 @@ import rails.game.model.CashMoneyModel; import rails.game.model.PortfolioModel; import rails.game.state.BooleanState; +import rails.game.state.Configurable; import rails.game.state.Observer; import rails.game.state.Owner; -import rails.game.state.Portfolio; import rails.game.state.PortfolioSet; import rails.game.state.AbstractItem; import rails.util.*; @@ -58,7 +61,7 @@ import rails.util.*; */ // FIXME: MapHex was previous a model -public class MapHex extends AbstractItem implements Owner, ConfigurableComponent, +public class MapHex extends AbstractItem implements Owner, Configurable, StationHolder { private static final String[] ewOrNames = @@ -126,8 +129,10 @@ StationHolder { protected List<PublicCompany> destinations; /** Tokens that are not bound to a Station (City), such as Bonus tokens */ - protected final PortfolioSet<Token> offStationTokens = PortfolioSet.create(this, - "offStationTokens", Token.class); + protected final PortfolioSet<BonusToken> bonusTokens = PortfolioSet.create(this, "bonusTokens", BonusToken.class); + + protected final PortfolioSet<BaseToken> offStationTokens = PortfolioSet.create(this, + "offStationTokens", BaseToken.class); /** Storage of revenueBonus that are bound to the hex */ protected List<RevenueBonusTemplate> revenueBonuses = null; @@ -181,14 +186,15 @@ StationHolder { } public static MapHex create(MapManager parent, Tag tag) throws ConfigurationException { - // TODO: Rewrite the creation process of MapHex - MapHex hex = new MapHex(parent, null); + // name serves as id + String id = tag.getAttributeAsString("name"); + MapHex hex = new MapHex(parent, id); hex.configureFromXML(tag); return hex; } /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { Pattern namePattern = Pattern.compile("(\\D+?)(-?\\d+)"); @@ -802,51 +808,40 @@ StationHolder { } // Move the tokens - Map<Token, Portfolio<Token>> tokenDestinations = - new HashMap<Token, Portfolio<Token>>(); - + Map<BaseToken, Owner> tokenDestinations = Maps.newHashMap(); for (Stop oldCity : stops) { newCity = oldToNewCities.get(oldCity); if (newCity != null) { - oldtoken: for (Token token : oldCity.getTokens()) { - if (token instanceof BaseToken) { - // Check if the new city already has such a token - PublicCompany company = - ((BaseToken) token).getParent(); - for (Token token2 : newCity.getTokens()) { - if (token2 instanceof BaseToken - && company == ((BaseToken) token2).getOwner()) { - // No duplicate tokens in one city, so move to free tokens - tokenDestinations.put(token, company.getBaseTokensModel().getFreeTokens()); - log.debug("Duplicate token " - + token.getUniqueId() - + " moved from " - + oldCity.getId() + " to " - + company.getId()); - ReportBuffer.add(LocalText.getText( - "DuplicateTokenRemoved", - company.getId(), - getId() )); - continue oldtoken; - } + oldtoken: for (BaseToken token : oldCity.getBaseTokens()) { + // Check if the new city already has such a token + PublicCompany company = token.getParent(); + for (BaseToken token2 : newCity.getBaseTokens()) { + if (company == token2.getOwner()) { + // No duplicate tokens in one city, so move to free tokens + tokenDestinations.put(token, company); + log.debug("Duplicate token " + + token.getUniqueId() + + " moved from " + + oldCity.getId() + " to " + + company.getId()); + ReportBuffer.add(LocalText.getText( + "DuplicateTokenRemoved", + company.getId(), + getId() )); + continue oldtoken; } } - tokenDestinations.put(token, newCity.getTokens()); + tokenDestinations.put(token, newCity); log.debug("Token " + token.getUniqueId() + " moved from " + oldCity.getId() + " to " + newCity.getId()); } - if (!tokenDestinations.isEmpty()) { - for (Token token : tokenDestinations.keySet()) { - tokenDestinations.get(token).moveInto(token); - } } - } else { - log.debug("No new city!?"); - } - } - + // TODO: Move that after the for-loop, check if this still works + for (BaseToken token : tokenDestinations.keySet()) { + token.moveTo(tokenDestinations.get(token)); + } } // TODO: Check as the code below was not reachable @@ -920,7 +915,7 @@ StationHolder { ... [truncated message content] |