|
From: Stefan F. <ste...@us...> - 2012-05-26 14:11:45
|
rails/algorithms/NetworkCompanyGraph.java | 2
rails/algorithms/NetworkGraphBuilder.java | 9
rails/algorithms/RevenueAdapter.java | 4
rails/algorithms/RevenueManager.java | 31
rails/common/GuiHints.java | 31
rails/common/ResourceLoader.java | 4
rails/game/AbstractRound.java | 544 +++++++++++++++
rails/game/Bank.java | 70 -
rails/game/BankPortfolio.java | 38 +
rails/game/BaseToken.java | 43 -
rails/game/Bonus.java | 1
rails/game/BonusToken.java | 53 -
rails/game/Certificate.java | 4
rails/game/Company.java | 53 -
rails/game/CompanyManager.java | 2
rails/game/CompanyManagerI.java | 2
rails/game/CompanyType.java | 53 -
rails/game/CompanyTypeI.java | 52 -
rails/game/EndOfGameRound.java | 2
rails/game/Game.java | 3
rails/game/GameManager.java | 125 +--
rails/game/MapHex.java | 179 ++--
rails/game/MapManager.java | 3
rails/game/OperatingRound.java | 192 ++---
rails/game/Phase.java | 2
rails/game/PhaseManager.java | 11
rails/game/Player.java | 79 +-
rails/game/PlayerManager.java | 9
rails/game/PrivateCompany.java | 143 +--
rails/game/PublicCertificate.java | 22
rails/game/PublicCompany.java | 496 ++++++-------
rails/game/ReportBuffer.java | 6
rails/game/Round.java | 537 --------------
rails/game/RoundI.java | 34
rails/game/ShareSellingRound.java | 47 -
rails/game/StartItem.java | 109 +--
rails/game/StartPacket.java | 6
rails/game/StartRound.java | 29
rails/game/StartRoundI.java | 28
rails/game/StartRound_1830.java | 8
rails/game/StartRound_1835.java | 30
rails/game/Station.java | 6
rails/game/StockMarket.java | 16
rails/game/StockRound.java | 109 +--
rails/game/StockSpace.java | 63 -
rails/game/Stop.java | 106 +-
rails/game/SwitchableUIRound.java | 2
rails/game/Tile.java | 56 -
rails/game/TileI.java | 90 --
rails/game/TileManager.java | 2
rails/game/Token.java | 49 -
rails/game/Train.java | 57 -
rails/game/TrainCertificateType.java | 36
rails/game/TrainManager.java | 4
rails/game/TreasuryShareRound.java | 36
rails/game/action/BuyBonusToken.java | 4
rails/game/action/BuyCertificate.java | 14
rails/game/action/BuyTrain.java | 37 -
rails/game/action/DiscardTrain.java | 4
rails/game/action/LayTile.java | 32
rails/game/action/PossibleORAction.java | 10
rails/game/action/UseSpecialProperty.java | 12
rails/game/correct/CashCorrectionManager.java | 6
rails/game/correct/CorrectionManager.java | 17
rails/game/correct/MapCorrectionAction.java | 22
rails/game/correct/MapCorrectionManager.java | 6
rails/game/model/BaseTokensModel.java | 71 +
rails/game/model/BonusModel.java | 7
rails/game/model/CalculatedMoneyModel.java | 10
rails/game/model/CashMoneyModel.java | 5
rails/game/model/CashOwner.java | 8
rails/game/model/CertificateCountModel.java | 31
rails/game/model/CertificatesModel.java | 12
rails/game/model/MoneyModel.java | 7
rails/game/model/PortfolioModel.java | 119 +--
rails/game/model/PortfolioOwner.java | 10
rails/game/model/PresidentModel.java | 14
rails/game/model/PriceModel.java | 19
rails/game/model/PrivatesModel.java | 9
rails/game/model/TrainsModel.java | 11
rails/game/round/RoundContext.java | 10
rails/game/special/ExchangeForShare.java | 5
rails/game/special/SellBonusToken.java | 25
rails/game/special/SpecialProperty.java | 54 -
rails/game/special/SpecialPropertyI.java | 70 -
rails/game/special/SpecialRight.java | 6
rails/game/special/SpecialTileLay.java | 8
rails/game/specific/_1825/PublicCompany_1825.java | 16
rails/game/specific/_1825/StartRound_1825.java | 2
rails/game/specific/_1825/StockRound_1825.java | 2
rails/game/specific/_1835/GameManager_1835.java | 15
rails/game/specific/_1835/OperatingRound_1835.java | 29
rails/game/specific/_1835/PrussianFormationRound.java | 32
rails/game/specific/_1835/StockRound_1835.java | 12
rails/game/specific/_1856/CGRFormationRound.java | 82 +-
rails/game/specific/_1856/GameManager_1856.java | 13
rails/game/specific/_1856/OperatingRound_1856.java | 28
rails/game/specific/_1856/PublicCompany_1856.java | 24
rails/game/specific/_1856/PublicCompany_CGR.java | 28
rails/game/specific/_1856/ShareSellingRound_1856.java | 26
rails/game/specific/_1856/StockRound_1856.java | 43 -
rails/game/specific/_1880/StartRound_1880.java | 43 -
rails/game/specific/_1889/OperatingRound_1889.java | 52 -
rails/game/specific/_18AL/AssignNamedTrains.java | 6
rails/game/specific/_18AL/NameTrains.java | 3
rails/game/specific/_18AL/NameableTrain.java | 12
rails/game/specific/_18AL/NamedTrainRevenueModifier.java | 2
rails/game/specific/_18AL/NamedTrainToken.java | 7
rails/game/specific/_18AL/OperatingRound_18AL.java | 2
rails/game/specific/_18EU/GameManager_18EU.java | 32
rails/game/specific/_18EU/OperatingRound_18EU.java | 56 -
rails/game/specific/_18EU/StartRound_18EU.java | 46 -
rails/game/specific/_18EU/StockRound_18EU.java | 94 +-
rails/game/specific/_18GA/OperatingRound_18GA.java | 4
rails/game/specific/_18TN/OperatingRound_18TN.java | 14
rails/game/specific/_18TN/PublicCompany_18TN.java | 15
rails/game/state/AbstractItem.java | 13
rails/game/state/ArrayListMultimapState.java | 6
rails/game/state/ArrayListState.java | 6
rails/game/state/BooleanState.java | 6
rails/game/state/ChangeStack.java | 2
rails/game/state/Context.java | 4
rails/game/state/GenericState.java | 8
rails/game/state/HashMapState.java | 6
rails/game/state/HashMultimapState.java | 5
rails/game/state/HashSetState.java | 6
rails/game/state/IntegerChange.java | 2
rails/game/state/IntegerState.java | 10
rails/game/state/Item.java | 2
rails/game/state/Ownable.java | 20
rails/game/state/OwnableItem.java | 22
rails/game/state/Owner.java | 13
rails/game/state/Portfolio.java | 36
rails/game/state/PortfolioChange.java | 2
rails/game/state/PortfolioHolder.java | 8
rails/game/state/PortfolioList.java | 10
rails/game/state/PortfolioManager.java | 12
rails/game/state/PortfolioMap.java | 10
rails/game/state/Root.java | 4
rails/game/state/State.java | 5
rails/game/state/StateManager.java | 8
rails/game/state/StringState.java | 6
rails/game/state/TileMove.java | 8
rails/game/state/Wallet.java | 6
rails/game/state/WalletManager.java | 6
rails/ui/swing/GameStatus.java | 21
rails/ui/swing/GameUIManager.java | 10
rails/ui/swing/GridPanel.java | 30
rails/ui/swing/ORPanel.java | 10
rails/ui/swing/ORUIManager.java | 36
rails/ui/swing/RemainingTilesWindow.java | 9
rails/ui/swing/StartRoundWindow.java | 4
rails/ui/swing/StatusWindow.java | 4
rails/ui/swing/UpgradesPanel.java | 48 -
rails/ui/swing/gamespecific/_1835/StatusWindow_1835.java | 2
rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java | 2
rails/ui/swing/hexmap/GUIHex.java | 51 -
rails/ui/swing/hexmap/GUITile.java | 8
rails/ui/swing/hexmap/HexMap.java | 5
rails/ui/swing/hexmap/HexMapImage.java | 16
rails/util/Util.java | 28
161 files changed, 2799 insertions(+), 2880 deletions(-)
New commits:
commit f080601bedb11b14264515a41730fd62f30e0025
Author: Stefan Frey <ste...@we...>
Date: Sun May 20 15:18:54 2012 +0200
further changes to the new defined elements
diff --git a/rails/algorithms/NetworkGraphBuilder.java b/rails/algorithms/NetworkGraphBuilder.java
index 0204793..a1a5d7f 100644
--- a/rails/algorithms/NetworkGraphBuilder.java
+++ b/rails/algorithms/NetworkGraphBuilder.java
@@ -32,7 +32,7 @@ import rails.game.MapHex;
import rails.game.MapManager;
import rails.game.PublicCompany;
import rails.game.Station;
-import rails.game.TileI;
+import rails.game.Tile;
import rails.game.Token;
import rails.game.Track;
import rails.game.state.Owner;
@@ -64,7 +64,7 @@ public final class NetworkGraphBuilder implements Iterable<NetworkVertex> {
for (MapHex hex:mapManager.getHexesAsList()) {
// get Tile
- TileI tile = hex.getCurrentTile();
+ Tile tile = hex.getCurrentTile();
// then get stations
List<Station> stations = tile.getStations();
@@ -89,7 +89,7 @@ public final class NetworkGraphBuilder implements Iterable<NetworkVertex> {
// loop over all maps and add tracks
for (MapHex hex:mapManager.getHexesAsList()) {
// get Tile
- TileI tile = hex.getCurrentTile();
+ Tile tile = hex.getCurrentTile();
// get Tracks
List<Track> tracks = tile.getTracks();
@@ -178,6 +178,7 @@ public final class NetworkGraphBuilder implements Iterable<NetworkVertex> {
public NetworkVertex getVertex(Token token) {
if (!(token instanceof BaseToken)) return null;
Owner owner = token.getOwner();
+ // TODO: Check if this still works
if (!(owner instanceof Stop)) return null;
Stop city = (Stop)owner;
MapHex hex = city.getHolder();
diff --git a/rails/algorithms/RevenueManager.java b/rails/algorithms/RevenueManager.java
index bfba854..a6e0cfc 100644
--- a/rails/algorithms/RevenueManager.java
+++ b/rails/algorithms/RevenueManager.java
@@ -14,6 +14,7 @@ import rails.common.parser.Tag;
import rails.game.GameManager;
import rails.game.state.AbstractItem;
import rails.game.state.ArrayListState;
+import rails.game.state.Item;
/**
* Coordinates and stores all elements related to revenue calulcation,
@@ -30,25 +31,17 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo
protected static Logger log =
Logger.getLogger(RevenueManager.class.getPackage().getName());
- private final HashSet<ConfigurableComponentI> configurableModifiers;
+ private final HashSet<ConfigurableComponentI> configurableModifiers = new HashSet<ConfigurableComponentI>();
- private final ArrayListState<NetworkGraphModifier> graphModifiers;
- private final ArrayListState<RevenueStaticModifier> staticModifiers;
- private final ArrayListState<RevenueDynamicModifier> dynamicModifiers;
+ private final ArrayListState<NetworkGraphModifier> graphModifiers = ArrayListState.create();
+ private final ArrayListState<RevenueStaticModifier> staticModifiers = ArrayListState.create();
+ private final ArrayListState<RevenueDynamicModifier> dynamicModifiers = ArrayListState.create();
- private final ArrayList<RevenueStaticModifier> activeStaticModifiers;
- private final ArrayList<RevenueDynamicModifier> activeDynamicModifiers;
+ private final ArrayList<RevenueStaticModifier> activeStaticModifiers = new ArrayList<RevenueStaticModifier>();
+ private final ArrayList<RevenueDynamicModifier> activeDynamicModifiers = new ArrayList<RevenueDynamicModifier>();
private RevenueDynamicModifier activeCalculator;
- public RevenueManager() {
- graphModifiers = ArrayListState.create(this, "NetworkGraphModifiers");
- staticModifiers = ArrayListState.create(this, "RevenueStaticModifiers");
- dynamicModifiers = ArrayListState.create(this, "RevenueDynamicModifiers");
- configurableModifiers = new HashSet<ConfigurableComponentI>();
-
- activeStaticModifiers = new ArrayList<RevenueStaticModifier>();
- activeDynamicModifiers = new ArrayList<RevenueDynamicModifier>();
- }
+ public RevenueManager() {}
public void configureFromXML(Tag tag) throws ConfigurationException {
@@ -100,6 +93,14 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo
}
+ @Override
+ public void init(Item parent, String id) {
+ super.init(parent, id);
+ graphModifiers.init(this, "NetworkGraphModifiers");
+ staticModifiers.init(this, "RevenueStaticModifiers");
+ dynamicModifiers.init(this, "RevenueDynamicModifiers");
+ }
+
public void finishConfiguration(GameManager parent)
throws ConfigurationException {
for (ConfigurableComponentI modifier:configurableModifiers) {
diff --git a/rails/common/GuiHints.java b/rails/common/GuiHints.java
index b386bc8..a40d4ac 100644
--- a/rails/common/GuiHints.java
+++ b/rails/common/GuiHints.java
@@ -4,9 +4,10 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import rails.game.RoundI;
+import rails.game.Round;
import rails.game.state.AbstractItem;
import rails.game.state.GenericState;
+import rails.game.state.Item;
/**
* This class contains hints from the server (game engine) to the client (GUI)
@@ -21,25 +22,27 @@ public class GuiHints extends AbstractItem implements Serializable{
public static final long serialVersionUID = 1L;
/** What round type is currently active in the engine? */
- private GenericState<Class<? extends RoundI>> currentRoundType = null;
+ private GenericState<Class<? extends Round>> currentRoundType = GenericState.create();
/** Which windows should be visible? */
private List<VisibilityHint> visibilityHints;
/** Which window type is active and should be on top? */
- private GenericState<GuiDef.Panel> activePanel = null;
+ private GenericState<GuiDef.Panel> activePanel = GenericState.create();
- public Class<? extends RoundI> getCurrentRoundType() {
+ @Override
+ public void init(Item parent, String id){
+ super.init(parent, id);
+ currentRoundType.init(this, "CurrentRoundType");
+ activePanel.init(this, "ActivePanel");
+ }
+
+ public Class<? extends Round> getCurrentRoundType() {
return currentRoundType.get();
}
- public void setCurrentRoundType(Class<? extends RoundI> currentRoundType) {
- if (this.currentRoundType == null) {
- this.currentRoundType = GenericState.<Class<? extends RoundI>>create
- (this, "CurrentRoundType", currentRoundType);
- } else {
- this.currentRoundType.set(currentRoundType);
- }
+ public void setCurrentRoundType(Class<? extends Round> currentRoundType) {
+ this.currentRoundType.set(currentRoundType);
}
public List<VisibilityHint> getVisibilityHints() {
@@ -66,11 +69,7 @@ public class GuiHints extends AbstractItem implements Serializable{
}
public void setActivePanel(GuiDef.Panel activePanel) {
- if (this.activePanel == null) {
- this.activePanel = GenericState.create(this, "ActivePanel", activePanel);
- } else {
- this.activePanel.set(activePanel);
- }
+ this.activePanel.set(activePanel);
}
public class VisibilityHint {
diff --git a/rails/common/ResourceLoader.java b/rails/common/ResourceLoader.java
index b064b9a..c31eebb 100644
--- a/rails/common/ResourceLoader.java
+++ b/rails/common/ResourceLoader.java
@@ -41,10 +41,6 @@ public final class ResourceLoader {
super(parent);
}
- RailsClassLoader() {
- super();
- }
-
@Override
public Class<?> findClass(String className)
throws ClassNotFoundException {
diff --git a/rails/game/AbstractRound.java b/rails/game/AbstractRound.java
new file mode 100644
index 0000000..ebdccfc
--- /dev/null
+++ b/rails/game/AbstractRound.java
@@ -0,0 +1,544 @@
+package rails.game;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.log4j.Logger;
+
+import rails.common.*;
+import rails.game.action.*;
+import rails.game.model.CashOwner;
+import rails.game.model.MoneyModel;
+import rails.game.model.PortfolioModel;
+import rails.game.special.SpecialProperty;
+import rails.game.state.AbstractItem;
+import rails.game.state.ArrayListState;
+import rails.game.state.BooleanState;
+import rails.game.state.ChangeStack;
+import rails.game.state.Item;
+import rails.game.state.Portfolio;
+
+/**
+ * @author Erik Vos
+ */
+public abstract class AbstractRound extends AbstractItem implements Round {
+
+ protected PossibleActions possibleActions = PossibleActions.getInstance();
+ protected GuiHints guiHints = null;
+
+ protected static Logger log =
+ Logger.getLogger(AbstractRound.class.getPackage().getName());
+
+ protected GameManager gameManager = null;
+ protected CompanyManagerI companyManager = null;
+ protected PlayerManager playerManager = null;
+ protected Bank bank = null;
+ protected PortfolioModel ipo = null;
+ protected PortfolioModel pool = null;
+ protected PortfolioModel unavailable = null;
+ protected PortfolioModel scrapHeap = null;
+ protected StockMarket stockMarket = null;
+ protected MapManager mapManager = null;
+
+ protected final BooleanState wasInterrupted = BooleanState.create(false);
+
+ protected ChangeStack changeStack = null;
+
+
+ /** Autopasses */
+ // TODO: Should this be moved to the StockRound classes?
+ // Only initialized if used
+ protected ArrayListState<Player> autopasses = null;
+ protected ArrayListState<Player> canRequestTurn = null;
+ protected ArrayListState<Player> hasRequestedTurn = null;
+
+ /**
+ * Constructor with the GameManager, will call setGameManager with the parameter to initialize
+ *
+ * @param aGameManager The GameManager Object needed to initialize the Round Class
+ *
+ */
+ public AbstractRound (GameManager aGameManager) {
+
+ this.gameManager = aGameManager;
+
+ if (gameManager == null) {
+ companyManager = null;
+ } else {
+ companyManager = gameManager.getCompanyManager();
+ playerManager = gameManager.getPlayerManager();
+ bank = gameManager.getBank();
+ ipo = bank.getIpo();
+ pool = bank.getPool();
+ unavailable = bank.getUnavailable();
+ scrapHeap = bank.getScrapHeap();
+ stockMarket = gameManager.getStockMarket();
+ mapManager = gameManager.getMapManager();
+
+ changeStack = gameManager.getChangeStack();
+ }
+
+ guiHints = gameManager.getUIHints();
+ guiHints.setCurrentRoundType(getClass());
+ }
+
+ @Override
+ public void init(Item parent, String id) {
+ super.init(parent, id);
+ wasInterrupted.init(this, "RoundInterrupted");
+ }
+
+ public Player getCurrentPlayer() {
+
+ if (gameManager != null) return gameManager.getCurrentPlayer();
+ return null;
+ }
+
+ /**
+ * @return Returns the currentPlayerIndex.
+ */
+ public int getCurrentPlayerIndex() {
+ return getCurrentPlayer().getIndex();
+ }
+
+ public void setCurrentPlayerIndex(int newIndex) {
+ gameManager.setCurrentPlayerIndex(newIndex);
+ }
+
+ public void setCurrentPlayer(Player player) {
+ gameManager.setCurrentPlayer(player);
+ }
+
+ protected List<Player> getPlayers() {
+ return gameManager.getPlayers();
+ }
+
+ protected int getNumberOfPlayers() {
+ return gameManager.getNumberOfPlayers();
+ }
+
+ protected int getNumberOfActivePlayers () {
+ int number = 0;
+ for (Player player : getPlayers()) {
+ if (!player.isBankrupt()) number++;
+ }
+ return number;
+ }
+
+ public Phase getCurrentPhase() {
+ return gameManager.getCurrentPhase();
+ }
+
+ /** Allows round instances to tell the UI what type of window to raise.
+ * Normally the type corresponds to the round type (e.g. OperatingRound
+ * needs ORWindow), but sometimes deviations occur (such as the
+ * CGRFormationRound, which isn't a StockRound type but needs StatusWindow).
+ * @return
+ */
+ public Class<? extends Round> getRoundTypeForUI () {
+ return this.getClass();
+ }
+
+ public String getGameOption (String name) {
+ return gameManager.getGameOption(name);
+ }
+
+ // TODO: Remove as this is abstract class?
+ public String getHelp() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ // TODO: Remove as this is abstract class?
+ public List<SpecialProperty> getSpecialProperties() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean process(PossibleAction action) {
+ return true;
+ }
+
+ protected boolean exchangeTokens(ExchangeTokens action, boolean linkedMoveSet) {
+
+ String errMsg = null;
+
+ List<ExchangeableToken> tokens = action.getTokensToExchange();
+ int min = action.getMinNumberToExchange();
+ int max = action.getMaxNumberToExchange();
+ int exchanged = 0;
+
+ checks: {
+
+ for (ExchangeableToken token : tokens) {
+ if (token.isSelected()) exchanged++;
+ }
+ if (exchanged < min || exchanged > max) {
+ errMsg = LocalText.getText("WrongNumberOfTokensExchanged",
+ action.getCompany(),
+ min, max, exchanged);
+ break checks;
+ }
+ }
+
+ if (errMsg != null) {
+ DisplayBuffer.add(LocalText.getText("CannotExchangeTokens",
+ action.getCompany(),
+ action.toString(),
+ errMsg));
+
+ return false;
+ }
+
+ // TODO: changeStack.start(true);
+ // FIMXE: if (linkedMoveSet) changeStack.linkToPreviousMoveSet();
+
+ if (exchanged > 0) {
+ MapHex hex;
+ Stop city;
+ String cityName, hexName;
+ int cityNumber;
+ String[] ct;
+ PublicCompany comp = action.getCompany();
+
+ ReportBuffer.add("");
+
+ for (ExchangeableToken token : tokens) {
+ cityName = token.getCityName();
+ ct = cityName.split("/");
+ hexName = ct[0];
+ try {
+ cityNumber = Integer.parseInt(ct[1]);
+ } catch (NumberFormatException e) {
+ cityNumber = 1;
+ }
+ hex = mapManager.getHex(hexName);
+ city = hex.getStop(cityNumber);
+
+ if (token.isSelected()) {
+
+ // For now we'll assume that the old token(s) have already been removed.
+ // This is true in the 1856 CGR formation.
+ if (hex.layBaseToken(comp, city.getNumber())) {
+ /* TODO: the false return value must be impossible. */
+ ReportBuffer.add(LocalText.getText("ExchangesBaseToken",
+ comp.getId(),
+ token.getOldCompanyName(),
+ city.getId()));
+ comp.layBaseToken(hex, 0);
+ }
+ } else {
+ ReportBuffer.add(LocalText.getText("NoBaseTokenExchange",
+ comp.getId(),
+ token.getOldCompanyName(),
+ city.getId()));
+ }
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Default version, does nothing. Subclasses should override this method
+ * with a real version.
+ */
+ // TODO: Remove as this is abstract class?
+ public boolean setPossibleActions() {
+ return false;
+ }
+
+ /** Set the operating companies in their current acting order */
+ public List<PublicCompany> setOperatingCompanies() {
+ return setOperatingCompanies (null, null);
+ }
+
+ public List<PublicCompany> setOperatingCompanies(List<PublicCompany> oldOperatingCompanies,
+ PublicCompany lastOperatingCompany) {
+
+ Map<Integer, PublicCompany> operatingCompanies =
+ new TreeMap<Integer, PublicCompany>();
+ List<PublicCompany> newOperatingCompanies;
+ StockSpace space;
+ int key;
+ int minorNo = 0;
+ boolean reorder = gameManager.isDynamicOperatingOrder()
+ && oldOperatingCompanies != null && lastOperatingCompany != null;
+
+ int lastOperatingCompanyndex;
+ if (reorder) {
+ newOperatingCompanies = oldOperatingCompanies;
+ lastOperatingCompanyndex = oldOperatingCompanies.indexOf(lastOperatingCompany);
+ } else {
+ newOperatingCompanies = companyManager.getAllPublicCompanies();
+ lastOperatingCompanyndex = -1;
+ }
+
+ for (PublicCompany company : newOperatingCompanies) {
+ if (!reorder && !canCompanyOperateThisRound(company)) continue;
+
+ if (reorder
+ && oldOperatingCompanies.indexOf(company) <= lastOperatingCompanyndex) {
+ // Companies that have operated this round get lowest keys
+ key = oldOperatingCompanies.indexOf(company);
+ } else if (company.hasStockPrice()) {
+ // Key must put companies in reverse operating order, because sort
+ // is ascending.
+ space = company.getCurrentSpace();
+ key = 1000000 * (999 - space.getPrice())
+ + 10000 * (99 - space.getColumn())
+ + 100 * (space.getRow()+1)
+ + space.getStackPosition(company);
+ } else {
+ key = 50 + ++minorNo;
+ }
+ operatingCompanies.put(new Integer(key), company);
+ }
+
+ return new ArrayList<PublicCompany>(operatingCompanies.values());
+ }
+
+ /** Can a public company operate? (Default version) */
+ protected boolean canCompanyOperateThisRound (PublicCompany company) {
+ return company.hasFloated() && !company.isClosed();
+ }
+
+ /**
+ * Check if a company must be floated, and if so, do it. <p>This method is
+ * included here because it is used in various types of Round.
+ *
+ * @param company
+ */
+ protected void checkFlotation(PublicCompany company) {
+
+ if (!company.hasStarted() || company.hasFloated()) return;
+
+ if (getSoldPercentage(company) >= company.getFloatPercentage()) {
+ // Company floats
+ floatCompany(company);
+ }
+ }
+
+ /** Determine sold percentage for floating purposes */
+ protected int getSoldPercentage (PublicCompany company) {
+
+ int soldPercentage = 0;
+ for (PublicCertificate cert : company.getCertificates()) {
+ if (certCountsAsSold(cert)) {
+ soldPercentage += cert.getShare();
+ }
+ }
+ return soldPercentage;
+ }
+
+ /** Can be subclassed for games with special rules */
+ protected boolean certCountsAsSold (PublicCertificate cert) {
+ Portfolio<PublicCertificate> portfolio = cert.getPortfolio();
+ return portfolio.getOwner() instanceof Player || portfolio.getParent() == pool;
+ }
+
+ /**
+ * Float a company, including a default implementation of moving cash and
+ * shares as a result of flotation. <p>Full capitalisation is implemented
+ * as in 1830. Partial capitalisation is implemented as in 1851. Other ways
+ * to process the consequences of company flotation must be handled in
+ * game-specific subclasses.
+ */
+ protected void floatCompany(PublicCompany company) {
+
+ // Move cash and shares where required
+ int soldPercentage = getSoldPercentage(company);
+ int cash = 0;
+ int capitalisationMode = company.getCapitalisation();
+ if (company.hasStockPrice()) {
+ int capFactor = 0;
+ int shareUnit = company.getShareUnit();
+ if (capitalisationMode == PublicCompany.CAPITALISE_FULL) {
+ // Full capitalisation as in 1830
+ capFactor = 100 / shareUnit;
+ } else if (capitalisationMode == PublicCompany.CAPITALISE_INCREMENTAL) {
+ // Incremental capitalisation as in 1851
+ capFactor = soldPercentage / shareUnit;
+ } else if (capitalisationMode == PublicCompany.CAPITALISE_WHEN_BOUGHT) {
+ // Cash goes directly to treasury at each buy (as in 1856 before phase 6)
+ capFactor = 0;
+ }
+ int price = company.getIPOPrice();
+ cash = capFactor * price;
+ } else {
+ cash = company.getFixedPrice();
+ }
+
+ // Substract initial token cost (e.g. 1851, 18EU)
+ cash -= company.getBaseTokensBuyCost();
+
+ company.setFloated(); // After calculating cash (for 1851: price goes
+ // up)
+
+ if (cash > 0) {
+ MoneyModel.cashMove(bank, company, cash);
+ ReportBuffer.add(LocalText.getText("FloatsWithCash",
+ company.getId(),
+ Bank.format(cash) ));
+ } else {
+ ReportBuffer.add(LocalText.getText("Floats",
+ company.getId()));
+ }
+
+ if (capitalisationMode == PublicCompany.CAPITALISE_INCREMENTAL
+ && company.canHoldOwnShares()) {
+ // move all shares from ipo to the company portfolio
+ // FIXME: Is this correct?
+ // Should a company not have a Portfolio<Share> where it stores the certificates that it owns
+ Portfolio.moveAll(ipo.getShareModel(company).getPortfolio(), company.getPortfolioModel().getShareModel(company).getPortfolio());
+ }
+ }
+
+ protected void finishRound() {
+ // Report financials
+ ReportBuffer.add("");
+ for (PublicCompany c : companyManager.getAllPublicCompanies()) {
+ if (c.hasFloated() && !c.isClosed()) {
+ ReportBuffer.add(LocalText.getText("Has", c.getId(),
+ Bank.format(c.getCash())));
+ }
+ }
+ for (Player p : playerManager.getPlayers()) {
+ ReportBuffer.add(LocalText.getText("Has", p.getId(),
+ Bank.format(p.getCashValue())));
+ }
+ // Inform GameManager
+ gameManager.nextRound(this);
+ }
+
+ /** Generic stub to resume an interrupted round.
+ * Only valid if implemented in a subclass.
+ *
+ */
+ public void resume() {
+ log.error("Calling Round.resume() is invalid");
+ }
+
+ public boolean wasInterrupted () {
+ return wasInterrupted.booleanValue();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName().replaceAll(".*\\.", "");
+ }
+
+ protected void transferCertificate(Certificate cert, PortfolioModel newHolder) {
+ if (cert instanceof PublicCertificate) {
+ newHolder.addPublicCertificate((PublicCertificate)cert);
+ } else if (cert instanceof PrivateCompany) {
+ newHolder.addPrivateCompany((PrivateCompany)cert);
+ }
+ }
+
+ // Note: all transferred shares must come from the same old shareholder.
+ // TODO: This is not very a very nice implementation
+ protected void transferCertificates(List<? extends Certificate> certs,
+ PortfolioModel newHolder) {
+
+ for (Certificate cert : certs) {
+ if (cert != null) {
+ transferCertificate(cert, newHolder);
+ }
+ }
+ }
+
+ protected void pay (CashOwner from, CashOwner to, int amount) {
+ if (to != null && amount != 0) {
+ MoneyModel.cashMove (from, to, amount);
+ }
+ }
+
+ public GameManager getGameManager() {
+ return gameManager;
+ }
+
+ protected Object getGameParameter (GameDef.Parm key) {
+ return gameManager.getGameParameter(key);
+ }
+
+ public int getGameParameterAsInt (GameDef.Parm key) {
+ if (key.defaultValue() instanceof Integer) {
+ return (Integer) gameManager.getGameParameter(key);
+ } else {
+ return -1;
+ }
+ }
+
+ public boolean getGameParameterAsBoolean (GameDef.Parm key) {
+ if (key.defaultValue() instanceof Boolean) {
+ return (Boolean) gameManager.getGameParameter(key);
+ } else {
+ return false;
+ }
+ }
+
+ public String getRoundName() {
+ return this.getClass().getSimpleName();
+ }
+
+ public boolean requestTurn (Player player) {
+ if (canRequestTurn (player)) {
+ if (hasRequestedTurn == null) {
+ hasRequestedTurn = ArrayListState.create();
+ hasRequestedTurn.init(this, "hasRequestedTurn");
+ }
+ if (!hasRequestedTurn.contains(player)) hasRequestedTurn.add(player);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean canRequestTurn (Player player) {
+ return canRequestTurn != null && canRequestTurn.contains(player);
+ }
+
+ public void setCanRequestTurn (Player player, boolean value) {
+ if (canRequestTurn == null) {
+ canRequestTurn = ArrayListState.create();
+ canRequestTurn.init(this, "canRequestTurn");
+ }
+ if (value && !canRequestTurn.contains(player)) {
+ canRequestTurn.add(player);
+ } else if (!value && canRequestTurn.contains(player)) {
+ canRequestTurn.remove(player);
+ }
+ }
+
+ public void setAutopass (Player player, boolean value) {
+ if (autopasses == null) {
+ autopasses = ArrayListState.create();
+ autopasses.init(this, "autopasses");
+ }
+ if (value && !autopasses.contains(player)) {
+ autopasses.add(player);
+ } else if (!value && autopasses.contains(player)) {
+ autopasses.remove(player);
+ }
+ }
+
+ public boolean hasAutopassed (Player player) {
+ return autopasses != null && autopasses.contains(player);
+ }
+
+ public List<Player> getAutopasses() {
+ return autopasses.view();
+ }
+
+ /** A stub for processing actions triggered by a phase change.
+ * Must be overridden by subclasses that need to process such actions.
+ * @param name (required) The name of the action to be executed
+ * @param value (optional) The value of the action to be executed, if applicable
+ */
+ public void processPhaseAction (String name, String value) {
+
+ }
+}
diff --git a/rails/game/Bank.java b/rails/game/Bank.java
index 5bebc7c..d5bf827 100644
--- a/rails/game/Bank.java
+++ b/rails/game/Bank.java
@@ -33,15 +33,15 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone
/** The Bank's amount of cash */
private final CashMoneyModel cash = CashMoneyModel.create();
-
+
/** The IPO */
- private final PortfolioModel ipo = PortfolioModel.create();
+ private final BankPortfolio ipo = BankPortfolio.create();
/** The Bank Pool */
- private final PortfolioModel pool = PortfolioModel.create();
+ private final BankPortfolio pool = BankPortfolio.create();
/** Collection of items that will (may) become available in the future */
- private final PortfolioModel unavailable = PortfolioModel.create();
+ private final BankPortfolio unavailable = BankPortfolio.create();
/** Collection of items that have been discarded (but are kept to allow Undo) */
- private final PortfolioModel scrapHeap = PortfolioModel.create();
+ private final BankPortfolio scrapHeap = BankPortfolio.create();
/** Is the bank broken */
private final BooleanState broken = BooleanState.create();
@@ -117,7 +117,7 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone
List<PrivateCompany> privates =
gameManager.getCompanyManager().getAllPrivateCompanies();
for (PrivateCompany priv : privates) {
- ipo.addPrivate(priv, -1);
+ ipo.getPortfolioModel().addPrivateCompany(priv);
}
// Add public companies
@@ -126,9 +126,10 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone
for (PublicCompany comp : companies) {
for (PublicCertificate cert : comp.getCertificates()) {
if (cert.isInitiallyAvailable()) {
- ipo.moveInto(cert);
+ // TODO: Make this shorter
+ ipo.getPortfolioModel().getShareModel(comp).getPortfolio().moveInto(cert);
} else {
- unavailable.moveInto(cert);
+ unavailable.getPortfolioModel().getShareModel(comp).getPortfolio().moveInto(cert);
}
}
}
@@ -138,11 +139,11 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone
* @return IPO Portfolio
*/
public PortfolioModel getIpo() {
- return ipo;
+ return ipo.getPortfolioModel();
}
public PortfolioModel getScrapHeap() {
- return scrapHeap;
+ return scrapHeap.getPortfolioModel();
}
/* FIXME: Add broken check somewhere
@@ -159,14 +160,14 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone
* @return Portfolio of stock in Bank Pool
*/
public PortfolioModel getPool() {
- return pool;
+ return pool.getPortfolioModel();
}
/**
* @return Portfolio of unavailable shares
*/
public PortfolioModel getUnavailable() {
- return unavailable;
+ return unavailable.getPortfolioModel();
}
public String getId() {
@@ -174,8 +175,8 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone
}
// CashOwner interface
- public CashMoneyModel getCash() {
- return cash;
+ public int getCash() {
+ return cash.value();
}
public static String format(int amount) {
@@ -194,5 +195,10 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone
}
return result.toString();
}
+
+ public CashMoneyModel getCashModel() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/rails/game/BankPortfolio.java b/rails/game/BankPortfolio.java
new file mode 100644
index 0000000..ce62f23
--- /dev/null
+++ b/rails/game/BankPortfolio.java
@@ -0,0 +1,38 @@
+package rails.game;
+
+import rails.game.model.PortfolioModel;
+import rails.game.model.PortfolioOwner;
+import rails.game.state.AbstractItem;
+import rails.game.state.Item;
+
+/**
+ * BankPortfolios
+ */
+
+public class BankPortfolio extends AbstractItem implements PortfolioOwner {
+
+ private final PortfolioModel portfolio = PortfolioModel.create();
+
+ private BankPortfolio() {}
+
+ public static BankPortfolio create() {
+ BankPortfolio bp = new BankPortfolio();
+ return bp;
+ }
+
+ /**
+ * parent is restricted to Bank
+ */
+ @Override
+ public void init(Item parent, String id) {
+ super.checkedInit(parent, id, Bank.class);
+ portfolio.init(this, "portfolio");
+ }
+
+ // PortfolioOwner methods
+ public PortfolioModel getPortfolioModel() {
+ return portfolio;
+ }
+
+
+}
diff --git a/rails/game/BaseToken.java b/rails/game/BaseToken.java
index ce55773..253bad1 100644
--- a/rails/game/BaseToken.java
+++ b/rails/game/BaseToken.java
@@ -14,19 +14,18 @@ import rails.game.state.Item;
*/
public final class BaseToken extends Token {
- /**
- * Creates a non-initialized BaseToken
- */
- public BaseToken() {};
+ private BaseToken() {};
+
+ public static BaseToken create(PublicCompany company) {
+ BaseToken token = new BaseToken();
+ token.init(company);
+ return token;
+ }
@Override
- public BaseToken init(Item parent) {
+ public void init(Item parent) {
super.checkedInit(parent, null, PublicCompany.class);
- // add token to the free tokens, this also intializes the portfolio
- getParent().getBaseTokensModel().addFreeToken(this);
-
- return this;
}
@Override
diff --git a/rails/game/BonusToken.java b/rails/game/BonusToken.java
index 3f33613..9c8f871 100644
--- a/rails/game/BonusToken.java
+++ b/rails/game/BonusToken.java
@@ -23,16 +23,17 @@ public final class BonusToken extends Token implements Closeable, ConfigurableCo
private Object removingObject = null;
private PublicCompany user = null;
- /**
- * Creates a non-initialized BonusToken
- */
- public BonusToken() {};
+ private BonusToken() {};
+
+ public static BonusToken create(PublicCompany company) {
+ BonusToken token = new BonusToken();
+ token.init(company);
+ return token;
+ }
- // FIXME: Who is the parent of BonusToken?
@Override
- public BonusToken init(Item parent) {
- super.checkedInit(parent, null, Item.class);
- return this;
+ public void init(Item parent) {
+ super.checkedInit(parent, null, PublicCompany.class);
}
public void configureFromXML(Tag tag) throws ConfigurationException {
diff --git a/rails/game/Certificate.java b/rails/game/Certificate.java
index 638fe51..b4cf016 100644
--- a/rails/game/Certificate.java
+++ b/rails/game/Certificate.java
@@ -1,5 +1,7 @@
package rails.game;
+import rails.game.state.Item;
+
/**
* The superinterface of PrivateCompany and PublicCertificate, which allows
* objects implementating these interfaces to be combined in start packets and
@@ -8,7 +10,7 @@ package rails.game;
* TODO: Check if this is still needed (or replaced by Ownable) or could be extended by
* combining methods from both public and private certificates
*/
-public interface Certificate{
+public interface Certificate extends Item {
}
diff --git a/rails/game/Company.java b/rails/game/Company.java
index 2ec211b..f628f88 100644
--- a/rails/game/Company.java
+++ b/rails/game/Company.java
@@ -12,6 +12,7 @@ import rails.common.parser.Tag;
import rails.game.special.SpecialProperty;
import rails.game.state.BooleanState;
import rails.game.state.AbstractItem;
+import rails.game.state.Item;
import rails.game.state.PortfolioList;
import rails.util.Util;
@@ -27,10 +28,9 @@ Cloneable, Comparable<Company> {
/** The name of the XML attribute for the company's type. */
public static final String COMPANY_TYPE_TAG = "type";
- protected String name;
protected String longName;
protected String alias = null; // To allow reloading files with old names after name changes
- protected CompanyTypeI type;
+ protected CompanyType type;
protected int companyNumber; // For internal use
protected String infoText = "";
@@ -56,15 +56,16 @@ Cloneable, Comparable<Company> {
protected static Logger log =
Logger.getLogger(Company.class.getPackage().getName());
- public Company() {
- }
-
- public void init(String name, CompanyTypeI type) {
- this.name = name;
- this.type = type;
+ @Override
+ public void init(Item parent, String id) {
+ super.init(parent, id);
closedObject.init(this, "closed");
specialProperties.init(this, "specialProperties");
}
+
+ public void initType(CompanyType type) {
+ this.type = type;
+ }
/** Only to be called from subclasses */
public void configureFromXML(Tag tag) throws ConfigurationException {
@@ -140,7 +141,7 @@ Cloneable, Comparable<Company> {
/**
* @return Type of company (Public/Private)
*/
- public CompanyTypeI getType() {
+ public CompanyType getType() {
return type;
}
@@ -148,14 +149,7 @@ Cloneable, Comparable<Company> {
* @return String for type of company (Public/Private)
*/
public String getTypeName() {
- return type.getName();
- }
-
- /**
- * @return Name of company
- */
- public String getId() {
- return name;
+ return type.getId();
}
public String getLongName() {
@@ -234,7 +228,7 @@ Cloneable, Comparable<Company> {
public boolean equals(Company company) {
if (this.companyNumber == company.getCompanyNumber()
- && this.name.equals(company.getId())
+ && this.getId().equals(company.getId())
&& this.type.equals(company.getType())) return true;
return false;
diff --git a/rails/game/CompanyManager.java b/rails/game/CompanyManager.java
index 5a00ee5..257494c 100644
--- a/rails/game/CompanyManager.java
+++ b/rails/game/CompanyManager.java
@@ -1 +1 @@
-package rails.game;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import rails.common.LocalText;
import rails.common.parser.ConfigurableComponentI;
import rails.common.parser.ConfigurationException;
import rails.common.parser.Tag;
import rails.game.state.AbstractItem;
public class CompanyManager extends AbstractItem implements CompanyManagerI, ConfigurableComponentI {
/** A List with all private companies */
private List<PrivateCompany> lPrivateCompanies =
new ArrayList<PrivateCompany>();
/** A List with all public companies */
private List<PublicCompany> lPublicCompanies =
new ArrayList<PublicCompany>();
/** A map with all private companies by name */
private Map<String, PrivateCompany> mPrivateCompanies =
new HashMap<String, PrivateCompany>();
/** A map with all public (i.e. non-private) companies by name */
private Map<String, PublicCompany> mPublicCompanies =
new HashMap<String, PublicCompany>();
/** A map of all type names to maps of companies of that type by name */
// TODO Redundant, current usage can be replaced.
private Map<String, Map<String, Company>> mCompaniesByTypeAndName =
new HashMap<String, Map<String, Company>>();
/** A list of all company types */
private List<CompanyTypeI> lCompanyTypes = new ArrayList<CompanyTypeI>();
/** A list of all start packets (usually one) */
private List<StartPacket> startPackets = new ArrayList<StartPacket>();
/** A map of all start packets, keyed by name. Default name is "Initial" */
private Map<String, StartPacket> startPacketMap
= new HashMap<String, StartPacket>();
/** A map to enable translating aliases to names */
protected Map<String, String> aliases = null;
private int numberOfPublicCompanies = 0;
protected static Logger log =
Logger.getLogger(CompanyManager.class.getPackage().getName());
protec |