|
From: Stefan F. <ste...@us...> - 2012-09-08 07:09:27
|
junit/rails/game/state/BooleanStateTest.java | 4
junit/rails/game/state/CountableItemImpl.java | 13
junit/rails/game/state/GenericStateTest.java | 4
junit/rails/game/state/HashSetStateTest.java | 3
junit/rails/game/state/IntegerStateTest.java | 2
junit/rails/game/state/ModelImpl.java | 2
junit/rails/game/state/ObservableTest.java | 61 --
junit/rails/game/state/StateManagerTest.java | 4
junit/rails/game/state/StateTest.java | 12
junit/rails/game/state/StringStateTest.java | 8
junit/rails/game/state/WalletBagTest.java | 53 +
junit/rails/game/state/WalletManagerTest.java | 110 ++++
src/rails/algorithms/NetworkGraphBuilder.java | 2
src/rails/game/Bank.java | 36 -
src/rails/game/BaseToken.java | 1
src/rails/game/GameManager.java | 26
src/rails/game/MapHex.java | 353 ++++++-------
src/rails/game/OperatingRound.java | 54 +
src/rails/game/Player.java | 4
src/rails/game/PublicCompany.java | 141 ++---
src/rails/game/Round.java | 7
src/rails/game/ShareSellingRound.java | 3
src/rails/game/StartItem.java | 8
src/rails/game/StartRound.java | 3
src/rails/game/StartRound_1830.java | 5
src/rails/game/StartRound_1835.java | 3
src/rails/game/Station.java | 94 +--
src/rails/game/StationHolder.java | 15
src/rails/game/StockRound.java | 12
src/rails/game/Stop.java | 86 +--
src/rails/game/Tile.java | 77 +-
src/rails/game/TileManager.java | 2
src/rails/game/Track.java | 27
src/rails/game/TreasuryShareRound.java | 7
src/rails/game/action/BuyCertificate.java | 15
src/rails/game/action/BuyTrain.java | 22
src/rails/game/action/DiscardTrain.java | 2
src/rails/game/action/LayTile.java | 48 -
src/rails/game/action/PossibleORAction.java | 4
src/rails/game/action/StartCompany.java | 9
src/rails/game/correct/CashCorrectionManager.java | 3
src/rails/game/correct/CorrectionManager.java | 3
src/rails/game/correct/MapCorrectionAction.java | 4
src/rails/game/correct/MapCorrectionManager.java | 7
src/rails/game/model/BaseTokensModel.java | 45 +
src/rails/game/model/PortfolioModel.java | 36 -
src/rails/game/model/PresidentModel.java | 6
src/rails/game/model/WalletMoneyModel.java | 1
src/rails/game/specific/_1835/OperatingRound_1835.java | 3
src/rails/game/specific/_1835/PrussianFormationRound.java | 13
src/rails/game/specific/_1856/CGRFormationRound.java | 33 -
src/rails/game/specific/_1880/StartRound_1880.java | 5
src/rails/game/specific/_1889/OperatingRound_1889.java | 9
src/rails/game/specific/_18AL/OperatingRound_18AL.java | 3
src/rails/game/specific/_18EU/FinalMinorExchangeRound.java | 3
src/rails/game/specific/_18EU/StartCompany_18EU.java | 4
src/rails/game/specific/_18EU/StartRound_18EU.java | 7
src/rails/game/specific/_18EU/StockRound_18EU.java | 9
src/rails/game/specific/_18GA/OperatingRound_18GA.java | 4
src/rails/game/state/ArrayListChange.java | 1
src/rails/game/state/Change.java | 2
src/rails/game/state/ChangeSet.java | 16
src/rails/game/state/ChangeStack.java | 14
src/rails/game/state/CountableItem.java | 4
src/rails/game/state/DelayedItem.java | 8
src/rails/game/state/HashMapState.java | 17
src/rails/game/state/Model.java | 30 -
src/rails/game/state/Observable.java | 59 --
src/rails/game/state/PortfolioChange.java | 4
src/rails/game/state/PortfolioManager.java | 4
src/rails/game/state/Root.java | 15
src/rails/game/state/State.java | 17
src/rails/game/state/StateManager.java | 150 ++++-
src/rails/game/state/TileMove.java | 70 --
src/rails/game/state/Trigger.java | 11
src/rails/game/state/UnknownOwner.java | 2
src/rails/game/state/Wallet.java | 6
src/rails/game/state/WalletBag.java | 7
src/rails/game/state/WalletManager.java | 4
src/rails/game/state/WalletSet.java | 5
src/rails/ui/swing/GameSetupWindow.java | 1
src/rails/ui/swing/RemainingTilesWindow.java | 2
src/rails/ui/swing/hexmap/GUIHex.java | 28 -
src/rails/ui/swing/hexmap/GUITile.java | 2
src/rails/ui/swing/hexmap/HexMap.java | 2
src/rails/util/GameFileIO.java | 3
86 files changed, 1042 insertions(+), 982 deletions(-)
New commits:
commit 40392cca7044d06affcefc3fa6506194be0eff9d
Author: Stefan Frey <ste...@we...>
Date: Sat Sep 8 06:01:47 2012 +0200
adding Trigger interface, Bank's MoneyModel
diff --git a/src/rails/game/Bank.java b/src/rails/game/Bank.java
index 2bb285a..2e9d90d 100644
--- a/src/rails/game/Bank.java
+++ b/src/rails/game/Bank.java
@@ -12,6 +12,9 @@ import rails.common.parser.ConfigurationException;
import rails.common.parser.Tag;
import rails.game.model.WalletMoneyModel;
import rails.game.state.BooleanState;
+import rails.game.state.Change;
+import rails.game.state.Observable;
+import rails.game.state.Trigger;
import rails.game.state.UnknownOwner;
import rails.util.Util;
@@ -44,7 +47,23 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable {
/** Is the bank broken */
private final BooleanState broken = BooleanState.create(this, "broken");
-
+
+ // Instance initializer to create a BankBroken model
+ {
+ new Trigger() {
+ {// instance initializer
+ cash.addTrigger(this);
+ }
+ public void triggered(Observable obs, Change change) {
+ if (cash.value() <= 0 && !broken.value()) {
+ broken.set(true);
+ cash.setText(LocalText.getText("BROKEN"));
+ GameManager.getInstance().registerBrokenBank();
+ }
+ }
+ };
+ }
+
protected static Logger log =
LoggerFactory.getLogger(Bank.class);
@@ -137,16 +156,6 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable {
return scrapHeap;
}
- /* FIXME: Add broken check somewhere
- * Check if the bank has broken. In some games <0 could apply, so this
- * will become configurable.
- if (cash.value() <= 0 && !broken.booleanValue()) {
- broken.set(true);
- cash.setText(LocalText.getText("BROKEN"));
- GameManager.getInstance().registerBrokenBank();
- }
- */
-
/**
* @return Portfolio of stock in Bank Pool
*/
@@ -161,10 +170,10 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable {
return unavailable;
}
- public String getId() {
+ public String toText() {
return LocalText.getText("BANK");
}
-
+
// MoneyOwner interface
public int getCash() {
return cash.value();
@@ -174,4 +183,5 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable {
return cash;
}
+
}
diff --git a/src/rails/game/model/WalletMoneyModel.java b/src/rails/game/model/WalletMoneyModel.java
index 4cbbf75..1d58f6e 100644
--- a/src/rails/game/model/WalletMoneyModel.java
+++ b/src/rails/game/model/WalletMoneyModel.java
@@ -17,6 +17,7 @@ public class WalletMoneyModel extends MoneyModel {
private WalletMoneyModel(MoneyOwner parent, String id, Boolean init, Currency currency) {
super(parent, id, currency);
wallet = WalletBag.create(parent, "wallet", Currency.class, currency);
+ wallet.addModel(this);
initialised = BooleanState.create(this, "initialised", init);
}
diff --git a/src/rails/game/state/ChangeSet.java b/src/rails/game/state/ChangeSet.java
index 2203de5..5395dde 100644
--- a/src/rails/game/state/ChangeSet.java
+++ b/src/rails/game/state/ChangeSet.java
@@ -45,7 +45,7 @@ public class ChangeSet {
log.debug("Add " + change);
// immediate execution and information of models
change.execute();
- change.getState().sendChangeToModels(change);
+ change.getState().informTriggers(change);
}
/**
diff --git a/src/rails/game/state/Model.java b/src/rails/game/state/Model.java
index 5bad3d9..5f3c727 100644
--- a/src/rails/game/state/Model.java
+++ b/src/rails/game/state/Model.java
@@ -16,12 +16,4 @@ public abstract class Model extends Observable {
super(parent, id);
}
- /**
- * Calling of update informs the model that some state has changed
- * Overriding this does not require a call, as it usually does nothing
- */
- public void update(Change change) {
- // Standard behavior is do nothing
- }
-
}
diff --git a/src/rails/game/state/Observable.java b/src/rails/game/state/Observable.java
index cab77d9..08ae14d 100644
--- a/src/rails/game/state/Observable.java
+++ b/src/rails/game/state/Observable.java
@@ -69,6 +69,18 @@ public abstract class Observable implements Item {
return getStateManager().getModels(this);
}
+ public void addTrigger(Trigger m) {
+ getStateManager().addTrigger(m, this);
+ }
+
+ public boolean removeTrigger(Trigger m) {
+ return getStateManager().removeTrigger(m, this);
+ }
+
+ public ImmutableSet<Trigger> getTriggers() {
+ return getStateManager().getTriggers(this);
+ }
+
/**
* Text to delivered to Observers
* Default is defined to be identical with toString()
diff --git a/src/rails/game/state/State.java b/src/rails/game/state/State.java
index ed4a580..c69b480 100644
--- a/src/rails/game/state/State.java
+++ b/src/rails/game/state/State.java
@@ -26,8 +26,8 @@ public abstract class State extends Observable {
}
}
- void sendChangeToModels(Change change) {
- this.getStateManager().sendChangeToModels(this, change);
+ void informTriggers(Change change) {
+ this.getStateManager().informTriggers(this, change);
}
}
\ No newline at end of file
diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java
index 18a12b1..26648a1 100644
--- a/src/rails/game/state/StateManager.java
+++ b/src/rails/game/state/StateManager.java
@@ -27,6 +27,9 @@ public final class StateManager extends Manager{
HashSetState.create(this, "allStates");
private final HashMultimapState<Observable, Model> models =
HashMultimapState.create(this, "models");
+ private final HashMultimapState<Observable, Trigger> triggers =
+ HashMultimapState.create(this, "triggers");
+
// observers is not a state variable (as the have to register and de-register themselves)
// gui eleemnts do not have a state of their own (with respect to the game engine)
@@ -102,7 +105,7 @@ public final class StateManager extends Manager{
/**
* Adds the combination of model to observable
- * @param Model the model that tracks the observable
+ * @param Model the model that is updated by the observable
* @param Observable the observable to monitor
*/
void addModel(Model model, Observable observable) {
@@ -117,16 +120,42 @@ public final class StateManager extends Manager{
return models.get(observable);
}
+ /**
+ * Adds the combination of trigger to observable
+ * @param Trigger the trigger that tracks the observable
+ * @param Observable the observable to monitor
+ */
+ void addTrigger(Trigger trigger, Observable observable) {
+ triggers.put(observable, trigger);
+ }
+
+ boolean removeTrigger(Trigger trigger, Observable observable) {
+ return triggers.remove(observable, trigger);
+ }
- void sendChangeToModels(State state, Change change) {
+ ImmutableSet<Trigger> getTriggers(Observable observable) {
+ return triggers.get(observable);
+ }
+
+ void informTriggers(State state, Change change) {
+
+ // Inform direct triggers
+ for (Trigger t:getTriggers(state)) {
+ t.triggered(state, change);
+ log.debug("State " + state + " sends change to Trigger " + t);
+ }
+
// check if there are models
- ImmutableSet<Model> initModels = state.getModels();
+ ImmutableSet<Model> initModels = getModels(state);
if (initModels.isEmpty()) return;
ImmutableList<Model> allModels = getModelsToUpdate(initModels);
+ // Inform indirect triggers
for (Model m:allModels) {
- m.update(change);
- log.debug("State " + state + " sends change to Model " + m);
+ for (Trigger t:getTriggers(m)) {
+ t.triggered(m, change);
+ log.debug("Model " + m + " sends change to Trigger " + t);
+ }
}
}
@@ -155,7 +184,7 @@ public final class StateManager extends Manager{
private static enum Color {WHITE, GREY, BLACK};
private void topoSort(final Observable v, final Map<Observable, Color> colors, final LinkedList<Model> topoList) {
colors.put(v, Color.GREY);
- for (Model m:v.getModels()) {
+ for (Model m:getModels(v)) {
if (!colors.containsKey(m)) {
topoSort(m, colors, topoList);
} else if (colors.get(m) == Color.GREY) {
@@ -170,7 +199,7 @@ public final class StateManager extends Manager{
void updateObservers(Set<State> states) {
// all direct observers
for (State s:states){
- Set<Observer> observers = s.getObservers();
+ Set<Observer> observers = getObservers(s);
if (observers.isEmpty()) continue;
// cache StateText
String stateText = s.toText();
@@ -182,7 +211,7 @@ public final class StateManager extends Manager{
// all indirect observers
for (Model m:getModelsToUpdate(states)) {
- Set<Observer> observers = m.getObservers();
+ Set<Observer> observers = getObservers(m);
if (observers.isEmpty()) continue;
// cache ModelText
String modelText = m.toText();
diff --git a/src/rails/game/state/Trigger.java b/src/rails/game/state/Trigger.java
new file mode 100644
index 0000000..6d98021
--- /dev/null
+++ b/src/rails/game/state/Trigger.java
@@ -0,0 +1,11 @@
+package rails.game.state;
+
+public interface Trigger {
+
+ /**
+ * Method that is called if something has changed
+ */
+ public void triggered(Observable observable, Change change);
+
+
+}
commit 7e1968117743a8cff1d809da5381dc499061b1a7
Author: Stefan Frey <ste...@we...>
Date: Fri Sep 7 12:48:10 2012 +0200
fixed several minor bugs
diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java
index a108723..defc765 100644
--- a/src/rails/game/GameManager.java
+++ b/src/rails/game/GameManager.java
@@ -767,9 +767,10 @@ public class GameManager extends RailsManager implements Configurable, Owner {
interruptedRound = getCurrentRound();
+ // An id basd on interruptedRound and company id
+ String id = "SSR_" + interruptedRound.getId() + "_" + cashNeedingCompany.getId();
// check if other companies can be dumped
- // FIXME: This ID will not work, as it will create duplication
- createRound(shareSellingRoundClass, "ShareSellingRound").start(
+ createRound(shareSellingRoundClass, id).start(
interruptedRound, player, cashToRaise, cashNeedingCompany,
!problemDumpOtherCompanies || forcedSellingCompanyDump);
// the last parameter indicates if the dump of other companies is allowed, either this is explicit or
diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java
index 3d0a8f4..7714ff8 100644
--- a/src/rails/game/MapHex.java
+++ b/src/rails/game/MapHex.java
@@ -20,8 +20,6 @@ import rails.game.Stop.RunTo;
import rails.game.Stop.Score;
import rails.game.Stop.Type;
import rails.game.action.LayTile;
-import rails.game.model.WalletMoneyModel;
-import rails.game.model.PortfolioModel;
import rails.game.state.BooleanState;
import rails.game.state.GenericState;
@@ -1278,8 +1276,8 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable {
*
* @TODO include tokens??
*/
- public String getData() {
- return currentTile.value().getNb() + "/" + currentTileRotation;
+ public String toText() {
+ return currentTile.value().getNb() + "/" + currentTileRotation.value();
}
/**
@@ -1352,27 +1350,4 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable {
return scoreType;
}
- // Owner interface
-
- public boolean hasPortfolio() {
- return false;
- }
-
- public PortfolioModel getPortfolioModel() {
- return null;
- }
-
- public boolean hasCash() {
- return false;
- }
-
- public WalletMoneyModel getCash() {
- return null;
- }
-
- public void update() {
- // TODO Auto-generated method stub
-
- }
-
}
diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java
index aa0e49b..d0b5631 100644
--- a/src/rails/game/OperatingRound.java
+++ b/src/rails/game/OperatingRound.java
@@ -308,7 +308,7 @@ public class OperatingRound extends Round implements Observer {
result = done(nullAction);
break;
case NullAction.SKIP:
- skip();
+ skip(nullAction);
result = true;
break;
}
@@ -703,10 +703,11 @@ public class OperatingRound extends Round implements Observer {
}
while (++stepIndex < steps.length) {
step = steps[stepIndex];
- log.debug("Step " + step);
+ log.debug("OR considers step " + step);
if (step == GameDef.OrStep.LAY_TOKEN
&& company.getNumberOfFreeBaseTokens() == 0) {
+ log.debug("OR skips " + step + ": No freeBaseTokens");
continue;
}
@@ -714,6 +715,7 @@ public class OperatingRound extends Round implements Observer {
if (!company.canRunTrains()) {
// No trains, then the revenue is zero.
+ log.debug("OR skips " + step + ": Cannot run trains");
executeSetRevenueAndDividend (
new SetDividend (0, false, new int[] {SetDividend.NO_TRAIN}));
// TODO: This probably does not handle share selling correctly
@@ -723,6 +725,7 @@ public class OperatingRound extends Round implements Observer {
if (step == GameDef.OrStep.PAYOUT) {
// This step is now obsolete
+ log.debug("OR skips " + step + ": Always skipped");
continue;
}
@@ -767,7 +770,10 @@ public class OperatingRound extends Round implements Observer {
}
- if (!gameSpecificNextStep (step)) continue;
+ if (!gameSpecificNextStep (step)) {
+ log.debug("OR skips " + step + ": Not game specific");
+ continue;
+ }
// No reason found to skip this step
break;
@@ -808,10 +814,10 @@ public class OperatingRound extends Round implements Observer {
* 3.1. NOOPS
*=======================================*/
- public void skip() {
+ public void skip(NullAction action) {
log.debug("Skip step " + stepObject.value());
// TODO: Check if this is ok
- // FIXME: changeStack.start(true);
+ ChangeStack.start(this, action);
nextStep();
}
@@ -2742,7 +2748,7 @@ public class OperatingRound extends Round implements Observer {
operatingCompany.value().buyTrain(train, price);
- if (oldOwner == ipo.getTrainsModel()) {
+ if (oldOwner == ipo.getParent()) {
train.getCertType().addToBoughtFromIPO();
trainManager.setAnyTrainBought(true);
// Clone the train if infinitely available
@@ -2751,7 +2757,7 @@ public class OperatingRound extends Round implements Observer {
}
}
- if (oldOwner instanceof Bank) {
+ if (oldOwner instanceof BankPortfolio) {
trainsBoughtThisTurn.add(train.getCertType());
}
diff --git a/src/rails/game/action/BuyCertificate.java b/src/rails/game/action/BuyCertificate.java
index 4401351..a6f400c 100644
--- a/src/rails/game/action/BuyCertificate.java
+++ b/src/rails/game/action/BuyCertificate.java
@@ -7,9 +7,6 @@ import rails.game.*;
import rails.game.model.PortfolioModel;
import rails.game.model.PortfolioOwner;
-/**
- * @author Erik Vos
- */
public class BuyCertificate extends PossibleAction {
// Server-side settings
diff --git a/src/rails/game/action/BuyTrain.java b/src/rails/game/action/BuyTrain.java
index a15a02f..518c32a 100644
--- a/src/rails/game/action/BuyTrain.java
+++ b/src/rails/game/action/BuyTrain.java
@@ -5,6 +5,8 @@ import java.io.ObjectInputStream;
import java.util.HashSet;
import java.util.Set;
+import com.google.common.base.Objects;
+
import rails.game.CompanyManager;
import rails.game.Currency;
import rails.game.GameManager;
@@ -218,7 +220,7 @@ public class BuyTrain extends PossibleORAction {
}
b.append("train (").append(trainUniqueId).append(") from ").append(from.getId());
if (fixedCost > 0) {
- b.append(" for ").append(Currency.format(train, fixedCost));
+ b.append(" for ").append(Currency.format(company, fixedCost));
} else {
b.append(" for any amount");
}
@@ -229,14 +231,14 @@ public class BuyTrain extends PossibleORAction {
b.append(forcedExchange ? " (forced exchange)" : " (exchange)");
}
if (presidentMustAddCash) {
- b.append(" must add cash ").append(Currency.format(train, presidentCashToAdd));
+ b.append(" must add cash ").append(Currency.format(company, presidentCashToAdd));
} else if (presidentMayAddCash) {
b.append(" may add cash up to ").append(
- Currency.format(train, presidentCashToAdd));
+ Currency.format(company, presidentCashToAdd));
}
if (acted) {
- b.append(" - paid: ").append(Currency.format(train, pricePaid));
- if (addedCash > 0) b.append(" pres.cash added: "+Currency.format(train, addedCash));
+ b.append(" - paid: ").append(Currency.format(company, pricePaid));
+ if (addedCash > 0) b.append(" pres.cash added: "+Currency.fo |