You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(46) |
Dec
(57) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(51) |
Feb
(10) |
Mar
|
Apr
|
May
(14) |
Jun
|
Jul
(13) |
Aug
(30) |
Sep
(83) |
Oct
(56) |
Nov
(148) |
Dec
(107) |
2010 |
Jan
(260) |
Feb
(164) |
Mar
(183) |
Apr
(99) |
May
(160) |
Jun
(40) |
Jul
(33) |
Aug
(48) |
Sep
(22) |
Oct
(24) |
Nov
(1) |
Dec
(12) |
2011 |
Jan
(6) |
Feb
(15) |
Mar
(13) |
Apr
(37) |
May
(27) |
Jun
(29) |
Jul
(33) |
Aug
(20) |
Sep
(17) |
Oct
(20) |
Nov
(33) |
Dec
(17) |
2012 |
Jan
(39) |
Feb
(38) |
Mar
(20) |
Apr
(21) |
May
(17) |
Jun
(22) |
Jul
(16) |
Aug
(3) |
Sep
(9) |
Oct
(10) |
Nov
|
Dec
|
From: Stefan F. <ste...@us...> - 2012-07-23 16:59:37
|
Tag 'v1.7.8' created by Stefan Frey <ste...@we...> at 2012-07-23 16:58 +0000 version 1.7.8 Changes since v1.7.7-2: --- 0 files changed --- |
From: Stefan F. <ste...@us...> - 2012-07-23 16:59:34
|
rails/ui/swing/GameStatus.java | 5 +++-- readme.txt | 13 ++++--------- version.number | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) New commits: commit 18c0f865fc235df7a4d370114d3d26cb3eff4f76 Author: Stefan Frey <ste...@we...> Date: Mon Jul 23 17:01:38 2012 +0200 prepared for 1.7.8 release diff --git a/readme.txt b/readme.txt index 33de310..111a7c4 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ -Rails release 1.7.7: +Rails release 1.7.8: A new maintenance release for Rails 1.x series @@ -6,13 +6,8 @@ This release fixes several bugs. Contributors: Erik Vos, Stefan Frey -Bug reported by Are-Harald Brenne, John David Galt - -New: -- Added little fun variant 18Lummer +Bugs reported by Martin Brumm, John David Galt Lists of bugs fixed: -- Errors in UI after adding a comment at game start -- Fixed failure on reloading a just started game -- 1835: Manual close of Pfalzbahn is possible (to enable closing after token lay only) -- 1835 (and others): Fixed UI issues with token relays on OO-tiles +- All Games: Update "PD" label in GameStatus lower player names panel +- 1835 (and others with NoMapMode): Cannot save game file with ClosePrivate action diff --git a/version.number b/version.number index 60520e3..f74a335 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.7 +version=1.7.8 # the following string "@DEVELOP@ is replaced by an empty string in the release version # this is done automatically by ant develop=@DEVELOP@ \ No newline at end of file commit 59d48a43689c5128a9487290d0682e0961201c6e Author: Erik Vos <eri...@xs...> Date: Mon Jul 23 12:06:11 2012 +0200 Fix to all games: update PD in GameStatus lower player names row.(cherry picked from commit 7d694b4bc788283c72de5165dee0d54ee55cb6d1) diff --git a/rails/ui/swing/GameStatus.java b/rails/ui/swing/GameStatus.java index a10dd80..498522a 100644 --- a/rails/ui/swing/GameStatus.java +++ b/rails/ui/swing/GameStatus.java @@ -975,8 +975,9 @@ public class GameStatus extends GridPanel implements ActionListener { public void setPriorityPlayer(int index) { for (int j = 0; j < np; j++) { - upperPlayerCaption[j].setText(players.get(j).getName() - + (j == index ? " PD" : "")); + String playerNameAndPriority = players.get(j).getName() + (j == index ? " PD" : ""); + upperPlayerCaption[j].setText(playerNameAndPriority); + lowerPlayerCaption[j].setText(playerNameAndPriority); } } |
From: Erik V. <ev...@us...> - 2012-07-23 10:06:58
|
rails/ui/swing/GameStatus.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) New commits: commit 7d694b4bc788283c72de5165dee0d54ee55cb6d1 Author: Erik Vos <eri...@xs...> Date: Mon Jul 23 12:06:11 2012 +0200 Fix to all games: update PD in GameStatus lower player names row. diff --git a/rails/ui/swing/GameStatus.java b/rails/ui/swing/GameStatus.java index 4022dc3..99ec31b 100644 --- a/rails/ui/swing/GameStatus.java +++ b/rails/ui/swing/GameStatus.java @@ -1011,8 +1011,9 @@ public class GameStatus extends GridPanel implements ActionListener { public void setPriorityPlayer(int index) { for (int j = 0; j < np; j++) { - upperPlayerCaption[j].setText(players.get(j).getName() - + (j == index ? " PD" : "")); + String playerNameAndPriority = players.get(j).getName() + (j == index ? " PD" : ""); + upperPlayerCaption[j].setText(playerNameAndPriority); + lowerPlayerCaption[j].setText(playerNameAndPriority); } } |
From: Stefan F. <ste...@us...> - 2012-07-22 21:32:42
|
rails/game/correct/ClosePrivate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit b564e00983be9033464fd3e0658d61143ab5bf5f Author: Stefan Frey <ste...@we...> Date: Sun Jul 22 23:32:17 2012 +0200 fixed bug: cannot save game file with ClosePrivate action, reported by John David Galt diff --git a/rails/game/correct/ClosePrivate.java b/rails/game/correct/ClosePrivate.java index e780ff1..45786f1 100644 --- a/rails/game/correct/ClosePrivate.java +++ b/rails/game/correct/ClosePrivate.java @@ -18,7 +18,7 @@ public class ClosePrivate extends PossibleAction { /* Preconditions */ /** private company to close */ - private PrivateCompanyI privateCompany; + transient private PrivateCompanyI privateCompany; /** converted to name */ private String privateCompanyName; |
From: Stefan F. <ste...@us...> - 2012-07-20 07:59:18
|
.classpath | 4 dev/null |binary junit/lib/fest-2.0M6/fest-assert-core-2.0M6.jar |binary junit/lib/fest-2.0M6/fest-util-1.2.1.jar |binary junit/rails/game/state/AbstractItemImpl.java | 8 junit/rails/game/state/ArrayListStateTest.java | 245 +++++++++++++++++++++++ junit/rails/game/state/BooleanStateTest.java | 38 +-- junit/rails/game/state/GenericStateTest.java | 54 ++--- junit/rails/game/state/HashMapStateTest.java | 177 ++++++++++++++++ junit/rails/game/state/HashSetStateTest.java | 166 +++++++++++++++ junit/rails/game/state/IntegerStateTest.java | 54 ++--- junit/rails/game/state/StateImpl.java | 6 junit/rails/game/state/StateTestUtils.java | 7 junit/rails/game/state/StringStateTest.java | 72 +++--- src/rails/game/state/AbstractItem.java | 5 src/rails/game/state/ArrayListChange.java | 30 +- src/rails/game/state/ArrayListMultimapState.java | 5 src/rails/game/state/ArrayListState.java | 73 +++++- src/rails/game/state/BooleanChange.java | 11 - src/rails/game/state/BooleanState.java | 2 src/rails/game/state/Context.java | 6 src/rails/game/state/GenericState.java | 5 src/rails/game/state/GenericStateChange.java | 23 -- src/rails/game/state/HashMapChange.java | 19 + src/rails/game/state/HashMapState.java | 113 ++++++++-- src/rails/game/state/HashMultimapState.java | 2 src/rails/game/state/HashSetChange.java | 21 + src/rails/game/state/HashSetState.java | 6 src/rails/game/state/IntegerChange.java | 11 - src/rails/game/state/IntegerState.java | 2 src/rails/game/state/Manager.java | 5 src/rails/game/state/MultimapChange.java | 15 - src/rails/game/state/Observable.java | 11 + src/rails/game/state/PortfolioChange.java | 13 - src/rails/game/state/PortfolioList.java | 5 src/rails/game/state/PortfolioMap.java | 4 src/rails/game/state/Root.java | 6 src/rails/game/state/State.java | 11 - src/rails/game/state/StringChange.java | 11 - src/rails/game/state/StringState.java | 2 src/rails/game/state/Wallet.java | 6 src/rails/game/state/WalletChange.java | 13 - 42 files changed, 983 insertions(+), 284 deletions(-) New commits: commit 4cc7610949e6fa611f086e2d89b7c2540c18e2a8 Author: Stefan Frey <ste...@we...> Date: Thu Jul 19 16:48:19 2012 +0200 changed only variable names diff --git a/junit/rails/game/state/ArrayListStateTest.java b/junit/rails/game/state/ArrayListStateTest.java index fb11df0..e858570 100644 --- a/junit/rails/game/state/ArrayListStateTest.java +++ b/junit/rails/game/state/ArrayListStateTest.java @@ -26,8 +26,8 @@ public class ArrayListStateTest { private Root root; private ChangeStack stack; - private ArrayListState<Item> state_default; - private ArrayListState<Item> state_init; + private ArrayListState<Item> stateDefault; + private ArrayListState<Item> stateInit; private Item oneItem; private Item anotherItem; @@ -41,8 +41,8 @@ public class ArrayListStateTest { oneItem = AbstractItemImpl.create(root, ONE_ITEM_ID); anotherItem = AbstractItemImpl.create(root, ANOTHER_ITEM_ID); - state_default = ArrayListState.create(root, DEFAULT_ID); - state_init = ArrayListState.create(root, INIT_ID, Lists.newArrayList(oneItem)); + stateDefault = ArrayListState.create(root, DEFAULT_ID); + stateInit = ArrayListState.create(root, INIT_ID, Lists.newArrayList(oneItem)); } // helper function to check the initial state after undo @@ -50,21 +50,21 @@ public class ArrayListStateTest { private void assertInitialStateAfterUndo() { stack.closeCurrentChangeSet(); stack.undo(); - assertEquals(state_default.view(), Lists.newArrayList()); - assertEquals(state_init.view(), Lists.newArrayList(oneItem)); + assertEquals(stateDefault.view(), Lists.newArrayList()); + assertEquals(stateInit.view(), Lists.newArrayList(oneItem)); stack.redo(); } private void assertTestAdd() { // TODO: replace with containsExactly, this does not work yet - assertThat(state_default).containsOnly(oneItem); - assertThat(state_init).containsSequence(oneItem, anotherItem); + assertThat(stateDefault).containsOnly(oneItem); + assertThat(stateInit).containsSequence(oneItem, anotherItem); } @Test public void testAdd() { - state_default.add(oneItem); - state_init.add(anotherItem); + stateDefault.add(oneItem); + stateInit.add(anotherItem); assertTestAdd(); // check undo @@ -74,20 +74,20 @@ public class ArrayListStateTest { @Test public void testAddIndex() { - state_init.add(0, anotherItem); + stateInit.add(0, anotherItem); // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem); - state_init.add(2, anotherItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem); + stateInit.add(2, anotherItem); // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem, anotherItem); - state_init.add(1, oneItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem, anotherItem); + stateInit.add(1, oneItem); // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem, oneItem, anotherItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem, oneItem, anotherItem); // Check undo assertInitialStateAfterUndo(); // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem, oneItem, anotherItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem, oneItem, anotherItem); } @Test @@ -95,13 +95,13 @@ public class ArrayListStateTest { // open new ChangeSet to test if it is still empty StateTestUtils.startActionChangeSet(root); try { - state_init.add(2, anotherItem); + stateInit.add(2, anotherItem); failBecauseExceptionWasNotThrown(IndexOutOfBoundsException.class); } catch (Exception e) { assertThat(e).isInstanceOf(IndexOutOfBoundsException.class); } try { - state_init.add(-1, anotherItem); + stateInit.add(-1, anotherItem); failBecauseExceptionWasNotThrown(IndexOutOfBoundsException.class); } catch (Exception e) { assertThat(e).isInstanceOf(IndexOutOfBoundsException.class); @@ -114,105 +114,105 @@ public class ArrayListStateTest { @Test public void testRemove() { // remove a non-existing item - assertFalse(state_default.remove(oneItem)); + assertFalse(stateDefault.remove(oneItem)); // remove an existing item - assertTrue(state_init.remove(oneItem)); + assertTrue(stateInit.remove(oneItem)); - assertThat(state_init).doesNotContain(oneItem); + assertThat(stateInit).doesNotContain(oneItem); // check undo assertInitialStateAfterUndo(); // ... and the redo - assertThat(state_init).doesNotContain(oneItem); + assertThat(stateInit).doesNotContain(oneItem); } @Test public void testMove() { - state_init.add(0, anotherItem); + stateInit.add(0, anotherItem); // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem); - state_init.move(oneItem, 0); + stateInit.move(oneItem, 0); // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(oneItem, anotherItem); + assertThat(stateInit).containsSequence(oneItem, anotherItem); - state_init.move(oneItem, 1); + stateInit.move(oneItem, 1); // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem); // try illegal move and check if nothing has changed try { - state_init.move(oneItem, 2); + stateInit.move(oneItem, 2); failBecauseExceptionWasNotThrown(IndexOutOfBoundsException.class); } catch (Exception e) { assertThat(e).isInstanceOf(IndexOutOfBoundsException.class); } // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem); // check undo assertInitialStateAfterUndo(); // ... and the redo // TODO: replace with containsExactly, this does not work yet - assertThat(state_init).containsSequence(anotherItem, oneItem); + assertThat(stateInit).containsSequence(anotherItem, oneItem); } @Test public void testContains() { - assertTrue(state_init.contains(oneItem)); - assertFalse(state_init.contains(anotherItem)); + assertTrue(stateInit.contains(oneItem)); + assertFalse(stateInit.contains(anotherItem)); } @Test public void testClear() { - state_init.add(anotherItem); - state_init.clear(); - assertTrue(state_init.isEmpty()); + stateInit.add(anotherItem); + stateInit.clear(); + assertTrue(stateInit.isEmpty()); // check undo and redo assertInitialStateAfterUndo(); - assertTrue(state_init.isEmpty()); + assertTrue(stateInit.isEmpty()); } @Test public void testView() { ImmutableList<Item> list = ImmutableList.of(oneItem); - assertEquals(list, state_init.view()); + assertEquals(list, stateInit.view()); } @Test public void testSize() { - assertEquals(0, state_default.size()); - assertEquals(1, state_init.size()); - state_init.add(anotherItem); - state_init.add(oneItem); - assertEquals(3, state_init.size()); + assertEquals(0, stateDefault.size()); + assertEquals(1, stateInit.size()); + stateInit.add(anotherItem); + stateInit.add(oneItem); + assertEquals(3, stateInit.size()); } @Test public void testIsEmpty() { - assertTrue(state_default.isEmpty()); - assertFalse(state_init.isEmpty()); + assertTrue(stateDefault.isEmpty()); + assertFalse(stateInit.isEmpty()); } @Test public void testIndexOf() { - state_init.add(anotherItem); - assertEquals(0, state_init.indexOf(oneItem)); - assertEquals(1, state_init.indexOf(anotherItem)); + stateInit.add(anotherItem); + assertEquals(0, stateInit.indexOf(oneItem)); + assertEquals(1, stateInit.indexOf(anotherItem)); // check if not included - assertEquals(-1, state_default.indexOf(oneItem)); + assertEquals(-1, stateDefault.indexOf(oneItem)); } @Test public void testGet() { - state_init.add(anotherItem); - assertSame(oneItem, state_init.get(0)); - assertSame(anotherItem, state_init.get(1)); + stateInit.add(anotherItem); + assertSame(oneItem, stateInit.get(0)); + assertSame(anotherItem, stateInit.get(1)); // check index out of bound try { - state_init.get(2); + stateInit.get(2); failBecauseExceptionWasNotThrown(IndexOutOfBoundsException.class); } catch (Exception e) { assertThat(e).isInstanceOf(IndexOutOfBoundsException.class); @@ -220,21 +220,21 @@ public class ArrayListStateTest { } private void assertTestIterator() { - Iterator<Item> it = state_init.iterator(); + Iterator<Item> it = stateInit.iterator(); assertSame(oneItem,it.next()); assertSame(anotherItem,it.next()); // iterator is finished assertFalse(it.hasNext()); // iterator is an immutable copy, thus not changed by adding a new item - state_init.add(oneItem); + stateInit.add(oneItem); assertFalse(it.hasNext()); // remove the last added item - state_init.remove(state_init.size()-1); + stateInit.remove(stateInit.size()-1); } @Test public void testIterator() { - state_init.add(anotherItem); + stateInit.add(anotherItem); assertTestIterator(); // check initial state after undo assertInitialStateAfterUndo(); diff --git a/junit/rails/game/state/BooleanStateTest.java b/junit/rails/game/state/BooleanStateTest.java index 51427af..c40fce5 100644 --- a/junit/rails/game/state/BooleanStateTest.java +++ b/junit/rails/game/state/BooleanStateTest.java @@ -13,50 +13,50 @@ public class BooleanStateTest { private Root root; private ChangeStack stack; - private BooleanState state_default; - private BooleanState state_init; + private BooleanState stateDefault; + private BooleanState stateInit; @Before public void setUp() { root = StateTestUtils.setUpRoot(); - state_default = BooleanState.create(root, DEFAULT_ID); - state_init = BooleanState.create(root, INIT_ID, true); + stateDefault = BooleanState.create(root, DEFAULT_ID); + stateInit = BooleanState.create(root, INIT_ID, true); stack = root.getStateManager().getChangeStack(); } @Test public void testValue() { - assertFalse(state_default.value()); - assertTrue(state_init.value()); + assertFalse(stateDefault.value()); + assertTrue(stateInit.value()); } @Test public void testSet() { - state_default.set(true); - assertTrue(state_default.value()); - state_init.set(false); - assertFalse(state_init.value()); + stateDefault.set(true); + assertTrue(stateDefault.value()); + stateInit.set(false); + assertFalse(stateInit.value()); } @Test public void testSetSameIgnored() { - state_default.set(false); - state_init.set(true); + stateDefault.set(false); + stateInit.set(true); stack.closeCurrentChangeSet(); - assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default, state_init); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(stateDefault, stateInit); } @Test public void testUndoRedo() { - assertFalse(state_default.value()); - state_default.set(true); - assertTrue(state_default.value()); + assertFalse(stateDefault.value()); + stateDefault.set(true); + assertTrue(stateDefault.value()); stack.closeCurrentChangeSet(); - assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default); + assertThat(stack.getLastClosedChangeSet().getStates()).contains(stateDefault); stack.undo(); - assertFalse(state_default.value()); + assertFalse(stateDefault.value()); stack.redo(); - assertTrue(state_default.value()); + assertTrue(stateDefault.value()); } } diff --git a/junit/rails/game/state/GenericStateTest.java b/junit/rails/game/state/GenericStateTest.java index aaccd90..b423e3c 100644 --- a/junit/rails/game/state/GenericStateTest.java +++ b/junit/rails/game/state/GenericStateTest.java @@ -15,8 +15,8 @@ public class GenericStateTest { private Root root; private ChangeStack stack; - private GenericState<Item> state_default; - private GenericState<Item> state_init; + private GenericState<Item> stateDefault; + private GenericState<Item> stateInit; private Item item, another_item; @@ -28,55 +28,55 @@ public class GenericStateTest { item = new AbstractItemImpl(root, ITEM_ID); another_item = new AbstractItemImpl(root, ANOTHER_ID); - state_default = GenericState.create(root, DEFAULT_ID); - state_init = GenericState.create(root, INIT_ID, item); + stateDefault = GenericState.create(root, DEFAULT_ID); + stateInit = GenericState.create(root, INIT_ID, item); } @Test public void testValue() { - assertNull(state_default.value()); - assertSame(item, state_init.value()); + assertNull(stateDefault.value()); + assertSame(item, stateInit.value()); } @Test public void testSet() { - state_default.set(item); - assertSame(item, state_default.value()); - state_default.set(null); - assertNull(state_default.value()); - state_init.set(another_item); - assertSame(another_item, state_init.value()); + stateDefault.set(item); + assertSame(item, stateDefault.value()); + stateDefault.set(null); + assertNull(stateDefault.value()); + stateInit.set(another_item); + assertSame(another_item, stateInit.value()); } @Test public void testSetSameIgnored() { - state_default.set(null); - state_init.set(item); + stateDefault.set(null); + stateInit.set(item); stack.closeCurrentChangeSet(); - assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default, state_init); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(stateDefault, stateInit); } @Test public void testUndoRedo() { - assertNull(state_default.value()); - assertSame(item, state_init.value()); + assertNull(stateDefault.value()); + assertSame(item, stateInit.value()); - state_default.set(item); - state_init.set(another_item); - assertSame(item, state_default.value()); - assertSame(another_item, state_init.value()); + stateDefault.set(item); + stateInit.set(another_item); + assertSame(item, stateDefault.value()); + assertSame(another_item, stateInit.value()); stack.closeCurrentChangeSet(); - // remark: state_init is an internal (isObservable = false) - assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default); + // remark: stateInit is an internal (isObservable = false) + assertThat(stack.getLastClosedChangeSet().getStates()).contains(stateDefault); stack.undo(); - assertNull(state_default.value()); - assertSame(item, state_init.value()); + assertNull(stateDefault.value()); + assertSame(item, stateInit.value()); stack.redo(); - assertSame(item, state_default.value()); - assertSame(another_item, state_init.value()); + assertSame(item, stateDefault.value()); + assertSame(another_item, stateInit.value()); } } diff --git a/junit/rails/game/state/HashSetStateTest.java b/junit/rails/game/state/HashSetStateTest.java index f30d078..02d76ff 100644 --- a/junit/rails/game/state/HashSetStateTest.java +++ b/junit/rails/game/state/HashSetStateTest.java @@ -26,8 +26,8 @@ public class HashSetStateTest { private Root root; private ChangeStack stack; - private HashSetState<Item> state_default; - private HashSetState<Item> state_init; + private HashSetState<Item> stateDefault; + private HashSetState<Item> stateInit; private Item oneItem; private Item anotherItem; @@ -41,8 +41,8 @@ public class HashSetStateTest { oneItem = AbstractItemImpl.create(root, ONE_ITEM_ID); anotherItem = AbstractItemImpl.create(root, ANOTHER_ITEM_ID); - state_default = HashSetState.create(root, DEFAULT_ID); - state_init = HashSetState.create(root, INIT_ID, Sets.newHashSet(oneItem)); + stateDefault = HashSetState.create(root, DEFAULT_ID); + stateInit = HashSetState.create(root, INIT_ID, Sets.newHashSet(oneItem)); } @@ -59,20 +59,20 @@ public class HashSetStateTest { private void assertInitialStateAfterUndo() { stack.closeCurrentChangeSet(); stack.undo(); - assertEquals(state_default.view(), Sets.newHashSet()); - assertEquals(state_init.view(), Sets.newHashSet(oneItem)); + assertEquals(stateDefault.view(), Sets.newHashSet()); + assertEquals(stateInit.view(), Sets.newHashSet(oneItem)); stack.redo(); } private void assertTestAdd() { - assertThat(state_default).containsOnly(oneItem); - assertThat(state_init).containsOnly(oneItem, anotherItem); + assertThat(stateDefault).containsOnly(oneItem); + assertThat(stateInit).containsOnly(oneItem, anotherItem); } @Test public void testAdd() { - state_default.add(oneItem); - state_init.add(anotherItem); + stateDefault.add(oneItem); + stateInit.add(anotherItem); assertTestAdd(); // check undo @@ -83,62 +83,62 @@ public class HashSetStateTest { @Test public void testRemove() { // remove a non-existing item - assertFalse(state_default.remove(oneItem)); + assertFalse(stateDefault.remove(oneItem)); // remove an existing item - assertTrue(state_init.remove(oneItem)); + assertTrue(stateInit.remove(oneItem)); - assertThat(state_init).doesNotContain(oneItem); + assertThat(stateInit).doesNotContain(oneItem); // check undo assertInitialStateAfterUndo(); // ... and the redo - assertThat(state_init).doesNotContain(oneItem); + assertThat(stateInit).doesNotContain(oneItem); } @Test public void testContains() { - assertTrue(state_init.contains(oneItem)); - assertFalse(state_init.contains(anotherItem)); + assertTrue(stateInit.contains(oneItem)); + assertFalse(stateInit.contains(anotherItem)); } @Test public void testClear() { - state_init.add(anotherItem); - state_init.clear(); - assertTrue(state_init.isEmpty()); + stateInit.add(anotherItem); + stateInit.clear(); + assertTrue(stateInit.isEmpty()); // check undo and redo assertInitialStateAfterUndo(); - assertTrue(state_init.isEmpty()); + assertTrue(stateInit.isEmpty()); } @Test public void testView() { ImmutableSet<Item> list = ImmutableSet.of(oneItem); - assertEquals(list, state_init.view()); + assertEquals(list, stateInit.view()); } @Test public void testSize() { - assertEquals(0, state_default.size()); - assertEquals(1, state_init.size()); - state_init.add(anotherItem); - assertEquals(2, state_init.size()); - state_init.add(oneItem); - assertEquals(2, state_init.size()); + assertEquals(0, stateDefault.size()); + assertEquals(1, stateInit.size()); + stateInit.add(anotherItem); + assertEquals(2, stateInit.size()); + stateInit.add(oneItem); + assertEquals(2, stateInit.size()); } @Test public void testIsEmpty() { - assertTrue(state_default.isEmpty()); - assertFalse(state_init.isEmpty()); + assertTrue(stateDefault.isEmpty()); + assertFalse(stateInit.isEmpty()); } private void assertTestIterator(Item thirdItem) { // no order is defined, so store them Set<Item> iterated = Sets.newHashSet(); - Iterator<Item> it = state_init.iterator(); + Iterator<Item> it = stateInit.iterator(); iterated.add(it.next()); iterated.add(it.next()); @@ -146,15 +146,15 @@ public class HashSetStateTest { // iterator is finished assertFalse(it.hasNext()); // iterator is an immutable copy, thus not changed by adding a new item - state_init.add(thirdItem); + stateInit.add(thirdItem); assertFalse(it.hasNext()); // remove the last added item - state_init.remove(thirdItem); + stateInit.remove(thirdItem); } @Test public void testIterator() { - state_init.add(anotherItem); + stateInit.add(anotherItem); Item thirdItem = AbstractItemImpl.create(root, "Third"); assertTestIterator(thirdItem); // check initial state after undo diff --git a/junit/rails/game/state/IntegerStateTest.java b/junit/rails/game/state/IntegerStateTest.java index 9c183a3..fed226c 100644 --- a/junit/rails/game/state/IntegerStateTest.java +++ b/junit/rails/game/state/IntegerStateTest.java @@ -15,8 +15,8 @@ public class IntegerStateTest { private Root root; private ChangeStack stack; - private IntegerState state_default; - private IntegerState state_init; + private IntegerState stateDefault; + private IntegerState stateInit; @Before @@ -24,62 +24,62 @@ public class IntegerStateTest { root = StateTestUtils.setUpRoot(); stack = root.getStateManager().getChangeStack(); - state_default = IntegerState.create(root, DEFAULT_ID); - state_init = IntegerState.create(root, INIT_ID, INIT); + stateDefault = IntegerState.create(root, DEFAULT_ID); + stateInit = IntegerState.create(root, INIT_ID, INIT); } @Test public void testValue() { - assertEquals(state_default.value(), 0); - assertEquals(state_init.value(), INIT); + assertEquals(stateDefault.value(), 0); + assertEquals(stateInit.value(), INIT); } @Test public void testSet() { - state_default.set(OTHER); - assertEquals(state_default.value(), OTHER); - state_init.set(0); - assertEquals(state_init.value(), 0); + stateDefault.set(OTHER); + assertEquals(stateDefault.value(), OTHER); + stateInit.set(0); + assertEquals(stateInit.value(), 0); } @Test public void testAdd() { - state_default.add(OTHER); - assertEquals(state_default.value(), OTHER); - state_init.add(OTHER); - assertEquals(state_init.value(), INIT + OTHER); + stateDefault.add(OTHER); + assertEquals(stateDefault.value(), OTHER); + stateInit.add(OTHER); + assertEquals(stateInit.value(), INIT + OTHER); } @Test public void testSetSameIgnored() { - state_default.set(0); - state_init.set((INIT)); + stateDefault.set(0); + stateInit.set((INIT)); stack.closeCurrentChangeSet(); - assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default, state_init); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(stateDefault, stateInit); } @Test public void testUndoRedo() { - state_default.set(INIT); - state_default.add(OTHER); + stateDefault.set(INIT); + stateDefault.add(OTHER); - state_init.add(OTHER); - state_init.set(0); + stateInit.add(OTHER); + stateInit.set(0); stack.closeCurrentChangeSet(); - assertEquals(state_default.value(), INIT+OTHER); - assertEquals(state_init.value(), 0); + assertEquals(stateDefault.value(), INIT+OTHER); + assertEquals(stateInit.value(), 0); stack.undo(); - assertEquals(state_default.value(), 0); - assertEquals(state_init.value(), INIT); + assertEquals(stateDefault.value(), 0); + assertEquals(stateInit.value(), INIT); stack.redo(); - assertEquals(state_default.value(), INIT+OTHER); - assertEquals(state_init.value(), 0); + assertEquals(stateDefault.value(), INIT+OTHER); + assertEquals(stateInit.value(), 0); } } diff --git a/junit/rails/game/state/StringStateTest.java b/junit/rails/game/state/StringStateTest.java index 814706d..31bff01 100644 --- a/junit/rails/game/state/StringStateTest.java +++ b/junit/rails/game/state/StringStateTest.java @@ -17,8 +17,8 @@ public class StringStateTest { private Root root; private ChangeStack stack; - private StringState state_default; - private StringState state_init; + private StringState stateDefault; + private StringState stateInit; @Before @@ -26,73 +26,73 @@ public class StringStateTest { root = StateTestUtils.setUpRoot(); stack = root.getStateManager().getChangeStack(); - state_default = StringState.create(root, DEFAULT_ID); - state_init = StringState.create(root, INIT_ID, INIT); + stateDefault = StringState.create(root, DEFAULT_ID); + stateInit = StringState.create(root, INIT_ID, INIT); } @Test public void testValue() { - assertEquals(state_default.value(), ""); - assertEquals(state_init.value(), INIT); + assertEquals(stateDefault.value(), ""); + assertEquals(stateInit.value(), INIT); } @Test public void testSet() { - state_default.set(OTHER); - assertEquals(state_default.value(), OTHER); - state_init.set(""); - assertEquals(state_init.value(), ""); - state_init.set(null); - assertEquals(state_init.value(), null); + stateDefault.set(OTHER); + assertEquals(stateDefault.value(), OTHER); + stateInit.set(""); + assertEquals(stateInit.value(), ""); + stateInit.set(null); + assertEquals(stateInit.value(), null); } @Test public void testAppend() { - state_default.append(OTHER, null); - assertEquals(state_default.value(), OTHER); - state_default.append(OTHER, ""); - assertEquals(state_default.value(), OTHER + OTHER); + stateDefault.append(OTHER, null); + assertEquals(stateDefault.value(), OTHER); + stateDefault.append(OTHER, ""); + assertEquals(stateDefault.value(), OTHER + OTHER); - state_init.append(OTHER, ","); - assertEquals(state_init.value(), INIT + "," + OTHER); + stateInit.append(OTHER, ","); + assertEquals(stateInit.value(), INIT + "," + OTHER); } @Test public void testSetSameIgnored() { - state_default.set(""); - state_init.set(null); + stateDefault.set(""); + stateInit.set(null); stack.closeCurrentChangeSet(); - assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default); - assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_init); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(stateDefault); + assertThat(stack.getLastClosedChangeSet().getStates()).contains(stateInit); - state_default.set(null); - state_init.set(null); + stateDefault.set(null); + stateInit.set(null); stack.closeCurrentChangeSet(); - assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default); - assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_init); + assertThat(stack.getLastClosedChangeSet().getStates()).contains(stateDefault); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(stateInit); } @Test public void testUndoRedo() { - state_default.set(OTHER); - state_default.append(OTHER, null); + stateDefault.set(OTHER); + stateDefault.append(OTHER, null); - state_init.append(OTHER, ""); - state_init.set(null); + stateInit.append(OTHER, ""); + stateInit.set(null); stack.closeCurrentChangeSet(); - assertEquals(state_default.value(), OTHER+OTHER); - assertNull(state_init.value()); + assertEquals(stateDefault.value(), OTHER+OTHER); + assertNull(stateInit.value()); stack.undo(); - assertEquals(state_default.value(), ""); - assertEquals(state_init.value(), INIT); + assertEquals(stateDefault.value(), ""); + assertEquals(stateInit.value(), INIT); stack.redo(); - assertEquals(state_default.value(), OTHER+OTHER); - assertNull(state_init.value()); + assertEquals(stateDefault.value(), OTHER+OTHER); + assertNull(stateInit.value()); } commit 24d0379866ab5428a071d255151025e4fafd7340 Author: Stefan Frey <ste...@we...> Date: Thu Jul 19 16:46:04 2012 +0200 added tests for HashMapState diff --git a/junit/rails/game/state/HashMapStateTest.java b/junit/rails/game/state/HashMapStateTest.java new file mode 100644 index 0000000..959e1f9 --- /dev/null +++ b/junit/rails/game/state/HashMapStateTest.java @@ -0,0 +1,177 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +public class HashMapStateTest { + + private final static String DEFAULT_ID = "Default"; + private final static String INIT_ID = "Init"; + + private final static String FIRST_ITEM_ID = "FirstItem"; + private final static String SECOND_ITEM_ID = "SecondItem"; + private final static String THIRD_ITEM_ID = "ThirdItem"; + + private Root root; + private ChangeStack stack; + private HashMapState<String, Item> state_default; + private HashMapState<String, Item> stateInit; + private Map<String, Item> initMap, testMap; + + private Item firstItem, secondItem, thirdItem; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + stack = root.getStateManager().getChangeStack(); + + firstItem = AbstractItemImpl.create(root, FIRST_ITEM_ID); + secondItem = AbstractItemImpl.create(root, SECOND_ITEM_ID); + thirdItem = AbstractItemImpl.create(root, THIRD_ITEM_ID); + + state_default = HashMapState.create(root, DEFAULT_ID); + + // intialize stateInit with initMap and create testMap + testMap = Maps.newHashMap(); + testMap.put(FIRST_ITEM_ID, firstItem); + initMap = ImmutableMap.copyOf(testMap); + stateInit = HashMapState.create(root, INIT_ID, testMap); + testMap.put(SECOND_ITEM_ID, secondItem); + } + + + @Test + public void testCreate() { + HashMapState<String, Item> state = HashMapState.create(root, "Test"); + assertThat(state.viewMap()).isEmpty(); + } + + @Test + public void testCreateMapOfKV() { + HashMapState<String, Item> state = HashMapState.create(root, "Test", testMap); + assertEquals(state.viewMap(), testMap); + } + + // helper function to check the initial state after undo + // includes redo, so after returning the state should be unchanged + private void assertInitialStateAfterUndo() { + stack.closeCurrentChangeSet(); + stack.undo(); + assertThat(state_default.viewMap()).isEmpty(); + assertEquals(stateInit.viewMap(), initMap); + stack.redo(); + } + + + @Test + public void testPut() { + for (String key: testMap.keySet()) { + state_default.put(key, testMap.get(key)); + stateInit.put(key, testMap.get(key)); + } + assertEquals(state_default.viewMap(), testMap); + assertEquals(stateInit.viewMap(), testMap); + + // check undo and redo + assertInitialStateAfterUndo(); + assertEquals(state_default.viewMap(), testMap); + assertEquals(stateInit.viewMap(), testMap); + } + + // includes tests for viewMap + @Test + public void testPutAll() { + stateInit.putAll(testMap); + state_default.putAll(testMap); + assertEquals(state_default.viewMap(), testMap); + assertEquals(stateInit.viewMap(), testMap); + + // check undo and redo + assertInitialStateAfterUndo(); + assertEquals(testMap, state_default.viewMap()); + assertEquals(testMap, stateInit.viewMap()); + } + + @Test + public void testGet() { + assertEquals(firstItem, stateInit.get(FIRST_ITEM_ID)); + assertNull(stateInit.get(SECOND_ITEM_ID)); + } + + @Test + public void testRemove() { + stateInit.remove(FIRST_ITEM_ID); + assertNull(stateInit.get(FIRST_ITEM_ID)); + + // check undo and redo + assertInitialStateAfterUndo(); + assertNull(stateInit.get(FIRST_ITEM_ID)); + } + + @Test + public void testContainsKey() { + state_default.put(THIRD_ITEM_ID, thirdItem); + assertTrue(state_default.containsKey(THIRD_ITEM_ID)); + + assertTrue(stateInit.containsKey(FIRST_ITEM_ID)); + assertFalse(stateInit.containsKey(SECOND_ITEM_ID)); + } + + @Test + public void testClear() { + state_default.putAll(testMap); + state_default.clear(); + assertTrue(state_default.isEmpty()); + + // check undo and redo + assertInitialStateAfterUndo(); + assertTrue(state_default.isEmpty()); + } + + @Test + public void testIsEmpty() { + assertTrue(state_default.isEmpty()); + state_default.put(FIRST_ITEM_ID, firstItem); + assertFalse(state_default.isEmpty()); + + assertFalse(stateInit.isEmpty()); + stateInit.remove(FIRST_ITEM_ID); + assertTrue(stateInit.isEmpty()); + } + + + @Test + public void testInitFromMap() { + state_default.put(THIRD_ITEM_ID, thirdItem); + state_default.initFromMap(testMap); + assertEquals(testMap, state_default.viewMap()); + + // check undo and redo + assertInitialStateAfterUndo(); + assertEquals(ImmutableMap.copyOf(testMap), state_default.viewMap()); + } + + @Test + public void testViewKeySet() { + state_default.putAll(testMap); + assertThat(state_default.viewKeySet()).containsAll(testMap.keySet()); + } + + @Test + public void testViewValues() { + state_default.putAll(testMap); + assertThat(state_default.viewValues()).containsAll(testMap.values()); + } + +} diff --git a/junit/rails/game/state/HashSetStateTest.java b/junit/rails/game/state/HashSetStateTest.java index 004b147..f30d078 100644 --- a/junit/rails/game/state/HashSetStateTest.java +++ b/junit/rails/game/state/HashSetStateTest.java @@ -3,10 +3,10 @@ package rails.game.state; import static org.fest.assertions.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.Iterator; +import java.util.Set; import org.junit.Before; @@ -135,9 +135,14 @@ public class HashSetStateTest { } private void assertTestIterator(Item thirdItem) { + // no order is defined, so store them + Set<Item> iterated = Sets.newHashSet(); + Iterator<Item> it = state_init.iterator(); - assertSame(oneItem,it.next()); - assertSame(anotherItem,it.next()); + iterated.add(it.next()); + iterated.add(it.next()); + + assertThat(iterated).containsOnly(oneItem, anotherItem); // iterator is finished assertFalse(it.hasNext()); // iterator is an immutable copy, thus not changed by adding a new item diff --git a/src/rails/game/state/HashMapState.java b/src/rails/game/state/HashMapState.java index ab4ae57..be193b1 100644 --- a/src/rails/game/state/HashMapState.java +++ b/src/rails/game/state/HashMapState.java @@ -8,8 +8,12 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import static com.google.common.base.Preconditions.checkNotNull; /** * A stateful version of a HashMap @@ -25,6 +29,7 @@ public final class HashMapState<K,V> extends State { } /** + * creates an empty HashMapState * @return empty HashMapState */ public static <K,V> HashMapState<K,V> create(Item parent, String id){ @@ -32,78 +37,132 @@ public final class HashMapState<K,V> extends State { } /** - * @return prefilled HashMapState + * creates an initialized (filled) HashMapState + * @param map used for initialization + * @return initialized HashMapState */ public static <K,V> HashMapState<K,V> create(Item parent, String id, Map<K,V> map){ return new HashMapState<K,V>(parent, id, map); } - public void put(K key, V value) { - // check if element already has the specified value - if (map.containsKey(key) && map.get(key).equals(value)) return; - new HashMapChange<K,V>(this, key, value); + /** + * Add key,value pair to map + * @param key for mapping + * @param value associated with key + * @return previous value associated with specified key, or null if there was no mapping for the key (or null was the value). + */ + public V put(K key, V value) { + // check if the key is in the map + if (map.containsKey(key)) { + V oldValue = map.get(key); + // check if element already has the specified value + if (!oldValue.equals(value)) { + new HashMapChange<K,V>(this, key, value); + } + return oldValue; + } else { + // if not in map, add tuple and return null + new HashMapChange<K,V>(this, key, value); + return null; + } } - + + /** + * Adds all (key,value) pairs + * @param map that gets added + * @throws NullPointerException if map is null + */ + public void putAll(Map<K,V> map) { + checkNotNull(map); for (K key:map.keySet()) { put(key, map.get(key)); } } - + + /** + * return value for specified key + * @param key used to retrieve value + * @return value associated with the key, null if map does not contain key + */ public V get(K key) { return map.get(key); } - public void remove(K key) { + /** + * removes key from mapping + * @param key to be removed from map + * @return value previously associated with key, null if map did not contain key + */ + public V remove(K key) { // check if map contains key - if (!map.containsKey(key)) return; + if (!map.containsKey(key)) return null; + V old = map.get(key); new HashMapChange<K,V>(this, key); + return old; } + /** + * test if key is present in mapping + * @param key whose presence is tested + * @return true if key is present + */ public boolean containsKey(K key) { return map.containsKey(key); } + /** + * removes all mappings from the map + */ public void clear() { - // Two-step process to avoid concurrent modification exception - List<K> keys = new ArrayList<K>(map.keySet()); - for (K key : keys) { + for (K key : ImmutableSet.copyOf(map.keySet())) { remove (key); } } /** - * (re)intializes the state map from another map + * checks if map is empty + * @return true if map is empty + */ + public boolean isEmpty() { + return map.isEmpty(); + } + + /** + * (re)initializes the state map from another map + * @param map used for initialization */ public void initFromMap(Map<K,V> initMap) { // all from initMap get added putAll(initMap); // remove those only in current map - for (K key:Sets.difference(map.keySet(), initMap.keySet())) { + for (K key:ImmutableSet.copyOf(Sets.difference(map.keySet(), initMap.keySet()))) { remove(key); } } /** - * @return unmodifiable view of map + * creates an immutable copy of the map + * @return immutable version of the map */ - public Map<K,V> viewMap() { - return Collections.unmodifiableMap(map); + public ImmutableMap<K,V> viewMap() { + return ImmutableMap.copyOf(map); } /** - * @return unmodifiable view of keyset + * creates an immutable copy of the keyset + * @return immutable keyset of the map */ - public Set<K> viewKeySet() { - return Collections.unmodifiableSet(map.keySet()); - } - - public Collection<V> viewValues() { - return Collections.unmodifiableCollection(map.values()); + public ImmutableSet<K> viewKeySet() { + return ImmutableSet.copyOf(map.keySet()); } - public boolean isEmpty() { - return map.isEmpty(); + /** + * creates an immutable copy of the values + * @return immutable list of values + */ + public ImmutableList<V> viewValues() { + return ImmutableList.copyOf(map.values()); } public String getData() { commit 80ad59a1182f0a841fb6c1ab945b3ebf4412478a Author: Stefan Frey <ste...@we...> Date: Thu Jul 19 11:05:49 2012 +0200 changed Change methods from public to default visibility diff --git a/src/rails/game/state/ArrayListChange.java b/src/rails/game/state/ArrayListChange.java index 832d387..54fa91f 100644 --- a/src/rails/game/state/ArrayListChange.java +++ b/src/rails/game/state/ArrayListChange.java @@ -32,18 +32,15 @@ final class ArrayListChange<E> extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(object, index, addToList); } - @Override - public void undo() { + @Override void undo() { state.change(object, index, !addToList); } - @Override - public ArrayListState<E> getState() { + @Override ArrayListState<E> getState() { return state; } diff --git a/src/rails/game/state/BooleanChange.java b/src/rails/game/state/BooleanChange.java index 824aeb7..6002069 100644 --- a/src/rails/game/state/BooleanChange.java +++ b/src/rails/game/state/BooleanChange.java @@ -17,18 +17,15 @@ final class BooleanChange extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(newValue); } - @Override - public void undo() { + @Override void undo() { state.change(oldValue); } - @Override - public BooleanState getState() { + @Override BooleanState getState() { return state; } diff --git a/src/rails/game/state/GenericStateChange.java b/src/rails/game/state/GenericStateChange.java index 86289ea..f6e1434 100644 --- a/src/rails/game/state/GenericStateChange.java +++ b/src/rails/game/state/GenericStateChange.java @@ -12,18 +12,15 @@ final class GenericStateChange<E> extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(next); } - @Override - public void undo() { + @Override void undo() { state.change(previous); } - @Override - public GenericState<E> getState() { + @Override GenericState<E> getState() { return state; } diff --git a/src/rails/game/state/HashMapChange.java b/src/rails/game/state/HashMapChange.java index c04edad..933a3c7 100644 --- a/src/rails/game/state/HashMapChange.java +++ b/src/rails/game/state/HashMapChange.java @@ -38,18 +38,15 @@ final class HashMapChange<K,V> extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(key, newValue, remove); } - @Override - public void undo() { + @Override void undo() { state.change(key, oldValue, !existed); } - @Override - public HashMapState<K,V> getState() { + @Override HashMapState<K,V> getState() { return state; } diff --git a/src/rails/game/state/HashSetChange.java b/src/rails/game/state/HashSetChange.java index 7f1c2d5..30f8bcb 100644 --- a/src/rails/game/state/HashSetChange.java +++ b/src/rails/game/state/HashSetChange.java @@ -18,18 +18,15 @@ final class HashSetChange<E> extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(element, addToSet); } - @Override - public void undo() { + @Override void undo() { state.change(element, !addToSet); } - @Override - public HashSetState<E> getState() { + @Override HashSetState<E> getState() { return state; } diff --git a/src/rails/game/state/IntegerChange.java b/src/rails/game/state/IntegerChange.java index b6e55e6..01d3030 100644 --- a/src/rails/game/state/IntegerChange.java +++ b/src/rails/game/state/IntegerChange.java @@ -16,18 +16,15 @@ final class IntegerChange extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(newValue); } - @Override - public void undo() { + @Override void undo() { state.change(oldValue); } - @Override - public IntegerState getState() { + @Override IntegerState getState() { return state; } diff --git a/src/rails/game/state/MultimapChange.java b/src/rails/game/state/MultimapChange.java index 2783a8f..36dcd5e 100644 --- a/src/rails/game/state/MultimapChange.java +++ b/src/rails/game/state/MultimapChange.java @@ -14,18 +14,15 @@ final class MultimapChange<K,V> extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(key, value, addToMap); } - @Override - public void undo() { + @Override void undo() { state.change(key, value, !addToMap); } - @Override - public MultimapState<K,V> getState() { + @Override MultimapState<K,V> getState() { return state; } diff --git a/src/rails/game/state/PortfolioChange.java b/src/rails/game/state/PortfolioChange.java index 5c3e21a..bb8624a 100644 --- a/src/rails/game/state/PortfolioChange.java +++ b/src/rails/game/state/PortfolioChange.java @@ -13,24 +13,21 @@ final class PortfolioChange<T extends Ownable<T>> extends Change { super.init(in); } - @Override - public void execute() { + @Override void execute() { in.change(item, true); if (out != null) { out.change(item, false); } } - @Override - public void undo() { + @Override void undo() { in.change(item, false); if (out != null) { out.change(item, true); } } - @Override - public Portfolio<? super T> getState() { + @Override Portfolio<? super T> getState() { return in; } diff --git a/src/rails/game/state/StringChange.java b/src/rails/game/state/StringChange.java index b1909e9..c327796 100644 --- a/src/rails/game/state/StringChange.java +++ b/src/rails/game/state/StringChange.java @@ -18,18 +18,15 @@ final class StringChange extends Change { super.init(state); } - @Override - public void execute() { + @Override void execute() { state.change(newValue); } - @Override - public void undo() { + @Override void undo() { state.change(oldValue); } - @Override - public StringState getState() { + @Override StringState getState() { return state; } diff --git a/src/rails/game/state/WalletChange.java b/src/rails/game/state/WalletChange.java index 6e3b089..62082ae 100644 --- a/src/rails/game/state/WalletChange.java +++ b/src/rails/game/state/WalletChange.java @@ -15,24 +15,21 @@ final class WalletChange<T extends CountableItem> extends Change { super.init(in); } - @Override - public void execute() { + @Override void execute() { in.change(item, amount); if (out != null) { out.change(item, - amount); } } - @Override - public void undo() { + @Override void undo() { in.change(item, - amount); if (out != null) { out.change(item, amount); } } - @Override - public Wallet<T> getState() { + @Override Wallet<T> getState() { return in; } commit 1a7522c88b0effb42bd6bce4dd3d80d7bee83c02 Author: Stefan Frey <ste...@we...> Date: Thu Jul 19 11:02:40 2012 +0200 added tests for HashSetState diff --git a/junit/rails/game/state/ArrayListStateTest.java b/junit/rails/game/state/ArrayListStateTest.java index 0745f7c..fb11df0 100644 --- a/junit/rails/game/state/ArrayListStateTest.java +++ b/junit/rails/game/state/ArrayListStateTest.java @@ -44,7 +44,9 @@ public class ArrayListStateTest { state_default = ArrayListState.create(root, DEFAULT_ID); state_init = ArrayListState.create(root, INIT_ID, Lists.newArrayList(oneItem)); } - + + // helper function to check the initial state after undo + // includes redo, so after returning the state should be unchanged private void assertInitialStateAfterUndo() { stack.closeCurrentChangeSet(); stack.undo(); @@ -168,6 +170,9 @@ public class ArrayListStateTest { state_init.add(anotherItem); state_init.clear(); assertTrue(state_init.isEmpty()); + // check undo and redo + assertInitialStateAfterUndo(); + assertTrue(state_init.isEmpty()); } @Test diff --git a/junit/rails/game/state/HashSetStateTest.java b/junit/rails/game/state/HashSetStateTest.java new file mode 100644 index 0000000..004b147 --- /dev/null +++ b/junit/rails/game/state/HashSetStateTest.java @@ -0,0 +1,161 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; + + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +public class HashSetStateTest { + + private final static String DEFAULT_ID = "Default"; + private final static String INIT_ID = "Init"; + + private final static String ONE_ITEM_ID = "OneItem"; + private final static String ANOTHER_ITEM_ID = "AnotherItem"; + + private Root root; + private ChangeStack stack; + private HashSetState<Item> state_default; + private HashSetState<Item> state_init; + + private Item oneItem; + private Item anotherItem; + + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + stack = root.getStateManager().getChangeStack(); + + oneItem = AbstractItemImpl.create(root, ONE_ITEM_ID); + anotherItem = AbstractItemImpl.create(root, ANOTHER_ITEM_ID); + + state_default = HashSetState.create(root, DEFAULT_ID); + state_init = HashSetState.create(root, INIT_ID, Sets.newHashSet(oneItem)); + } + + + @Test + public void testCreationWithList() { + // checks if the set is created with a list, that it only contains non-unique elements + HashSetState<Item> state = HashSetState.create(root, null, Lists.newArrayList(oneItem, oneItem)); + assertThat(state).containsOnly(oneItem); + assertThat(state).hasSize(1); + } + + // helper function to check the initial state after undo + // includes redo, so after returning the state should be unchanged + private void assertInitialStateAfterUndo() { + stack.closeCurrentChangeSet(); + stack.undo(); + assertEquals(state_default.view(), Sets.newHashSet()); + assertEquals(state_init.view(), Sets.newHashSet(oneItem)); + stack.redo(); + } + + private void assertTestAdd() { + assertThat(state_default).containsOnly(oneItem); + assertThat(state_init).containsOnly(oneItem, anotherItem); + } + + @Test + public void testAdd() { + state_default.add(oneItem); + state_init.add(anotherItem); + assertTestAdd(); + + // check undo + assertInitialStateAfterUndo(); + assertTestAdd(); + } + + @Test + public void testRemove() { + // rem |
From: Stefan F. <ste...@us...> - 2012-07-17 05:36:40
|
.project | 8 junit/rails/game/state/BooleanStateTest.java | 7 junit/rails/game/state/GenericStateTest.java | 33 - junit/rails/game/state/IntegerStateTest.java | 85 +++ junit/rails/game/state/StateTest.java | 8 junit/rails/game/state/StringStateTest.java | 99 ++++ src/rails/common/GuiHints.java | 4 src/rails/game/GameManager.java | 14 src/rails/game/OperatingRound.java | 366 ++++++++--------- src/rails/game/PhaseManager.java | 2 src/rails/game/PublicCompany.java | 8 src/rails/game/StartRound_1830.java | 6 src/rails/game/StockRound.java | 14 src/rails/game/Stop.java | 8 src/rails/game/Train.java | 6 src/rails/game/model/PriceModel.java | 6 src/rails/game/special/SellBonusToken.java | 2 src/rails/game/specific/_1825/StockRound_1825.java | 2 src/rails/game/specific/_1835/OperatingRound_1835.java | 14 src/rails/game/specific/_1835/StockRound_1835.java | 2 src/rails/game/specific/_1856/OperatingRound_1856.java | 128 ++--- src/rails/game/specific/_1856/PublicCompany_CGR.java | 2 src/rails/game/specific/_1880/StartRound_1880.java | 10 src/rails/game/specific/_1889/OperatingRound_1889.java | 2 src/rails/game/specific/_18AL/NameableTrain.java | 2 src/rails/game/specific/_18AL/OperatingRound_18AL.java | 10 src/rails/game/specific/_18EU/GameManager_18EU.java | 6 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 24 - src/rails/game/specific/_18EU/StartRound_18EU.java | 16 src/rails/game/specific/_18EU/StockRound_18EU.java | 4 src/rails/game/specific/_18GA/OperatingRound_18GA.java | 2 src/rails/game/specific/_18TN/OperatingRound_18TN.java | 4 src/rails/game/state/GenericState.java | 3 src/rails/game/state/GenericStateChange.java | 2 src/rails/game/state/IntegerState.java | 2 src/rails/game/state/StringState.java | 12 36 files changed, 562 insertions(+), 361 deletions(-) New commits: commit bded8d45322af638b3c80f244070adc00a620b4e Author: Stefan Frey <ste...@we...> Date: Mon Jul 16 15:47:52 2012 +0200 added state_id for init test state diff --git a/junit/rails/game/state/BooleanStateTest.java b/junit/rails/game/state/BooleanStateTest.java index 1e4b6f5..51427af 100644 --- a/junit/rails/game/state/BooleanStateTest.java +++ b/junit/rails/game/state/BooleanStateTest.java @@ -8,7 +8,8 @@ import org.junit.Test; public class BooleanStateTest { - private final static String STATE_ID = "Boolean"; + private final static String DEFAULT_ID = "Default"; + private final static String INIT_ID = "Init"; private Root root; private ChangeStack stack; @@ -18,8 +19,8 @@ public class BooleanStateTest { @Before public void setUp() { root = StateTestUtils.setUpRoot(); - state_default = BooleanState.create(root, STATE_ID); - state_init = BooleanState.create(root, null, true); + state_default = BooleanState.create(root, DEFAULT_ID); + state_init = BooleanState.create(root, INIT_ID, true); stack = root.getStateManager().getChangeStack(); } diff --git a/junit/rails/game/state/GenericStateTest.java b/junit/rails/game/state/GenericStateTest.java index cbceb30..aaccd90 100644 --- a/junit/rails/game/state/GenericStateTest.java +++ b/junit/rails/game/state/GenericStateTest.java @@ -8,7 +8,8 @@ import org.junit.Test; public class GenericStateTest { - private final static String STATE_ID = "Generic"; + private final static String DEFAULT_ID = "Default"; + private final static String INIT_ID = "Init"; private final static String ITEM_ID = "Item"; private final static String ANOTHER_ID = "Another"; @@ -27,8 +28,8 @@ public class GenericStateTest { item = new AbstractItemImpl(root, ITEM_ID); another_item = new AbstractItemImpl(root, ANOTHER_ID); - state_default = GenericState.create(root, STATE_ID); - state_init = GenericState.create(root, null, item); + state_default = GenericState.create(root, DEFAULT_ID); + state_init = GenericState.create(root, INIT_ID, item); } @Test diff --git a/junit/rails/game/state/IntegerStateTest.java b/junit/rails/game/state/IntegerStateTest.java index aaac06d..9c183a3 100644 --- a/junit/rails/game/state/IntegerStateTest.java +++ b/junit/rails/game/state/IntegerStateTest.java @@ -8,7 +8,8 @@ import org.junit.Test; public class IntegerStateTest { - private final static String STATE_ID = "Integer"; + private final static String DEFAULT_ID = "Default"; + private final static String INIT_ID = "Init"; private final static int INIT = 10; private final static int OTHER = -5; @@ -23,8 +24,8 @@ public class IntegerStateTest { root = StateTestUtils.setUpRoot(); stack = root.getStateManager().getChangeStack(); - state_default = IntegerState.create(root, STATE_ID); - state_init = IntegerState.create(root, null, INIT); + state_default = IntegerState.create(root, DEFAULT_ID); + state_init = IntegerState.create(root, INIT_ID, INIT); } @Test commit 88aa9f9c92c473d67ce216759534e0fbe90b2a2d Author: Stefan Frey <ste...@we...> Date: Mon Jul 16 15:45:42 2012 +0200 added tests for StringState diff --git a/junit/rails/game/state/IntegerStateTest.java b/junit/rails/game/state/IntegerStateTest.java index c09803e..aaac06d 100644 --- a/junit/rails/game/state/IntegerStateTest.java +++ b/junit/rails/game/state/IntegerStateTest.java @@ -25,7 +25,6 @@ public class IntegerStateTest { state_default = IntegerState.create(root, STATE_ID); state_init = IntegerState.create(root, null, INIT); - stack.closeCurrentChangeSet(); } @Test diff --git a/junit/rails/game/state/StringStateTest.java b/junit/rails/game/state/StringStateTest.java new file mode 100644 index 0000000..814706d --- /dev/null +++ b/junit/rails/game/state/StringStateTest.java @@ -0,0 +1,99 @@ +package rails.game.state; + + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; + +public class StringStateTest { + + private final static String DEFAULT_ID = "Default"; + private final static String INIT_ID = "Init"; + private final static String INIT = "INIT"; + private final static String OTHER = "OTHER"; + + private Root root; + private ChangeStack stack; + private StringState state_default; + private StringState state_init; + + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + stack = root.getStateManager().getChangeStack(); + + state_default = StringState.create(root, DEFAULT_ID); + state_init = StringState.create(root, INIT_ID, INIT); + } + + @Test + public void testValue() { + assertEquals(state_default.value(), ""); + assertEquals(state_init.value(), INIT); + } + + @Test + public void testSet() { + state_default.set(OTHER); + assertEquals(state_default.value(), OTHER); + state_init.set(""); + assertEquals(state_init.value(), ""); + state_init.set(null); + assertEquals(state_init.value(), null); + } + + @Test + public void testAppend() { + state_default.append(OTHER, null); + assertEquals(state_default.value(), OTHER); + state_default.append(OTHER, ""); + assertEquals(state_default.value(), OTHER + OTHER); + + state_init.append(OTHER, ","); + assertEquals(state_init.value(), INIT + "," + OTHER); + } + + + @Test + public void testSetSameIgnored() { + state_default.set(""); + state_init.set(null); + stack.closeCurrentChangeSet(); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default); + assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_init); + + state_default.set(null); + state_init.set(null); + stack.closeCurrentChangeSet(); + assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_init); + } + + @Test + public void testUndoRedo() { + + state_default.set(OTHER); + state_default.append(OTHER, null); + + state_init.append(OTHER, ""); + state_init.set(null); + stack.closeCurrentChangeSet(); + + assertEquals(state_default.value(), OTHER+OTHER); + assertNull(state_init.value()); + + stack.undo(); + assertEquals(state_default.value(), ""); + assertEquals(state_init.value(), INIT); + + stack.redo(); + assertEquals(state_default.value(), OTHER+OTHER); + assertNull(state_init.value()); + } + + +} diff --git a/src/rails/game/PublicCompany.java b/src/rails/game/PublicCompany.java index 683c471..ae98342 100644 --- a/src/rails/game/PublicCompany.java +++ b/src/rails/game/PublicCompany.java @@ -1644,7 +1644,7 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner, String tileLaid = "#" + tile.getExternalId() + "/" + hex.getId() + "/" + hex.getOrientationName(orientation); - tilesLaidThisTurn.appendWithDelimiter(tileLaid, ", "); + tilesLaidThisTurn.append(tileLaid, ", "); if (cost > 0) tilesCostThisTurn.change(cost); @@ -1655,7 +1655,7 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner, public void layTilenNoMapMode(int cost) { if (cost > 0) tilesCostThisTurn.change(cost); - tilesLaidThisTurn.appendWithDelimiter(Bank.format(cost), ","); + tilesLaidThisTurn.append(Bank.format(cost), ","); } public StringState getTilesLaidThisTurnModel() { @@ -1669,13 +1669,13 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner, public void layBaseToken(MapHex hex, int cost) { String tokenLaid = hex.getId(); - tokensLaidThisTurn.appendWithDelimiter(tokenLaid, ", "); + tokensLaidThisTurn.append(tokenLaid, ", "); if (cost > 0) tokensCostThisTurn.change(cost); } public void layBaseTokennNoMapMode(int cost) { if (cost > 0) tokensCostThisTurn.change(cost); - tokensLaidThisTurn.appendWithDelimiter(Bank.format(cost), ","); + tokensLaidThisTurn.append(Bank.format(cost), ","); } /** diff --git a/src/rails/game/state/StringState.java b/src/rails/game/state/StringState.java index 4cb7308..f069f19 100644 --- a/src/rails/game/state/StringState.java +++ b/src/rails/game/state/StringState.java @@ -27,7 +27,15 @@ public final class StringState extends State { } public void set(String value) { - new StringChange(this, value); + if (value == null) { + if (this.value != null) { + new StringChange(this, value); + } // otherwise both are null + } else { + if (this.value == null || !value.equals(this.value)) { + new StringChange(this, value); + } // otherwise the non-null current value is unequal to the new value + } } /** @@ -37,7 +45,7 @@ public final class StringState extends State { * @param value string to append * @param delimiter to use before appending (only for non-empty value) */ - public void appendWithDelimiter(String value, String delimiter) { + public void append(String value, String delimiter) { if (value == null || value.equals("") ) return; String newValue; commit e986c281fa5a2b55a74a02805e4478b076aec0e3 Author: Stefan Frey <ste...@we...> Date: Mon Jul 16 15:18:25 2012 +0200 added test for IntegerState, fixed missing check for identical values diff --git a/junit/rails/game/state/IntegerStateTest.java b/junit/rails/game/state/IntegerStateTest.java new file mode 100644 index 0000000..c09803e --- /dev/null +++ b/junit/rails/game/state/IntegerStateTest.java @@ -0,0 +1,85 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +public class IntegerStateTest { + + private final static String STATE_ID = "Integer"; + private final static int INIT = 10; + private final static int OTHER = -5; + + private Root root; + private ChangeStack stack; + private IntegerState state_default; + private IntegerState state_init; + + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + stack = root.getStateManager().getChangeStack(); + + state_default = IntegerState.create(root, STATE_ID); + state_init = IntegerState.create(root, null, INIT); + stack.closeCurrentChangeSet(); + } + + @Test + public void testValue() { + assertEquals(state_default.value(), 0); + assertEquals(state_init.value(), INIT); + } + + @Test + public void testSet() { + state_default.set(OTHER); + assertEquals(state_default.value(), OTHER); + state_init.set(0); + assertEquals(state_init.value(), 0); + + } + + @Test + public void testAdd() { + state_default.add(OTHER); + assertEquals(state_default.value(), OTHER); + state_init.add(OTHER); + assertEquals(state_init.value(), INIT + OTHER); + } + + + @Test + public void testSetSameIgnored() { + state_default.set(0); + state_init.set((INIT)); + stack.closeCurrentChangeSet(); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default, state_init); + } + + @Test + public void testUndoRedo() { + + state_default.set(INIT); + state_default.add(OTHER); + + state_init.add(OTHER); + state_init.set(0); + stack.closeCurrentChangeSet(); + + assertEquals(state_default.value(), INIT+OTHER); + assertEquals(state_init.value(), 0); + + stack.undo(); + assertEquals(state_default.value(), 0); + assertEquals(state_init.value(), INIT); + + stack.redo(); + assertEquals(state_default.value(), INIT+OTHER); + assertEquals(state_init.value(), 0); + } + +} diff --git a/junit/rails/game/state/StateTest.java b/junit/rails/game/state/StateTest.java index 0fb56a5..dcc2bef 100644 --- a/junit/rails/game/state/StateTest.java +++ b/junit/rails/game/state/StateTest.java @@ -46,9 +46,9 @@ public class StateTest { } @Test - public void testObserverText() { - assertNull(state.observerText()); - assertEquals(STATE_TEXT, state_wo_id.observerText()); - } + public void testObserverText() { + assertNull(state.observerText()); + assertEquals(STATE_TEXT, state_wo_id.observerText()); + } } diff --git a/src/rails/game/state/IntegerState.java b/src/rails/game/state/IntegerState.java index cb3286a..4a03f7e 100644 --- a/src/rails/game/state/IntegerState.java +++ b/src/rails/game/state/IntegerState.java @@ -27,7 +27,7 @@ public final class IntegerState extends State { } public void set(int value) { - new IntegerChange(this, value); + if (value != this.value) new IntegerChange(this, value); } public int add(int value) { commit 60f9ec44f5b48c01845eb7065d18fa80d73be3da Author: Stefan Frey <ste...@we...> Date: Mon Jul 16 14:48:23 2012 +0200 rename GenericState.get() to GenericState.value() diff --git a/.project b/.project index 8f28e06..a2abb72 100644 --- a/.project +++ b/.project @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <projectDescription> <name>Rails</name> - <comment></comment> + <comment>@key 32303037303533312D31303030205261696C732F6672657973746566 </comment> <projects> </projects> <buildSpec> @@ -10,10 +10,16 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>com.soyatec.additional.Builder</name> + <arguments> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.jem.workbench.JavaEMFNature</nature> <nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jem.beaninfo.BeanInfoNature</nature> + <nature>com.soyatec.additional.Nature</nature> </natures> </projectDescription> diff --git a/junit/rails/game/state/GenericStateTest.java b/junit/rails/game/state/GenericStateTest.java index 36926f9..cbceb30 100644 --- a/junit/rails/game/state/GenericStateTest.java +++ b/junit/rails/game/state/GenericStateTest.java @@ -33,18 +33,18 @@ public class GenericStateTest { @Test public void testValue() { - assertNull(state_default.get()); - assertSame(item, state_init.get()); + assertNull(state_default.value()); + assertSame(item, state_init.value()); } @Test public void testSet() { state_default.set(item); - assertSame(item, state_default.get()); + assertSame(item, state_default.value()); state_default.set(null); - assertNull(state_default.get()); + assertNull(state_default.value()); state_init.set(another_item); - assertSame(another_item, state_init.get()); + assertSame(another_item, state_init.value()); } @Test @@ -57,25 +57,25 @@ public class GenericStateTest { @Test public void testUndoRedo() { - assertNull(state_default.get()); - assertSame(item, state_init.get()); + assertNull(state_default.value()); + assertSame(item, state_init.value()); state_default.set(item); state_init.set(another_item); - assertSame(item, state_default.get()); - assertSame(another_item, state_init.get()); + assertSame(item, state_default.value()); + assertSame(another_item, state_init.value()); stack.closeCurrentChangeSet(); // remark: state_init is an internal (isObservable = false) assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default); stack.undo(); - assertNull(state_default.get()); - assertSame(item, state_init.get()); + assertNull(state_default.value()); + assertSame(item, state_init.value()); stack.redo(); - assertSame(item, state_default.get()); - assertSame(another_item, state_init.get()); + assertSame(item, state_default.value()); + assertSame(another_item, state_init.value()); } } diff --git a/src/rails/common/GuiHints.java b/src/rails/common/GuiHints.java index ddd3d1b..562af79 100644 --- a/src/rails/common/GuiHints.java +++ b/src/rails/common/GuiHints.java @@ -39,7 +39,7 @@ public final class GuiHints extends AbstractItem implements Serializable{ } public Class<? extends Round> getCurrentRoundType() { - return currentRoundType.get(); + return currentRoundType.value(); } public void setCurrentRoundType(Class<? extends Round> currentRoundType) { @@ -66,7 +66,7 @@ public final class GuiHints extends AbstractItem implements Serializable{ } public GuiDef.Panel getActivePanel() { - return (GuiDef.Panel)activePanel.get(); + return (GuiDef.Panel)activePanel.value(); } public void setActivePanel(GuiDef.Panel activePanel) { diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index 083fba6..6aea545 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -914,7 +914,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, // logging of game actions activated for (PossibleAction pa : possibleActions.getList()) { - log.debug(((Player) currentPlayer.get()).getId() + " may: " + log.debug(((Player) currentPlayer.value()).getId() + " may: " + pa.toString()); } @@ -1031,8 +1031,8 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, if (skipNextDone) { if (action instanceof NullAction && ((NullAction)action).getMode() == NullAction.DONE) { - if (currentRound.get() instanceof OperatingRound - && ((OperatingRound)currentRound.get()).getStep() == skippedStep) { + if (currentRound.value() instanceof OperatingRound + && ((OperatingRound)currentRound.value()).getStep() == skippedStep) { doProcess = false; } } @@ -1407,7 +1407,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, * @see rails.game.GameManager#getCurrentRound() */ public Round getCurrentRound() { - return (Round) currentRound.get(); + return (Round) currentRound.value(); } /* (non-Javadoc) @@ -1432,7 +1432,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, */ public void setCurrentPlayer(Player player) { // transfer messages for the next player to the display buffer - if ((Player)currentPlayer.get() != player && !nextPlayerMessages.isEmpty()) { + if ((Player)currentPlayer.value() != player && !nextPlayerMessages.isEmpty()) { DisplayBuffer.add( LocalText.getText("NextPlayerMessage", getCurrentPlayer().getId())); for (String s:nextPlayerMessages.view()) @@ -1465,14 +1465,14 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, * @see rails.game.GameManager#getPriorityPlayer() */ public Player getPriorityPlayer() { - return (Player) priorityPlayer.get(); + return (Player) priorityPlayer.value(); } /* (non-Javadoc) * @see rails.game.GameManager#getCurrentPlayer() */ public Player getCurrentPlayer() { - return (Player) currentPlayer.get(); + return (Player) currentPlayer.value(); } /* (non-Javadoc) diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java index b5b56ad..6596ade 100644 --- a/src/rails/game/OperatingRound.java +++ b/src/rails/game/OperatingRound.java @@ -232,10 +232,10 @@ public class OperatingRound extends Round implements Observer { if (action instanceof PossibleORAction && !(action instanceof DiscardTrain)) { PublicCompany company = ((PossibleORAction) action).getCompany(); - if (company != operatingCompany.get()) { + if (company != operatingCompany.value()) { DisplayBuffer.add(LocalText.getText("WrongCompany", company.getId(), - operatingCompany.get().getId() )); + operatingCompany.value().getId() )); return false; } } @@ -369,14 +369,14 @@ public class OperatingRound extends Round implements Observer { GameDef.OrStep step = getStep(); if (step == GameDef.OrStep.LAY_TRACK) { - if (!operatingCompany.get().hasLaidHomeBaseTokens()) { + if (!operatingCompany.value().hasLaidHomeBaseTokens()) { // This can occur if the home hex has two cities and track, // such as the green OO tile #59 // BR: as this is a home token, need to call LayBaseToken with a MapHex, not a list // to avoid the LayBaseToken action from being a regular token lay // I am not sure that this will work with multiple home hexes. - for (MapHex home : operatingCompany.get().getHomeHexes()) { + for (MapHex home : operatingCompany.value().getHomeHexes()) { possibleActions.add(new LayBaseToken (home) ); } forced = true; @@ -407,7 +407,7 @@ public class OperatingRound extends Round implements Observer { // || operatingCompany.getObject().getPortfolio().getNumberOfTrains() > 0) { doneAllowed = true; //} - if (noMapMode && (operatingCompany.get().getLastRevenue() == 0)) + if (noMapMode && (operatingCompany.value().getLastRevenue() == 0)) prepareNoMapActions(); } else if (step == GameDef.OrStep.DISCARD_TRAINS) { @@ -436,7 +436,7 @@ public class OperatingRound extends Round implements Observer { if (isPrivateSellingAllowed()) { // Create a list of players with the current one in front - int currentPlayerIndex = operatingCompany.get().getPresident().getIndex(); + int currentPlayerIndex = operatingCompany.value().getPresident().getIndex(); Player player; int minPrice, maxPrice; List<Player> players = getPlayers(); @@ -462,7 +462,7 @@ public class OperatingRound extends Round implements Observer { } } - if (operatingCompany.get().canUseSpecialProperties()) { + if (operatingCompany.value().canUseSpecialProperties()) { // Are there any "common" special properties, // i.e. properties that are available to everyone? @@ -473,8 +473,8 @@ public class OperatingRound extends Round implements Observer { if (sp instanceof SellBonusToken) { sbt = (SellBonusToken) sp; // Can't buy if already owned - if (operatingCompany.get().getBonuses() != null) { - for (Bonus bonus : operatingCompany.get().getBonuses()) { + if (operatingCompany.value().getBonuses() != null) { + for (Bonus bonus : operatingCompany.value().getBonuses()) { if (bonus.getName().equals(sp.getId())) continue loop; } } @@ -484,7 +484,7 @@ public class OperatingRound extends Round implements Observer { } // Are there other step-independent special properties owned by the company? - List<SpecialProperty> orsps = operatingCompany.get().getPortfolioModel().getAllSpecialProperties(); + List<SpecialProperty> orsps = operatingCompany.value().getPortfolioModel().getAllSpecialProperties(); // TODO: Do we still need this directly from the operating company? // List<SpecialProperty> compsps = operatingCompany.get().getSpecialProperties(); @@ -529,7 +529,7 @@ public class OperatingRound extends Round implements Observer { for (PossibleAction pa : possibleActions.getList()) { try { - log.debug(operatingCompany.get().getId() + " may: " + pa.toString()); + log.debug(operatingCompany.value().getId() + " may: " + pa.toString()); } catch (Exception e) { log.error("Error in toString() of " + pa.getClass(), e); } @@ -548,36 +548,36 @@ public class OperatingRound extends Round implements Observer { *=======================================*/ protected void initTurn() { - log.debug("Starting turn of "+operatingCompany.get().getId()); + log.debug("Starting turn of "+operatingCompany.value().getId()); ReportBuffer.add(" "); ReportBuffer.add(LocalText.getText("CompanyOperates", - operatingCompany.get().getId(), - operatingCompany.get().getPresident().getId())); - setCurrentPlayer(operatingCompany.get().getPresident()); + operatingCompany.value().getId(), + operatingCompany.value().getPresident().getId())); + setCurrentPlayer(operatingCompany.value().getPresident()); - if (noMapMode && !operatingCompany.get().hasLaidHomeBaseTokens()){ + if (noMapMode && !operatingCompany.value().hasLaidHomeBaseTokens()){ // Lay base token in noMapMode - BaseToken token = operatingCompany.get().getFreeToken(); + BaseToken token = operatingCompany.value().getFreeToken(); if (token == null) { - log.error("Company " + operatingCompany.get().getId() + " has no free token to lay base token"); + log.error("Company " + operatingCompany.value().getId() + " has no free token to lay base token"); } else { - log.debug("Company " + operatingCompany.get().getId() + " lays base token in nomap mode"); + log.debug("Company " + operatingCompany.value().getId() + " lays base token in nomap mode"); // FIXME: This has to be rewritten // Where are the nomap base tokens to be stored? // bank.getUnavailable().addBonusToken(token); } } - operatingCompany.get().initTurn(); + operatingCompany.value().initTurn(); trainsBoughtThisTurn.clear(); } protected void finishTurn() { - if (!operatingCompany.get().isClosed()) { - operatingCompany.get().setOperated(); - companiesOperatedThisRound.add(operatingCompany.get()); + if (!operatingCompany.value().isClosed()) { + operatingCompany.value().setOperated(); + companiesOperatedThisRound.add(operatingCompany.value()); - for (PrivateCompany priv : operatingCompany.get().getPortfolioModel().getPrivateCompanies()) { + for (PrivateCompany priv : operatingCompany.value().getPortfolioModel().getPrivateCompanies()) { priv.checkClosingIfExercised(true); } } @@ -603,18 +603,18 @@ public class OperatingRound extends Round implements Observer { protected boolean setNextOperatingCompany(boolean initial) { while (true) { - if (initial || operatingCompany.get() == null || operatingCompany == null) { + if (initial || operatingCompany.value() == null || operatingCompany == null) { setOperatingCompany(operatingCompanies.get(0)); initial = false; } else { - int index = operatingCompanies.indexOf(operatingCompany.get()); + int index = operatingCompanies.indexOf(operatingCompany.value()); if (++index >= operatingCompanies.size()) { return false; } // Check if the operating order has changed List<PublicCompany> newOperatingCompanies - = setOperatingCompanies (operatingCompanies.view(), operatingCompany.get()); + = setOperatingCompanies (operatingCompanies.view(), operatingCompany.value()); PublicCompany company; for (int i=0; i<newOperatingCompanies.size(); i++) { company = newOperatingCompanies.get(i); @@ -629,7 +629,7 @@ public class OperatingRound extends Round implements Observer { setOperatingCompany(operatingCompanies.get(index)); } - if (operatingCompany.get().isClosed()) continue; + if (operatingCompany.value().isClosed()) continue; return true; } @@ -645,7 +645,7 @@ public class OperatingRound extends Round implements Observer { * @return The currently operating company object. */ public PublicCompany getOperatingCompany() { - return operatingCompany.get(); + return operatingCompany.value(); } public List<PublicCompany> getOperatingCompanies() { @@ -668,7 +668,7 @@ public class OperatingRound extends Round implements Observer { * @return The number that defines the next action. */ public GameDef.OrStep getStep() { - return (GameDef.OrStep) stepObject.get(); + return (GameDef.OrStep) stepObject.value(); } /** @@ -697,7 +697,7 @@ public class OperatingRound extends Round implements Observer { /** Take the next step after a given one (see nextStep()) */ protected void nextStep(GameDef.OrStep step) { - PublicCompany company = operatingCompany.get(); + PublicCompany company = operatingCompany.value(); // Cycle through the steps until we reach one where a user action is // expected. @@ -795,7 +795,7 @@ public class OperatingRound extends Round implements Observer { * updateStatus(), which is called after each user action) */ protected void prepareStep() { - GameDef.OrStep step = stepObject.get(); + GameDef.OrStep step = stepObject.value(); if (step == GameDef.OrStep.LAY_TRACK) { // getNormalTileLays(); @@ -813,7 +813,7 @@ public class OperatingRound extends Round implements Observer { *=======================================*/ public void skip() { - log.debug("Skip step " + stepObject.get()); + log.debug("Skip step " + stepObject.value()); // TODO: Check if this is ok // FIXME: changeStack.start(true); nextStep(); @@ -827,8 +827,8 @@ public class OperatingRound extends Round implements Observer { */ public boolean done() { - if (operatingCompany.get().getPortfolioModel().getNumberOfTrains() == 0 - && operatingCompany.get().mustOwnATrain()) { + if (operatingCompany.value().getPortfolioModel().getNumberOfTrains() == 0 + && operatingCompany.value().mustOwnATrain()) { // FIXME: Need to check for valid route before throwing an // error. /* Check TEMPORARILY disabled @@ -918,7 +918,7 @@ public class OperatingRound extends Round implements Observer { // otherwise continue train buying if (!checkForExcessTrains()) { // Trains may have been discarded by other players - setCurrentPlayer (operatingCompany.get().getPresident()); + setCurrentPlayer (operatingCompany.value().getPresident()); stepObject.set(GameDef.OrStep.BUY_TRAIN); } @@ -1023,11 +1023,11 @@ public class OperatingRound extends Round implements Observer { break; } // Does the company have the money? - if (price > operatingCompany.get().getCash()) { + if (price > operatingCompany.value().getCash()) { errMsg = LocalText.getText("NotEnoughMoney", publicCompanyName, - Bank.format(operatingCompany.get().getCash()), + Bank.format(operatingCompany.value().getCash()), Bank.format(price) ); break; } @@ -1053,7 +1053,7 @@ public class OperatingRound extends Round implements Observer { // TODO: changeStack.start(true); - operatingCompany.get().buyPrivate(privateCompany, player.getPortfolioModel(), + operatingCompany.value().buyPrivate(privateCompany, player.getPortfolioModel(), price); return true; @@ -1075,7 +1075,7 @@ public class OperatingRound extends Round implements Observer { protected int getPrivateMaximumPrice (PrivateCompany privComp) { int maxPrice = privComp.getUpperPrice(); if (maxPrice == PrivateCompany.NO_PRICE_LIMIT) { - maxPrice = operatingCompany.get().getCash(); + maxPrice = operatingCompany.value().getCash(); } return maxPrice; } @@ -1191,7 +1191,7 @@ public class OperatingRound extends Round implements Observer { // Checks // Is company operating? - if (company != operatingCompany.get()) { + if (company != operatingCompany.value()) { errMsg = LocalText.getText("WrongCompany", companyName, @@ -1224,31 +1224,31 @@ public class OperatingRound extends Round implements Observer { int number = action.getNumberTaken(); int amount = calculateLoanAmount (number); - operatingCompany.get().addLoans(number); - MoneyModel.cashMove (bank, operatingCompany.get(), amount); + operatingCompany.value().addLoans(number); + MoneyModel.cashMove (bank, operatingCompany.value(), amount); if (number == 1) { ReportBuffer.add(LocalText.getText("CompanyTakesLoan", - operatingCompany.get().getId(), - Bank.format(operatingCompany.get().getValuePerLoan()), + operatingCompany.value().getId(), + Bank.format(operatingCompany.value().getValuePerLoan()), Bank.format(amount) )); } else { ReportBuffer.add(LocalText.getText("CompanyTakesLoans", - operatingCompany.get().getId(), + operatingCompany.value().getId(), number, - Bank.format(operatingCompany.get().getValuePerLoan()), + Bank.format(operatingCompany.value().getValuePerLoan()), Bank.format(amount) )); } - if (operatingCompany.get().getMaxLoansPerRound() > 0) { + if (operatingCompany.value().getMaxLoansPerRound() > 0) { int oldLoansThisRound = 0; if (loansThisRound == null) { loansThisRound = HashMapState.create(this, "loansThisRound"); - } else if (loansThisRound.containsKey(operatingCompany.get())){ - oldLoansThisRound = loansThisRound.get(operatingCompany.get()); + } else if (loansThisRound.containsKey(operatingCompany.value())){ + oldLoansThisRound = loansThisRound.get(operatingCompany.value()); } - loansThisRound.put(operatingCompany.get(), + loansThisRound.put(operatingCompany.value(), new Integer (oldLoansThisRound + number)); } } @@ -1267,11 +1267,11 @@ public class OperatingRound extends Round implements Observer { return false; } - int repayment = action.getNumberRepaid() * operatingCompany.get().getValuePerLoan(); - if (repayment > 0 && repayment > operatingCompany.get().getCash()) { + int repayment = action.getNumberRepaid() * operatingCompany.value().getValuePerLoan(); + if (repayment > 0 && repayment > operatingCompany.value().getCash()) { // President must contribute - int remainder = repayment - operatingCompany.get().getCash(); - Player president = operatingCompany.get().getPresident(); + int remainder = repayment - operatingCompany.value().getCash(); + Player president = operatingCompany.value().getPresident(); int presCash = president.getCashValue(); if (remainder > presCash) { // Start a share selling round @@ -1281,8 +1281,8 @@ public class OperatingRound extends Round implements Observer { log.info("President has $"+presCash+", so $"+cashToBeRaisedByPresident+" must be added"); savedAction = action; // TODO: changeStack.start(true); - gameManager.startShareSellingRound(operatingCompany.get().getPresident(), - cashToBeRaisedByPresident, operatingCompany.get(), false); + gameManager.startShareSellingRound(operatingCompany.value().getPresident(), + cashToBeRaisedByPresident, operatingCompany.value(), false); return true; } } @@ -1307,50 +1307,50 @@ public class OperatingRound extends Round implements Observer { int payment; int remainder = 0; - operatingCompany.get().addLoans(-number); - int amount = number * operatingCompany.get().getValuePerLoan(); - payment = Math.min(amount, operatingCompany.get().getCash()); + operatingCompany.value().addLoans(-number); + int amount = number * operatingCompany.value().getValuePerLoan(); + payment = Math.min(amount, operatingCompany.value().getCash()); remainder = amount - payment; if (payment > 0) { - MoneyModel.cashMove (operatingCompany.get(), bank, payment); + MoneyModel.cashMove (operatingCompany.value(), bank, payment); ReportBuffer.add (LocalText.getText("CompanyRepaysLoans", - operatingCompany.get().getId(), + operatingCompany.value().getId(), Bank.format(payment), Bank.format(amount), number, - Bank.format(operatingCompany.get().getValuePerLoan()))); + Bank.format(operatingCompany.value().getValuePerLoan()))); } if (remainder > 0) { - Player president = operatingCompany.get().getPresident(); + Player president = operatingCompany.value().getPresident(); if (president.getCashValue() >= remainder) { payment = remainder; MoneyModel.cashMove (president, bank, payment); ReportBuffer.add (LocalText.getText("CompanyRepaysLoansWithPresCash", - operatingCompany.get().getId(), + operatingCompany.value().getId(), Bank.format(payment), Bank.format(amount), number, - Bank.format(operatingCompany.get().getValuePerLoan()), + Bank.format(operatingCompany.value().getValuePerLoan()), president.getId())); } } } protected int calculateLoanAmount (int numberOfLoans) { - return numberOfLoans * operatingCompany.get().getValuePerLoan(); + return numberOfLoans * operatingCompany.value().getValuePerLoan(); } // TODO UNUSED?? public void payLoanInterest () { - int amount = operatingCompany.get().getCurrentLoanValue() - * operatingCompany.get().getLoanInterestPct() / 100; - MoneyModel.cashMove (operatingCompany.get(), bank, amount); + int amount = operatingCompany.value().getCurrentLoanValue() + * operatingCompany.value().getLoanInterestPct() / 100; + MoneyModel.cashMove (operatingCompany.value(), bank, amount); DisplayBuffer.add(LocalText.getText("CompanyPaysLoanInterest", - operatingCompany.get().getId(), + operatingCompany.value().getId(), Bank.format(amount), - operatingCompany.get().getLoanInterestPct(), - operatingCompany.get().getCurrentNumberOfLoans(), - Bank.format(operatingCompany.get().getValuePerLoan()))); + operatingCompany.value().getLoanInterestPct(), + operatingCompany.value().getCurrentNumberOfLoans(), + Bank.format(operatingCompany.value().getValuePerLoan()))); } /*======================================= @@ -1382,11 +1382,11 @@ public class OperatingRound extends Round implements Observer { // TODO: changeStack.start(true); - operatingCompany.get().setRight(rightName, rightValue); - MoneyModel.cashMove (operatingCompany.get(), bank, right.getCost()); + operatingCompany.value().setRight(rightName, rightValue); + MoneyModel.cashMove (operatingCompany.value(), bank, right.getCost()); ReportBuffer.add(LocalText.getText("BuysRight", - operatingCompany.get().getId(), + operatingCompany.value().getId(), rightName, Bank.format(right.getCost()))); @@ -1416,11 +1416,11 @@ public class OperatingRound extends Round implements Observer { while (true) { // Checks // Must be correct company. - if (!companyName.equals(operatingCompany.get().getId())) { + if (!companyName.equals(operatingCompany.value().getId())) { errMsg = LocalText.getText("WrongCompany", companyName, - operatingCompany.get().getId() ); + operatingCompany.value().getId() ); break; } // Must be correct step @@ -1495,11 +1495,11 @@ public class OperatingRound extends Round implements Observer { break; } // Does the company have the money? - if (cost > operatingCompany.get().getCash()) { + if (cost > operatingCompany.value().getCash()) { errMsg = LocalText.getText("NotEnoughMoney", companyName, - Bank.format(operatingCompany.get().getCash()), + Bank.format(operatingCompany.value().getCash()), Bank.format(cost) ); break; } @@ -1520,8 +1520,8 @@ public class OperatingRound extends Round implements Observer { if (tile != null) { if (cost > 0) - MoneyModel.cashMove(operatingCompany.get(), bank, cost); - operatingCompany.get().layTile(hex, tile, orientation, cost); + MoneyModel.cashMove(operatingCompany.value(), bank, cost); + operatingCompany.value().layTile(hex, tile, orientation, cost); if (cost == 0) { ReportBuffer.add(LocalText.getText("LaysTileAt", @@ -1628,7 +1628,7 @@ public class OperatingRound extends Round implements Observer { // duplicate the phase colours Map<String, Integer> newTileColours = new HashMap<String, Integer>(getCurrentPhase().getTileColours()); for (String colour : newTileColours.keySet()) { - int allowedNumber = operatingCompany.get().getNumberOfTileLays(colour); + int allowedNumber = operatingCompany.value().getNumberOfTileLays(colour); // Replace the null map value with the allowed number of lays newTileColours.put(colour, new Integer(allowedNumber)); } @@ -1679,7 +1679,7 @@ public class OperatingRound extends Round implements Observer { /* Special-property tile lays */ List<LayTile> currentSpecialTileLays = new ArrayList<LayTile>(); - if (operatingCompany.get().canUseSpecialProperties()) { + if (operatingCompany.value().canUseSpecialProperties()) { for (SpecialTileLay stl : getSpecialProperties(SpecialTileLay.class)) { if (stl.isExtra() @@ -1750,7 +1750,7 @@ public class OperatingRound extends Round implements Observer { MapHex hex = action.getChosenHex(); int station = action.getChosenStation(); - String companyName = operatingCompany.get().getId(); + String companyName = operatingCompany.value().getId(); // Dummy loop to enable a quick jump out. while (true) { @@ -1764,12 +1764,12 @@ public class OperatingRound extends Round implements Observer { break; } - if (operatingCompany.get().getNumberOfFreeBaseTokens() == 0) { + if (operatingCompany.value().getNumberOfFreeBaseTokens() == 0) { errMsg = LocalText.getText("HasNoTokensLeft", companyName); break; } - if (!isTokenLayAllowed (operatingCompany.get(), hex, station)) { + if (!isTokenLayAllowed (operatingCompany.value(), hex, station)) { errMsg = LocalText.getText("BaseTokenSlotIsReserved"); break; } @@ -1784,7 +1784,7 @@ public class OperatingRound extends Round implements Observer { * cities on one tile may hold tokens of the same company; this case * is not yet covered. */ - if (hex.hasTokenOfCompany(operatingCompany.get())) { + if (hex.hasTokenOfCompany(operatingCompany.value())) { errMsg = LocalText.getText("TileAlreadyHasToken", hex.getId(), @@ -1806,14 +1806,14 @@ public class OperatingRound extends Round implements Observer { if (stl != null) extra = stl.isExtra(); } - cost = operatingCompany.get().getBaseTokenLayCost(hex); + cost = operatingCompany.value().getBaseTokenLayCost(hex); if (stl != null && stl.isFree()) cost = 0; // Does the company have the money? - if (cost > operatingCompany.get().getCash()) { + if (cost > operatingCompany.value().getCash()) { errMsg = LocalText.getText("NotEnoughMoney", companyName, - Bank.format(operatingCompany.get().getCash()), + Bank.format(operatingCompany.value().getCash()), Bank.format(cost)); break; } @@ -1831,10 +1831,10 @@ public class OperatingRound extends Round implements Observer { /* End of validation, start of execution */ // TODO: changeStack.start(true); - if (hex.layBaseToken(operatingCompany.get(), station)) { + if (hex.layBaseToken(operatingCompany.value(), station)) { /* TODO: the false return value must be impossible. */ - operatingCompany.get().layBaseToken(hex, cost); + operatingCompany.value().layBaseToken(hex, cost); // If this is a home base token lay, stop here if (action.getType() == LayBaseToken.HOME_CITY) { @@ -1842,7 +1842,7 @@ public class OperatingRound extends Round implements Observer { } if (cost > 0) { - MoneyModel.cashMove(operatingCompany.get(), bank, cost); + MoneyModel.cashMove(operatingCompany.value(), bank, cost); ReportBuffer.add(LocalText.getText("LAYS_TOKEN_ON", companyName, hex.getId(), @@ -1872,7 +1872,7 @@ public class OperatingRound extends Round implements Observer { if (currentNormalTokenLays.isEmpty()) { log.debug("No more normal token lays are allowed"); - } else if (operatingCompany.get().getNumberOfFreeBaseTokens() == 0) { + } else if (operatingCompany.value().getNumberOfFreeBaseTokens() == 0) { log.debug("Normal token lay allowed by no more tokens"); currentNormalTokenLays.clear(); } else { @@ -1916,7 +1916,7 @@ public class OperatingRound extends Round implements Observer { currentNormalTokenLays.clear(); /* For now, we allow one token of the currently operating company */ - if (operatingCompany.get().getNumberOfFreeBaseTokens() > 0) { + if (operatingCompany.value().getNumberOfFreeBaseTokens() > 0) { currentNormalTokenLays.add(new LayBaseToken((List<MapHex>) null)); } @@ -1933,13 +1933,13 @@ public class OperatingRound extends Round implements Observer { /* Special-property tile lays */ currentSpecialTokenLays.clear(); - if (!operatingCompany.get().canUseSpecialProperties()) return; + if (!operatingCompany.value().canUseSpecialProperties()) return; /* * In 1835, this only applies to major companies. TODO: For now, * hardcode this, but it must become configurable later. */ - if (operatingCompany.get().getType().getId().equals("Minor")) return; + if (operatingCompany.value().getType().getId().equals("Minor")) return; for (SpecialTokenLay stl : getSpecialProperties(SpecialTokenLay.class)) { log.debug("Spec.prop:" + stl); @@ -1988,10 +1988,10 @@ public class OperatingRound extends Round implements Observer { if (stl != null && stl.isFree()) cost = 0; // Does the company have the money? - if (cost > operatingCompany.get().getCash()) { + if (cost > operatingCompany.value().getCash()) { errMsg = LocalText.getText("NotEnoughMoney", - operatingCompany.get().getId()); + operatingCompany.value().getId()); break; } break; @@ -2011,13 +2011,13 @@ public class OperatingRound extends Round implements Observer { if (hex.layBonusToken(token, gameManager.getPhaseManager())) { /* TODO: the false return value must be impossible. */ - operatingCompany.get().addBonus(new Bonus(operatingCompany.get(), + operatingCompany.value().addBonus(new Bonus(operatingCompany.value(), token.getId(), token.getValue(), Collections.singletonList(hex))); - token.setUser(operatingCompany.get()); + token.setUser(operatingCompany.value()); ReportBuffer.add(LocalText.getText("LaysBonusTokenOn", - operatingCompany.get().getId(), + operatingCompany.value().getId(), token.getId(), Bank.format(token.getValue()), hex.getId() )); @@ -2052,11 +2052,11 @@ public class OperatingRound extends Round implements Observer { seller = (CashOwner)sbt.getSeller(); // TODO: Remove the cast? // Does the company have the money? - if (cost > operatingCompany.get().getCash()) { + if (cost > operatingCompany.value().getCash()) { errMsg = LocalText.getText("NotEnoughMoney", - operatingCompany.get().getId(), - Bank.format(operatingCompany.get().getCash()), + operatingCompany.value().getId(), + Bank.format(operatingCompany.value().getCash()), Bank.format(cost)); break; } @@ -2064,7 +2064,7 @@ public class OperatingRound extends Round implements Observer { } if (errMsg != null) { DisplayBuffer.add(LocalText.getText("CannotBuyBonusToken", - operatingCompany.get().getId(), + operatingCompany.value().getId(), sbt.getId(), seller.getId(), Bank.format(cost), @@ -2075,14 +2075,14 @@ public class OperatingRound extends Round implements Observer { /* End of validation, start of execution */ // TODO: changeStack.start(true); - MoneyModel.cashMove(operatingCompany.get(), seller, cost); - operatingCompany.get().addBonus(new Bonus(operatingCompany.get(), + MoneyModel.cashMove(operatingCompany.value(), seller, cost); + operatingCompany.value().addBonus(new Bonus(operatingCompany.value(), sbt.getId(), sbt.getValue(), sbt.getLocations())); ReportBuffer.add(LocalText.getText("BuysBonusTokenFrom", - operatingCompany.get().getId(), + operatingCompany.value().getId(), sbt.getId(), Bank.format(sbt.getValue()), seller.getId(), @@ -2160,11 +2160,11 @@ public class OperatingRound extends Round implements Observer { // Must be correct company. company = action.getCompany(); companyName = company.getId(); - if (company != operatingCompany.get()) { + if (company != operatingCompany.value()) { errMsg = LocalText.getText("WrongCompany", companyName, - operatingCompany.get().getId() ); + operatingCompany.value().getId() ); break; } // Must be correct step @@ -2220,9 +2220,9 @@ public class OperatingRound extends Round implements Observer { action.setRevenueAllocation(SetDividend.WITHHOLD); } - if (amount == 0 && operatingCompany.get().getNumberOfTrains() == 0) { + if (amount == 0 && operatingCompany.value().getNumberOfTrains() == 0) { DisplayBuffer.add(LocalText.getText("RevenueWithNoTrains", - operatingCompany.get().getId(), + operatingCompany.value().getId(), Bank.format(0) )); } @@ -2237,8 +2237,8 @@ public class OperatingRound extends Round implements Observer { int amount = action.getActualRevenue(); int revenueAllocation = action.getRevenueAllocation(); - operatingCompany.get().setLastRevenue(amount); - operatingCompany.get().setLastRevenueAllocation(revenueAllocation); + operatingCompany.value().setLastRevenue(amount); + operatingCompany.value().setLastRevenueAllocation(revenueAllocation); // Pay any debts from treasury, revenue and/or president's cash // The remaining dividend may be less that the original income @@ -2247,27 +2247,27 @@ public class OperatingRound extends Round implements Observer { if (amount == 0) { ReportBuffer.add(LocalText.getText("CompanyDoesNotPayDividend", - operatingCompany.get().getId())); + operatingCompany.value().getId())); withhold(amount); } else if (revenueAllocation == SetDividend.PAYOUT) { ReportBuffer.add(LocalText.getText("CompanyPaysOutFull", - operatingCompany.get().getId(), Bank.format(amount) )); + operatingCompany.value().getId(), Bank.format(amount) )); payout(amount); } else if (revenueAllocation == SetDividend.SPLIT) { ReportBuffer.add(LocalText.getText("CompanySplits", - operatingCompany.get().getId(), Bank.format(amount) )); + operatingCompany.value().getId(), Bank.format(amount) )); splitRevenue(amount); } else if (revenueAllocation == SetDividend.WITHHOLD) { ReportBuffer.add(LocalText.getText("CompanyWithholds", - operatingCompany.get().getId(), + operatingCompany.value().getId(), Bank.format(amount) )); withhold(amount); @@ -2275,7 +2275,7 @@ public class OperatingRound extends Round implements Observer { } // Rust any obsolete trains - operatingCompany.get().getPortfolioModel().rustObsoleteTrains(); + operatingCompany.value().getPortfolioModel().rustObsoleteTrains(); // We have done the payout step, so continue from there nextStep(GameDef.OrStep.PAYOUT); @@ -2303,17 +2303,17 @@ public class OperatingRound extends Round implements Observer { if (recipient instanceof Bank) continue; shares = (sharesPerRecipient.get(recipient)); if (shares == 0) continue; - part = (int) Math.ceil(amount * shares * operatingCompany.get().getShareUnit() / 100.0); + part = (int) Math.ceil(amount * shares * operatingCompany.value().getShareUnit() / 100.0); ReportBuffer.add(LocalText.getText("Payout", ... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-07-11 18:25:43
|
junit/rails/game/state/FormatterTest.java | 54 +++++++++++++------ junit/rails/game/state/GenericStateTest.java | 3 - junit/rails/game/state/ObservableTest.java | 2 junit/rails/game/state/ObserverTest.java | 37 +++++++++++++ junit/rails/game/state/StateTest.java | 8 +- src/rails/game/GameManager.java | 2 src/rails/game/OperatingRound.java | 2 src/rails/game/PublicCompany.java | 2 src/rails/game/model/PresidentModel.java | 11 --- src/rails/game/state/Change.java | 2 src/rails/game/state/ChangeSet.java | 12 +++- src/rails/game/state/ChangeStack.java | 28 ++++++++-- src/rails/game/state/Formatter.java | 22 ++++++- src/rails/game/state/Model.java | 31 ++++++----- src/rails/game/state/Observable.java | 35 ++++++------ src/rails/game/state/Observer.java | 2 src/rails/game/state/Root.java | 13 ++-- src/rails/game/state/State.java | 32 ++--------- src/rails/game/state/StateManager.java | 70 ++++++++++++++++++++++++- src/rails/ui/swing/GridPanel.java | 2 src/rails/ui/swing/elements/Field.java | 4 - src/rails/ui/swing/elements/GUIStockSpace.java | 3 - src/rails/ui/swing/hexmap/GUIHex.java | 9 --- 23 files changed, 260 insertions(+), 126 deletions(-) New commits: commit afd1a0667ca3e872149f6657eec7e9b676338f70 Author: Stefan Frey <ste...@we...> Date: Wed Jul 11 11:35:02 2012 +0200 refactored Observer and Formatter classes diff --git a/junit/rails/game/state/FormatterTest.java b/junit/rails/game/state/FormatterTest.java index 626f0be..51f6b48 100644 --- a/junit/rails/game/state/FormatterTest.java +++ b/junit/rails/game/state/FormatterTest.java @@ -1,40 +1,60 @@ package rails.game.state; -import static org.junit.Assert.*; +import static org.mockito.Mockito.*; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +@RunWith(MockitoJUnitRunner.class) public class FormatterTest { + + private static final String YES = "yes"; + private static final String NO = "no"; // This formatter doubles the text of the state - private class FormatterImpl implements Formatter<State> { - public String formatValue(State state) { - return state.toString() + state.toString(); + private class FormatterImpl extends Formatter<BooleanState> { + private final BooleanState state; + private FormatterImpl(BooleanState state){ + super(state); + this.state = state; + } + public String observerText() { + if (state.value()) { + return YES; + } else { + return NO; + } } } private final static String STATE_ID = "State"; - private final static String STATE_TEXT = "Test"; private Root root; - private State state; - private Formatter<State> formatter; - + private BooleanState state; + private Formatter<BooleanState> formatter; + @Mock private Observer observer; + @Before public void setUp() { - root = Root.create(); - state = new StateImpl(root, STATE_ID, STATE_TEXT); - formatter = new FormatterImpl(); + root = StateTestUtils.setUpRoot(); + state = BooleanState.create(root, STATE_ID); + formatter = new FormatterImpl(state); + formatter.addObserver(observer); } @Test public void testFormatValue() { - assertEquals(STATE_TEXT, state.getText()); - state.setFormatter(formatter); - assertEquals(STATE_TEXT + STATE_TEXT, state.getText()); - state.setFormatter(null); - assertEquals(STATE_TEXT, state.getText()); - } + state.set(true); + root.getStateManager().getChangeStack().closeCurrentChangeSet(); + state.set(false); + root.getStateManager().getChangeStack().closeCurrentChangeSet(); + InOrder inOrder = inOrder(observer); + inOrder.verify(observer).update(YES); + inOrder.verify(observer).update(NO); + } } diff --git a/junit/rails/game/state/GenericStateTest.java b/junit/rails/game/state/GenericStateTest.java index c25424c..36926f9 100644 --- a/junit/rails/game/state/GenericStateTest.java +++ b/junit/rails/game/state/GenericStateTest.java @@ -66,7 +66,8 @@ public class GenericStateTest { assertSame(another_item, state_init.get()); stack.closeCurrentChangeSet(); - assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default, state_init); + // remark: state_init is an internal (isObservable = false) + assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default); stack.undo(); assertNull(state_default.get()); diff --git a/junit/rails/game/state/ObservableTest.java b/junit/rails/game/state/ObservableTest.java index 2e2000b..98d96f3 100644 --- a/junit/rails/game/state/ObservableTest.java +++ b/junit/rails/game/state/ObservableTest.java @@ -20,7 +20,7 @@ public class ObservableTest { } @Override - public String getText() { + public String observerText() { return null; } } diff --git a/junit/rails/game/state/ObserverTest.java b/junit/rails/game/state/ObserverTest.java new file mode 100644 index 0000000..94b0671 --- /dev/null +++ b/junit/rails/game/state/ObserverTest.java @@ -0,0 +1,37 @@ +package rails.game.state; + +import static org.mockito.Mockito.*; +import static org.fest.assertions.api.Assertions.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ObserverTest { + + private final static String STATE_ID = "State"; + + private Root root; + private BooleanState state; + @Mock private Observer observer; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + state = BooleanState.create(root, STATE_ID, false); + state.addObserver(observer); + } + + @Test + public void testUpdate() { + assertThat(state.getObservers()).contains(observer); + state.set(true); + verify(observer, never()).update(state.observerText()); + root.getStateManager().getChangeStack().closeCurrentChangeSet(); + verify(observer).update(state.observerText()); + } + +} diff --git a/junit/rails/game/state/StateTest.java b/junit/rails/game/state/StateTest.java index 61bffab..0fb56a5 100644 --- a/junit/rails/game/state/StateTest.java +++ b/junit/rails/game/state/StateTest.java @@ -46,9 +46,9 @@ public class StateTest { } @Test - public void testGetText() { - assertNull(state.getText()); - assertEquals(STATE_TEXT, state_wo_id.getText()); - } + public void testObserverText() { + assertNull(state.observerText()); + assertEquals(STATE_TEXT, state_wo_id.observerText()); + } } diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index acb3453..083fba6 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -782,7 +782,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, } public String getNumOfORs () { - return numOfORs.getText(); + return numOfORs.observerText(); } /* (non-Javadoc) diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java index 50becdd..b5b56ad 100644 --- a/src/rails/game/OperatingRound.java +++ b/src/rails/game/OperatingRound.java @@ -3124,7 +3124,7 @@ public class OperatingRound extends Round implements Observer { /** * Update the status if the step has changed by an Undo or Redo */ - public void update(Observable observable, String text) { + public void update(String text) { prepareStep(); } diff --git a/src/rails/game/PublicCompany.java b/src/rails/game/PublicCompany.java index 30f7527..683c471 100644 --- a/src/rails/game/PublicCompany.java +++ b/src/rails/game/PublicCompany.java @@ -1191,7 +1191,7 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner, } public String getFormattedCash() { - return treasury.getText(); + return treasury.observerText(); } public Model getText() { diff --git a/src/rails/game/model/PresidentModel.java b/src/rails/game/model/PresidentModel.java index 0f7cbb4..f167c72 100644 --- a/src/rails/game/model/PresidentModel.java +++ b/src/rails/game/model/PresidentModel.java @@ -3,18 +3,16 @@ package rails.game.model; import rails.game.Player; import rails.game.PublicCompany; import rails.game.state.Model; -import rails.game.state.Observable; -import rails.game.state.Observer; /** * model object for the current company president * gets registered by the ShareModels * - * FIXME: Finalize implementation + * FIXME: Finalize implementation, this does not work currently * TODO: Check if this is all done correctly, where is the observable stored? */ -public final class PresidentModel extends Model implements Observer { +public final class PresidentModel extends Model { public static final String ID = "PresidentModel"; @@ -43,9 +41,4 @@ public final class PresidentModel extends Model implements Observer { else return company.getPresident().getNameAndPriority(); } - // FIXME: Add code what to do here - public void update(Observable observable, String text) { - - } - } diff --git a/src/rails/game/state/Change.java b/src/rails/game/state/Change.java index eecaafc..c01bdcb 100644 --- a/src/rails/game/state/Change.java +++ b/src/rails/game/state/Change.java @@ -7,7 +7,7 @@ package rails.game.state; abstract class Change { protected void init(State state){ - state.getRoot().getStateManager().getChangeStack().getCurrentChangeSet().addChange(this); + state.getStateManager().getChangeStack().getCurrentChangeSet().addChange(this); } abstract void execute(); diff --git a/src/rails/game/state/ChangeSet.java b/src/rails/game/state/ChangeSet.java index d57c599..5c4d0c3 100644 --- a/src/rails/game/state/ChangeSet.java +++ b/src/rails/game/state/ChangeSet.java @@ -58,7 +58,9 @@ abstract class ChangeSet { private void defineStates() { ImmutableSet.Builder<State> builder = new ImmutableSet.Builder<State>(); for (Change change:changes) { - builder.add(change.getState()); + if (change.getState().isObservable()){ + builder.add(change.getState()); + } } states = builder.build(); } @@ -92,8 +94,16 @@ abstract class ChangeSet { abstract boolean isTerminal(); + /** + * @return set of States in the ChangeSet + * Remark: It only includes those which are observable (isObservable = true) + */ ImmutableSet<State> getStates() { if (!closed) throw new IllegalStateException("ChangeSet is still open"); return states; } + + + + } diff --git a/src/rails/game/state/ChangeStack.java b/src/rails/game/state/ChangeStack.java index b3585e6..0d2687a 100644 --- a/src/rails/game/state/ChangeStack.java +++ b/src/rails/game/state/ChangeStack.java @@ -2,10 +2,14 @@ package rails.game.state; import java.util.ArrayDeque; import java.util.Deque; +import java.util.HashSet; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Sets; + import rails.game.Player; import rails.game.action.PossibleAction; @@ -18,12 +22,16 @@ public class ChangeStack { private final Deque<ChangeSet> undoStack = new ArrayDeque<ChangeSet>(); private final Deque<ChangeSet> redoStack = new ArrayDeque<ChangeSet>(); + private final StateManager stateManager; + private ChangeSet currentSet; - private ChangeStack() {}; + private ChangeStack(StateManager stateManager) { + this.stateManager = stateManager; + } - public static ChangeStack create() { - ChangeStack changeStack = new ChangeStack(); + public static ChangeStack create(StateManager stateManager) { + ChangeStack changeStack = new ChangeStack(stateManager); changeStack.startAutoChangeSet(true); // first set is terminal return changeStack; } @@ -50,6 +58,8 @@ public class ChangeStack { return false; } else { currentSet.close(); + // FIXME: This is a hack, has to replaced + updateObservers(Sets.newHashSet(currentSet)); } undoStack.addFirst(currentSet); return true; @@ -139,11 +149,21 @@ public class ChangeStack { } /** + * Update the relevant observers + */ + private void updateObservers(Set<ChangeSet> changeSets) { + Set<State> states = Sets.newHashSet(); + for (ChangeSet cs:changeSets) { + states.addAll(cs.getStates()); + } + stateManager.updateObservers(states); + } + + /** * @return size of ChangeStack */ public int sizeUndoStack() { return undoStack.size(); } - } diff --git a/src/rails/game/state/Formatter.java b/src/rails/game/state/Formatter.java index 223fab8..c0b5ab5 100644 --- a/src/rails/game/state/Formatter.java +++ b/src/rails/game/state/Formatter.java @@ -1,9 +1,23 @@ package rails.game.state; /** - * An interface defining a formatter for a state variable - * @author freystef + * Abstract class for a Formatter */ -public interface Formatter<E extends State> { - public String formatValue(E state); +public abstract class Formatter<T extends Observable> { + + private final T observable; + + protected Formatter(T observable) { + this.observable = observable; + } + + public abstract String observerText(); + + public void addObserver(Observer observer) { + observable.getStateManager().addObserver(observer, this); + } + + public T getObservable() { + return observable; + } } diff --git a/src/rails/game/state/Model.java b/src/rails/game/state/Model.java index d774e11..2143924 100644 --- a/src/rails/game/state/Model.java +++ b/src/rails/game/state/Model.java @@ -1,6 +1,5 @@ package rails.game.state; - /** * Model is an abstract generic class * that defines the a middle layer between State(s) and @@ -8,14 +7,12 @@ package rails.game.state; * * Models themselves can be layered upon each other. * - * * It replaces the ModelObject class in Rails 1.0 - * - * @author freystef */ + public abstract class Model extends Observable { - private boolean updated = false; + private boolean current = false; private String cache = null; protected Model(Item parent, String id) { @@ -23,24 +20,30 @@ public abstract class Model extends Observable { } /** - * Indicates that the model is updated, so the getText() cache - * is flushed + * Calling of update informs the model that some prerequisites has been updated */ public void update() { - updated = false; + current = false; } /** - * For a model the text shown to observer is derived from toString() - * The value is cached until the model is updated + * {@inheritDoc} + * Remark: A Model has to either override this or cachedText(), the latter automatically caches results */ @Override - public final String getText() { - if (!updated){ - updated = true; - cache = toString(); + public String observerText() { + if (!current){ + current = true; + cache = this.cachedText(); } return cache; } + /** + * @return Default Model text used for Observer updates (gets cached automatically) + */ + public String cachedText() { + return null; + } + } diff --git a/src/rails/game/state/Observable.java b/src/rails/game/state/Observable.java index 0ac1ffb..9bdde04 100644 --- a/src/rails/game/state/Observable.java +++ b/src/rails/game/state/Observable.java @@ -15,11 +15,6 @@ public abstract class Observable implements Item { private final Item parent; private final Context context; - // stores observers and models if observable - // those are unobservable states themselves - private final HashSetState<Observer> observers; - private final HashSetState<Model> models; - /** * @param parent parent node in item hierarchy (cannot be null) * @param id id of the observable @@ -43,45 +38,45 @@ public abstract class Observable implements Item { // if id is null this is an "unobservable" observable if (id == null) { - observers = null; - models = null; } else { - observers = HashSetState.create(this, null); - models = HashSetState.create(this, null); // add item to context if it has an id context.addItem(this); } } + + protected StateManager getStateManager() { + return context.getRoot().getStateManager(); + } public void addObserver(Observer o) { checkState(id != null, "Cannot add observer to unobservable object"); - observers.add(o); + getStateManager().addObserver(o, this); } public boolean removeObserver(Observer o) { checkState(id != null, "Cannot remove observer from unobservable object"); - return observers.remove(o); + return getStateManager().removeObserver(o, this); } public ImmutableSet<Observer> getObservers() { checkState(id != null, "Cannot get observers of unobservable object"); - return observers.view(); + return getStateManager().getObservers(this); } public void addModel(Model m) { checkState(id != null, "Cannot add model to unobservable object"); - models.add(m); + getStateManager().addModel(m, this); } public boolean removeModel(Model m) { checkState(id != null, "Cannot remove model from unobservable object"); - return models.remove(m); + return getStateManager().removeModel(m, this); } public ImmutableSet<Model> getModels() { checkState(id != null, "Cannot get models of unobservable object"); - return models.view(); + return getStateManager().getModels(this); } /** @@ -90,11 +85,15 @@ public abstract class Observable implements Item { */ public void updateModels() { if (id == null) return; - for (Model m:models) { + for (Model m:this.getModels()) { m.update(); } } + public boolean isObservable() { + return (id != null); + } + // Item methods public String getId() { @@ -132,8 +131,8 @@ public abstract class Observable implements Item { /** - * @return text to be read by observers + * @return text delivered to observers, if no formatter is used */ - public abstract String getText(); + public abstract String observerText(); } diff --git a/src/rails/game/state/Observer.java b/src/rails/game/state/Observer.java index 2cdd4ea..d392e41 100644 --- a/src/rails/game/state/Observer.java +++ b/src/rails/game/state/Observer.java @@ -5,6 +5,6 @@ package rails.game.state; */ public interface Observer{ - void update(Observable observable, String text); + void update(String text); } diff --git a/src/rails/game/state/Root.java b/src/rails/game/state/Root.java index 29c85e3..af481cd 100644 --- a/src/rails/game/state/Root.java +++ b/src/rails/game/state/Root.java @@ -9,27 +9,26 @@ public final class Root extends Context { public final static String ID = ""; private StateManager stateManager; - private final HashMapState<String, Item> items = HashMapState.create(this, null); + private HashMapState<String, Item> items; private Root() { + } /** * @return a Root object with initialized StateManager embedded */ public static Root create() { + // precise sequence to avoid any unintialized problems Root root = new Root(); StateManager stateManager = StateManager.create(root, "states"); - root.addStateManager(stateManager); + root.stateManager = stateManager; + root.items = HashMapState.create(root, null); + root.addItem(stateManager); root.addItem(root); return root; } - private void addStateManager(StateManager stateManager) { - this.stateManager = stateManager; - this.addItem(stateManager); - } - public StateManager getStateManager() { return stateManager; } diff --git a/src/rails/game/state/State.java b/src/rails/game/state/State.java index 59a95c0..324c99f 100644 --- a/src/rails/game/state/State.java +++ b/src/rails/game/state/State.java @@ -1,7 +1,5 @@ package rails.game.state; -import static com.google.common.base.Preconditions.*; - /** * State is an abstract generic class * that defines the base layer of objects that contain game state. @@ -15,45 +13,27 @@ import static com.google.common.base.Preconditions.*; */ public abstract class State extends Observable { - // optional formatter - private Formatter<State> formatter = null; - protected State(Item parent, String id) { super(parent, id); - // register if observable state if (id != null) { // check if parent is a model and add as dependent model if (parent instanceof Model) { addModel((Model)parent); } - // check if there is a StateManager available - checkState(getContext().getRoot().getStateManager() != null, "Root of state has no StateManager attached"); - // if so => register state there - getRoot().getStateManager().registerState(this); + this.getStateManager().registerState(this); } } // Observable methods /** - * For a state getText() it is identical to toString() - * If this does not work use a formatter + * {@inheritDoc} + * For a state defaultText() it is identical to toString() + * If this is not the correct behavior, overwrite it */ @Override - public final String getText() { - if (formatter == null) { - return toString(); - } else { - return formatter.formatValue(this); - } - } - - /** - * Adds a Formatter - * @param formatter - */ - public void setFormatter(Formatter<State> formatter) { - this.formatter = formatter; + public String observerText() { + return toString(); } } \ No newline at end of file diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java index 37cc852..3dd66eb 100644 --- a/src/rails/game/state/StateManager.java +++ b/src/rails/game/state/StateManager.java @@ -1,5 +1,7 @@ package rails.game.state; +import static com.google.common.base.Preconditions.checkArgument; + import java.util.List; import java.util.Set; @@ -17,8 +19,16 @@ public final class StateManager extends Manager { protected static Logger log = LoggerFactory.getLogger(StateManager.class.getPackage().getName()); - private final ChangeStack changeStack = ChangeStack.create(); + private final ChangeStack changeStack = ChangeStack.create(this); private final HashSetState<State> allStates = HashSetState.create(this, null); + + private final HashMultimapState<Observable, Observer> + observers = HashMultimapState.create(this, null); + private final HashMapState<Observer, Formatter<? extends Observable>> + formatters = HashMapState.create(this, null); + private final HashMultimapState<Observable, Model> + models = HashMultimapState.create(this, null); + // private final PortfolioManager portfolioManager = PortfolioManager.create(this, "portfolioManager"); // private final WalletManager walletManager = WalletManager.create(this, "walletManager"); @@ -58,6 +68,48 @@ public final class StateManager extends Manager { } /** + * Adds the combination of observer to observable + * @throws an IllegalArgumentException - if observer is already assigned to an observable + */ + void addObserver(Observer observer, Observable observable) { + checkArgument(!observers.containsValue(observer), "Observer can only be assigned to one Observable"); + observers.put(observable, observer); + } + + /** + * Adds the combination of observer to observable, using a Formatter + * @throws an IllegalArgumentException - if observer is already assigned to an observable + */ + <T extends Observable> void addObserver(Observer observer, Formatter<T> formatter) { + this.addObserver(observer, formatter.getObservable()); + formatters.put(observer, formatter); + } + + boolean removeObserver(Observer observer, Observable observable) { + formatters.remove(observer); + return observers.remove(observable, observer); + } + + public ImmutableSet<Observer> getObservers(Observable observable) { + return observers.get(observable); + } + + /** + * Adds the combination of model to observable + */ + void addModel(Model model, Observable observable) { + models.put(observable, model); + } + + boolean removeModel(Model model, Observable observable) { + return models.remove(observable, model); + } + + public ImmutableSet<Model> getModels(Observable observable) { + return models.get(observable); + } + + /** * A set of states is given as input * and then calculates all observer to update in the correct sequence * @@ -121,7 +173,7 @@ public final class StateManager extends Manager { * @param states Set of states * @return all observers to be updated from states (either directly or via Models) */ - Set<Observer> getObservers(Set<State> states){ + private Set<Observer> getObservers(Set<State> states){ Set<Observer> observers = Sets.newHashSet(); @@ -138,6 +190,20 @@ public final class StateManager extends Manager { return observers; } + void updateObservers(Set<State> states) { + for (Observable observable:getSortedObservables(states)) { + for (Observer observer:observable.getObservers()) { + // check if formatter is defined + if (formatters.containsKey(observer)) { + observer.update(formatters.get(observer).observerText()); + } else { + // otherwise use observable text + observer.update(observable.observerText()); + } + } + } + } + /** * @param states Set of states * @return all models to be updated from states diff --git a/src/rails/ui/swing/GridPanel.java b/src/rails/ui/swing/GridPanel.java index f61dca3..5430170 100644 --- a/src/rails/ui/swing/GridPanel.java +++ b/src/rails/ui/swing/GridPanel.java @@ -180,7 +180,7 @@ implements ActionListener, KeyListener { } */ - public void update(Observable observable, String text) { + public void update(String text) { // FIXME: There was a Boolean object submitted if the company is closed // TODO: Make this functionality available again // see above the old update method diff --git a/src/rails/ui/swing/elements/Field.java b/src/rails/ui/swing/elements/Field.java index 95dcaf9..9c440a8 100644 --- a/src/rails/ui/swing/elements/Field.java +++ b/src/rails/ui/swing/elements/Field.java @@ -87,7 +87,7 @@ public class Field extends JLabel implements Observer { @Override public void paintComponent(Graphics g) { if (observable != null && pull) { - setText(observable.getText()); + setText(observable.observerText()); } super.paintComponent(g); } @@ -116,7 +116,7 @@ public class Field extends JLabel implements Observer { } /** Needed to satisfy the Observer interface. */ - public void update(Observable observable, String text) { + public void update(String text) { setText(text); } diff --git a/src/rails/ui/swing/elements/GUIStockSpace.java b/src/rails/ui/swing/elements/GUIStockSpace.java index 0c388da..d1d0ab5 100644 --- a/src/rails/ui/swing/elements/GUIStockSpace.java +++ b/src/rails/ui/swing/elements/GUIStockSpace.java @@ -17,7 +17,6 @@ import org.slf4j.LoggerFactory; import rails.game.PublicCompany; import rails.game.StockSpace; import rails.game.state.Model; -import rails.game.state.Observable; import rails.game.state.Observer; import rails.ui.swing.GUIToken; import rails.util.Util; @@ -138,7 +137,7 @@ public class GUIStockSpace extends JLayeredPane implements Observer { * @see java.rails.util.Observer#update(java.rails.util.Observable, * java.lang.Object) */ - public void update(Observable observable, String text) { + public void update(String text) { recreate(); } diff --git a/src/rails/ui/swing/hexmap/GUIHex.java b/src/rails/ui/swing/hexmap/GUIHex.java index ad9d27d..8a36d78 100644 --- a/src/rails/ui/swing/hexmap/GUIHex.java +++ b/src/rails/ui/swing/hexmap/GUIHex.java @@ -37,7 +37,6 @@ import rails.game.Stop; import rails.game.Tile; import rails.game.TileOrientation; import rails.game.Token; -import rails.game.state.Observable; import rails.game.state.Observer; import rails.ui.swing.GUIToken; import rails.util.Util; @@ -897,6 +896,7 @@ public class GUIHex implements Observer { } // Used by Undo/Redo + // FIMXE: Does this still work? public void update(String notification) { // The below code so far only deals with tile lay undo/redo. // Tokens still to do @@ -922,11 +922,4 @@ public class GUIHex implements Observer { public String toString () { return getName() + " (" + currentTile.getId() + ")"; } - - // FIMXE: Add the code here - public void update(Observable observable, String id) { - // TODO Auto-generated method stub - - } - } |
From: Stefan F. <ste...@us...> - 2012-07-08 20:59:31
|
src/rails/game/OperatingRound.java | 12 +----------- src/rails/game/model/PresidentModel.java | 11 +++-------- src/rails/game/state/Observer.java | 12 ++---------- src/rails/ui/swing/GridPanel.java | 22 ++++++++-------------- src/rails/ui/swing/elements/Field.java | 18 ++++-------------- src/rails/ui/swing/elements/GUIStockSpace.java | 22 +--------------------- src/rails/ui/swing/hexmap/GUIHex.java | 15 +-------------- 7 files changed, 20 insertions(+), 92 deletions(-) New commits: commit 39169f9f7195e3b705d712780d589fa26dea3a39 Author: Stefan Frey <ste...@we...> Date: Sun Jul 8 22:59:08 2012 +0200 started rethinking the Observer interface diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java index 4e2c305..50becdd 100644 --- a/src/rails/game/OperatingRound.java +++ b/src/rails/game/OperatingRound.java @@ -3124,7 +3124,7 @@ public class OperatingRound extends Round implements Observer { /** * Update the status if the step has changed by an Undo or Redo */ - public void update() { + public void update(Observable observable, String text) { prepareStep(); } @@ -3144,14 +3144,4 @@ public class OperatingRound extends Round implements Observer { return toString(); } - // Observer Interface - public Observable getObservable() { - return stepObject; - } - - public boolean deRegister() { - if (stepObject == null) return false; - return stepObject.removeObserver(this); - } - } \ No newline at end of file diff --git a/src/rails/game/model/PresidentModel.java b/src/rails/game/model/PresidentModel.java index 442385d..0f7cbb4 100644 --- a/src/rails/game/model/PresidentModel.java +++ b/src/rails/game/model/PresidentModel.java @@ -43,14 +43,9 @@ public final class PresidentModel extends Model implements Observer { else return company.getPresident().getNameAndPriority(); } - public Observable getObservable() { - // TODO Auto-generated method stub - return null; - } - - public boolean deRegister() { - // TODO Auto-generated method stub - return false; + // FIXME: Add code what to do here + public void update(Observable observable, String text) { + } } diff --git a/src/rails/game/state/Observer.java b/src/rails/game/state/Observer.java index c1b1eb5..2cdd4ea 100644 --- a/src/rails/game/state/Observer.java +++ b/src/rails/game/state/Observer.java @@ -1,18 +1,10 @@ package rails.game.state; /** - * An interface defining an observer for states and models - * - * It is a very simple approach that only relays the update information itself. - * - * @author freystef + * An interface defining an Observer to Observable classes */ public interface Observer{ - void update(); - - Observable getObservable(); - - boolean deRegister(); + void update(Observable observable, String text); } diff --git a/src/rails/ui/swing/GridPanel.java b/src/rails/ui/swing/GridPanel.java index 02bc2ef..f61dca3 100644 --- a/src/rails/ui/swing/GridPanel.java +++ b/src/rails/ui/swing/GridPanel.java @@ -75,10 +75,11 @@ implements ActionListener, KeyListener { revalidate(); } + // FIXME: This has to be replaced protected void deRegisterObservers() { log.debug("Deregistering observers"); for (Observer vo : observers) { - vo.deRegister(); +// vo.deRegister(); } } @@ -106,10 +107,11 @@ implements ActionListener, KeyListener { gridPanel.add(comp, gbc); - if (comp instanceof Observer - && ((Observer) comp).getObservable() != null) { - observers.add((Observer) comp); - } + // FIXME: This has to be replaced +// if (comp instanceof Observer +// && ((Observer) comp).getObservable() != null) { +// observers.add((Observer) comp); +// } if (fields != null && fields[x][y] == null) fields[x][y] = comp; comp.setVisible(visible); @@ -178,20 +180,12 @@ implements ActionListener, KeyListener { } */ - public void update() { + public void update(Observable observable, String text) { // FIXME: There was a Boolean object submitted if the company is closed // TODO: Make this functionality available again // see above the old update method } - public Observable getObservable() { - return observable; - } - - public boolean deRegister() { - return observable.removeObserver(this); - } - } diff --git a/src/rails/ui/swing/elements/Field.java b/src/rails/ui/swing/elements/Field.java index ae4199d..95dcaf9 100644 --- a/src/rails/ui/swing/elements/Field.java +++ b/src/rails/ui/swing/elements/Field.java @@ -71,10 +71,11 @@ public class Field extends JLabel implements Observer { return observable; } + // FIXME: Rewrite that part here public void setModel(Observable m) { observable = m; observable.addObserver(this); - update(); +// update(); } public void setHighlight(boolean highlight) { @@ -115,19 +116,8 @@ public class Field extends JLabel implements Observer { } /** Needed to satisfy the Observer interface. */ - public void update() { - setText(observable.getText()); + public void update(Observable observable, String text) { + setText(text); } - public boolean deRegister() { - dependents = null; - if (observable == null) return false; - return observable.removeObserver(this); - } - - public Observable getObservable() { - return observable; - } - - } diff --git a/src/rails/ui/swing/elements/GUIStockSpace.java b/src/rails/ui/swing/elements/GUIStockSpace.java index f121a09..0c388da 100644 --- a/src/rails/ui/swing/elements/GUIStockSpace.java +++ b/src/rails/ui/swing/elements/GUIStockSpace.java @@ -135,32 +135,12 @@ public class GUIStockSpace extends JLayeredPane implements Observer { /* * (non-Javadoc) * - * @see rails.ui.swing.elements.ViewObject#deRegister() - */ - public boolean deRegister() { - if (model == null) return false; - return model.removeObserver(this); - } - - /* - * (non-Javadoc) - * * @see java.rails.util.Observer#update(java.rails.util.Observable, * java.lang.Object) */ - public void update(String data) { + public void update(Observable observable, String text) { recreate(); } - public void update() { - // TODO Auto-generated method stub - - } - - public Observable getObservable() { - // TODO Auto-generated method stub - return null; - } - } diff --git a/src/rails/ui/swing/hexmap/GUIHex.java b/src/rails/ui/swing/hexmap/GUIHex.java index 86cd721..ad9d27d 100644 --- a/src/rails/ui/swing/hexmap/GUIHex.java +++ b/src/rails/ui/swing/hexmap/GUIHex.java @@ -891,13 +891,6 @@ public class GUIHex implements Observer { toolTip = null; } - /** Needed to satisfy the ViewObject interface. Currently not used. */ - public boolean deRegister() { - if (model == null) return false; - model.removeObserver(this); - return true; - } - // FIXME: Why is this called getModel instead of getMapHex? public MapHex getModel() { return model; @@ -931,15 +924,9 @@ public class GUIHex implements Observer { } // FIMXE: Add the code here - public void update() { + public void update(Observable observable, String id) { // TODO Auto-generated method stub } - public Observable getObservable() { - // TODO Auto-generated method stub - return null; - } - - } |
From: Stefan F. <ste...@us...> - 2012-07-07 06:55:17
|
junit/rails/game/state/AbstractItemImpl.java | 1 junit/rails/game/state/AbstractItemTest.java | 24 +-- junit/rails/game/state/ActionChangeSetTest.java | 5 junit/rails/game/state/BooleanStateTest.java | 61 ++++++++ junit/rails/game/state/ChangeStackTest.java | 38 ++--- junit/rails/game/state/FormatterTest.java | 40 +++++ junit/rails/game/state/GenericStateTest.java | 80 +++++++++++ junit/rails/game/state/ManagerImpl.java | 1 junit/rails/game/state/ManagerTest.java | 39 ++--- junit/rails/game/state/ModelImpl.java | 17 ++ junit/rails/game/state/ObservableTest.java | 166 ++++++++++++++++++++++++ junit/rails/game/state/RootTest.java | 24 +-- junit/rails/game/state/StateImpl.java | 18 ++ junit/rails/game/state/StateTest.java | 54 +++++++ junit/rails/game/state/StateTestUtils.java | 21 +++ src/rails/game/state/BooleanChange.java | 1 src/rails/game/state/BooleanState.java | 11 + src/rails/game/state/GenericState.java | 14 -- src/rails/game/state/GenericStateChange.java | 14 +- src/rails/game/state/Observable.java | 12 + src/rails/game/state/State.java | 9 - 21 files changed, 562 insertions(+), 88 deletions(-) New commits: commit 8d420cfb229c5a0883b5cdef9eebb68141612dec Author: Stefan Frey <ste...@we...> Date: Fri Jul 6 15:40:46 2012 +0200 added GenericStateTest diff --git a/junit/rails/game/state/BooleanStateTest.java b/junit/rails/game/state/BooleanStateTest.java index e5d9f77..1e4b6f5 100644 --- a/junit/rails/game/state/BooleanStateTest.java +++ b/junit/rails/game/state/BooleanStateTest.java @@ -38,6 +38,14 @@ public class BooleanStateTest { } @Test + public void testSetSameIgnored() { + state_default.set(false); + state_init.set(true); + stack.closeCurrentChangeSet(); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default, state_init); + } + + @Test public void testUndoRedo() { assertFalse(state_default.value()); state_default.set(true); diff --git a/junit/rails/game/state/GenericStateTest.java b/junit/rails/game/state/GenericStateTest.java new file mode 100644 index 0000000..c25424c --- /dev/null +++ b/junit/rails/game/state/GenericStateTest.java @@ -0,0 +1,80 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +public class GenericStateTest { + + private final static String STATE_ID = "Generic"; + private final static String ITEM_ID = "Item"; + private final static String ANOTHER_ID = "Another"; + + private Root root; + private ChangeStack stack; + private GenericState<Item> state_default; + private GenericState<Item> state_init; + + private Item item, another_item; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + stack = root.getStateManager().getChangeStack(); + + item = new AbstractItemImpl(root, ITEM_ID); + another_item = new AbstractItemImpl(root, ANOTHER_ID); + + state_default = GenericState.create(root, STATE_ID); + state_init = GenericState.create(root, null, item); + } + + @Test + public void testValue() { + assertNull(state_default.get()); + assertSame(item, state_init.get()); + } + + @Test + public void testSet() { + state_default.set(item); + assertSame(item, state_default.get()); + state_default.set(null); + assertNull(state_default.get()); + state_init.set(another_item); + assertSame(another_item, state_init.get()); + } + + @Test + public void testSetSameIgnored() { + state_default.set(null); + state_init.set(item); + stack.closeCurrentChangeSet(); + assertThat(stack.getLastClosedChangeSet().getStates()).doesNotContain(state_default, state_init); + } + + @Test + public void testUndoRedo() { + assertNull(state_default.get()); + assertSame(item, state_init.get()); + + state_default.set(item); + state_init.set(another_item); + assertSame(item, state_default.get()); + assertSame(another_item, state_init.get()); + + stack.closeCurrentChangeSet(); + assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default, state_init); + + stack.undo(); + assertNull(state_default.get()); + assertSame(item, state_init.get()); + + stack.redo(); + assertSame(item, state_default.get()); + assertSame(another_item, state_init.get()); + } + +} diff --git a/src/rails/game/state/BooleanState.java b/src/rails/game/state/BooleanState.java index f2da4c2..301e1dd 100644 --- a/src/rails/game/state/BooleanState.java +++ b/src/rails/game/state/BooleanState.java @@ -31,7 +31,7 @@ public final class BooleanState extends State { * @param value set state to this value */ public void set(boolean value) { - new BooleanChange(this, value); + if (value != this.value) new BooleanChange(this, value); } /** diff --git a/src/rails/game/state/GenericState.java b/src/rails/game/state/GenericState.java index 6003c40..ea79cb6 100644 --- a/src/rails/game/state/GenericState.java +++ b/src/rails/game/state/GenericState.java @@ -29,24 +29,16 @@ public final class GenericState<E> extends State { return new GenericState<E>(parent, id, object); } - private void set(E object, boolean forced) { + public void set(E object) { if (object == null) { if (this.object != null) { new GenericStateChange<E>(this, object); } - } else if (!object.equals(this.object) || forced) { - new GenericStateChange<E>(this, object); + } else if (object != this.object) { + new GenericStateChange<E>(this, object); } } - public void set(E object) { - set(object, false); - } - - public void setForced(E object) { - set(object, true); - } - public E get() { return this.object; } diff --git a/src/rails/game/state/GenericStateChange.java b/src/rails/game/state/GenericStateChange.java index 076f731..d53d925 100644 --- a/src/rails/game/state/GenericStateChange.java +++ b/src/rails/game/state/GenericStateChange.java @@ -29,7 +29,19 @@ final class GenericStateChange<E> extends Change { @Override public String toString() { - return "Change State " + state.getId() + " from " + previous.toString() + " to" + next.toString(); + String from, to; + if (previous == null) { + from = "<null>"; + } else { + from = previous.toString(); + } + if (next == null) { + to = "<null>"; + } else { + to = next.toString(); + } + + return "Change State " + state + " from " + from + " to " + to ; } } commit f828e621bdcf63659cc8b24516ba5a0e1430974e Author: Stefan Frey <ste...@we...> Date: Fri Jul 6 15:12:16 2012 +0200 added BooleanStateTest and StateTestUtils diff --git a/junit/rails/game/state/BooleanStateTest.java b/junit/rails/game/state/BooleanStateTest.java new file mode 100644 index 0000000..e5d9f77 --- /dev/null +++ b/junit/rails/game/state/BooleanStateTest.java @@ -0,0 +1,53 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +public class BooleanStateTest { + + private final static String STATE_ID = "Boolean"; + + private Root root; + private ChangeStack stack; + private BooleanState state_default; + private BooleanState state_init; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + state_default = BooleanState.create(root, STATE_ID); + state_init = BooleanState.create(root, null, true); + stack = root.getStateManager().getChangeStack(); + } + + @Test + public void testValue() { + assertFalse(state_default.value()); + assertTrue(state_init.value()); + } + + @Test + public void testSet() { + state_default.set(true); + assertTrue(state_default.value()); + state_init.set(false); + assertFalse(state_init.value()); + } + + @Test + public void testUndoRedo() { + assertFalse(state_default.value()); + state_default.set(true); + assertTrue(state_default.value()); + stack.closeCurrentChangeSet(); + assertThat(stack.getLastClosedChangeSet().getStates()).contains(state_default); + stack.undo(); + assertFalse(state_default.value()); + stack.redo(); + assertTrue(state_default.value()); + } + +} diff --git a/junit/rails/game/state/StateTestUtils.java b/junit/rails/game/state/StateTestUtils.java new file mode 100644 index 0000000..1d1d50e --- /dev/null +++ b/junit/rails/game/state/StateTestUtils.java @@ -0,0 +1,21 @@ +package rails.game.state; + +import org.mockito.Mock; + +import rails.game.Player; +import rails.game.action.PossibleAction; + +/** + * Common Utilities for State Testing + */ +class StateTestUtils { + @Mock static Player player; + @Mock static PossibleAction action; + + public static Root setUpRoot() { + Root root = Root.create(); + // avoid initial changeSet as it is not undoable + root.getStateManager().getChangeStack().startActionChangeSet(player, action); + return root; + } +} diff --git a/src/rails/game/state/BooleanChange.java b/src/rails/game/state/BooleanChange.java index 6246fd0..75aa2bc 100644 --- a/src/rails/game/state/BooleanChange.java +++ b/src/rails/game/state/BooleanChange.java @@ -2,7 +2,6 @@ package rails.game.state; /** * Change associated with BooleanState - * @author freystef */ final class BooleanChange extends Change { diff --git a/src/rails/game/state/BooleanState.java b/src/rails/game/state/BooleanState.java index 2c35526..f2da4c2 100644 --- a/src/rails/game/state/BooleanState.java +++ b/src/rails/game/state/BooleanState.java @@ -2,8 +2,6 @@ package rails.game.state; /** * A stateful version of a boolean variable - * - * @author Erik Vos, Stefan Frey (V2.0) */ public final class BooleanState extends State { @@ -22,16 +20,23 @@ public final class BooleanState extends State { } /** + * Creates a BooleanState with defined initial value * @param value initial value */ public static BooleanState create(Item parent, String id, Boolean value){ return new BooleanState(parent, id, value); } + /** + * @param value set state to this value + */ public void set(boolean value) { new BooleanChange(this, value); } + /** + * @return current value of state variable + */ public boolean value() { return value; } commit a190b541b3264233275b92644cbfb99025c47827 Author: Stefan Frey <ste...@we...> Date: Fri Jul 6 13:21:29 2012 +0200 added StateTest and required Impl test classes diff --git a/junit/rails/game/state/FormatterTest.java b/junit/rails/game/state/FormatterTest.java new file mode 100644 index 0000000..626f0be --- /dev/null +++ b/junit/rails/game/state/FormatterTest.java @@ -0,0 +1,40 @@ +package rails.game.state; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +public class FormatterTest { + + // This formatter doubles the text of the state + private class FormatterImpl implements Formatter<State> { + public String formatValue(State state) { + return state.toString() + state.toString(); + } + } + + private final static String STATE_ID = "State"; + private final static String STATE_TEXT = "Test"; + + private Root root; + private State state; + private Formatter<State> formatter; + + @Before + public void setUp() { + root = Root.create(); + state = new StateImpl(root, STATE_ID, STATE_TEXT); + formatter = new FormatterImpl(); + } + + @Test + public void testFormatValue() { + assertEquals(STATE_TEXT, state.getText()); + state.setFormatter(formatter); + assertEquals(STATE_TEXT + STATE_TEXT, state.getText()); + state.setFormatter(null); + assertEquals(STATE_TEXT, state.getText()); + } + +} diff --git a/junit/rails/game/state/ModelImpl.java b/junit/rails/game/state/ModelImpl.java new file mode 100644 index 0000000..e029de0 --- /dev/null +++ b/junit/rails/game/state/ModelImpl.java @@ -0,0 +1,17 @@ +package rails.game.state; + +//An implementation only for testing +class ModelImpl extends Model { + + private final String text; + + ModelImpl(Item parent, String id, String text) { + super(parent, id); + this.text = text; + } + + @Override + public String toString() { + return text; + } +} diff --git a/junit/rails/game/state/StateImpl.java b/junit/rails/game/state/StateImpl.java new file mode 100644 index 0000000..4f4f160 --- /dev/null +++ b/junit/rails/game/state/StateImpl.java @@ -0,0 +1,18 @@ +package rails.game.state; + +// An implementation only for testing +class StateImpl extends State { + + private final String text; + + StateImpl(Item parent, String id, String text) { + super(parent, id); + this.text = text; + } + + @Override + public String toString() { + return text; + } + +} diff --git a/junit/rails/game/state/StateTest.java b/junit/rails/game/state/StateTest.java new file mode 100644 index 0000000..61bffab --- /dev/null +++ b/junit/rails/game/state/StateTest.java @@ -0,0 +1,54 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +public class StateTest { + + private final static String STATE_ID = "State"; + private final static String MODEL_ID = "Model"; + private final static String STATE_TEXT = "Test"; + + private Root root; + private State state; + private State state_model; + private State state_wo_id; + private Model model; + + @Before + public void setUp() { + root = Root.create(); + state = new StateImpl(root, STATE_ID, null); + model = new ModelImpl(root, MODEL_ID, null); + state_model = new StateImpl(model, STATE_ID, null); + state_wo_id = new StateImpl(model, null, STATE_TEXT); + } + + @Test + public void testState() { + // check that model is linked by state_model + assertThat(state_model.getModels()).contains(model); + // but for the standard model only after explicit link + assertThat(state.getModels()).doesNotContain(model); + state.addModel(model); + assertThat(state.getModels()).contains(model); + + // state_wo_id does not have any link + try { + state_wo_id.getModels(); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + + } + + @Test + public void testGetText() { + assertNull(state.getText()); + assertEquals(STATE_TEXT, state_wo_id.getText()); + } + +} diff --git a/src/rails/game/state/State.java b/src/rails/game/state/State.java index fc2ef79..59a95c0 100644 --- a/src/rails/game/state/State.java +++ b/src/rails/game/state/State.java @@ -20,13 +20,14 @@ public abstract class State extends Observable { protected State(Item parent, String id) { super(parent, id); - // check if parent is a model and add as dependent model - if (parent instanceof Model) { - addModel((Model)parent); - } + // register if observable state if (id != null) { + // check if parent is a model and add as dependent model + if (parent instanceof Model) { + addModel((Model)parent); + } // check if there is a StateManager available checkState(getContext().getRoot().getStateManager() != null, "Root of state has no StateManager attached"); // if so => register state there commit 08ffe071434691403dc840e50859997bbd32c5ac Author: Stefan Frey <ste...@we...> Date: Fri Jul 6 10:57:07 2012 +0200 fixed wronger ordering of expected and actual arguments in existing tests diff --git a/junit/rails/game/state/AbstractItemTest.java b/junit/rails/game/state/AbstractItemTest.java index 19c994e..ec38434 100644 --- a/junit/rails/game/state/AbstractItemTest.java +++ b/junit/rails/game/state/AbstractItemTest.java @@ -26,38 +26,38 @@ public class AbstractItemTest { @Test public void testGetId() { - assertEquals(item.getId(), ITEM_ID); - assertEquals(anotherItem.getId(), ANOTHER_ID); + assertEquals(ITEM_ID, item.getId()); + assertEquals(ANOTHER_ID, anotherItem.getId()); } @Test public void testGetParent() { - assertSame(item.getParent(), manager); - assertSame(anotherItem.getParent(), item); + assertSame(manager, item.getParent()); + assertSame(item, anotherItem.getParent()); } @Test public void testGetContext() { - assertSame(item.getContext(), manager); - assertSame(anotherItem.getContext(), manager); + assertSame(manager, item.getContext()); + assertSame(manager, anotherItem.getContext()); } @Test public void testGetRoot() { - assertSame(item.getRoot(), root); - assertSame(anotherItem.getRoot(), root); + assertSame(root, item.getRoot()); + assertSame(root, anotherItem.getRoot()); } @Test public void testGetURI() { - assertEquals(item.getURI(), ITEM_ID); - assertEquals(anotherItem.getURI(), ITEM_ID + Item.SEP + ANOTHER_ID); + assertEquals(ITEM_ID, item.getURI()); + assertEquals(ITEM_ID + Item.SEP + ANOTHER_ID, anotherItem.getURI()); } @Test public void testGetFullURI() { - assertEquals(item.getFullURI(), Item.SEP + MANAGER_ID + Item.SEP + ITEM_ID); - assertEquals(anotherItem.getFullURI(), Item.SEP + MANAGER_ID+ Item.SEP + ITEM_ID + Item.SEP + ANOTHER_ID); + assertEquals(Item.SEP + MANAGER_ID + Item.SEP + ITEM_ID, item.getFullURI()); + assertEquals(Item.SEP + MANAGER_ID+ Item.SEP + ITEM_ID + Item.SEP + ANOTHER_ID, anotherItem.getFullURI()); } } diff --git a/junit/rails/game/state/ActionChangeSetTest.java b/junit/rails/game/state/ActionChangeSetTest.java index 8062dba..dd388ec 100644 --- a/junit/rails/game/state/ActionChangeSetTest.java +++ b/junit/rails/game/state/ActionChangeSetTest.java @@ -42,12 +42,12 @@ public class ActionChangeSetTest { @Test public void testGetPlayer() { - assertSame(changeSet.getPlayer(), player); + assertSame(player, changeSet.getPlayer()); } @Test public void testGetAction() { - assertSame(changeSet.getAction(), action); + assertSame(action, changeSet.getAction()); } @Test @@ -79,5 +79,4 @@ public class ActionChangeSetTest { assertTrue(state.value()); } - } diff --git a/junit/rails/game/state/ChangeStackTest.java b/junit/rails/game/state/ChangeStackTest.java index d1d04ef..3b24122 100644 --- a/junit/rails/game/state/ChangeStackTest.java +++ b/junit/rails/game/state/ChangeStackTest.java @@ -43,16 +43,16 @@ public class ChangeStackTest { @Test public void testGetCurrentChangeSet() { - assertSame(changeStack.getCurrentChangeSet(), action_3); + assertSame(action_3, changeStack.getCurrentChangeSet()); // on the stack there are auto_1, action_1, auto_2, action_2 - assertEquals(changeStack.sizeUndoStack(), 4); + assertEquals(4, changeStack.sizeUndoStack()); } @Test public void testCloseCurrentChangeSet() { changeStack.closeCurrentChangeSet(); assertTrue(action_3.isClosed()); - assertSame(changeStack.getLastClosedChangeSet(), action_3); + assertSame(action_3, changeStack.getLastClosedChangeSet()); // and now action_3 is added assertEquals(changeStack.sizeUndoStack(), 5); } @@ -62,26 +62,26 @@ public class ChangeStackTest { assertFalse(state.value()); // undo action 3 assertTrue(changeStack.undo()); - assertEquals(changeStack.sizeUndoStack(), 4); - assertSame(changeStack.getLastClosedChangeSet(), action_2); + assertEquals(4, changeStack.sizeUndoStack()); + assertSame(action_2, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertFalse(state.value()); // undo action 2 assertTrue(changeStack.undo()); - assertEquals(changeStack.sizeUndoStack(), 3); - assertSame(changeStack.getLastClosedChangeSet(), auto_2); + assertEquals(3, changeStack.sizeUndoStack()); + assertSame(auto_2, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertTrue(state.value()); // undo auto_2 and action 1 assertTrue(changeStack.undo()); - assertEquals(changeStack.sizeUndoStack(), 1); - assertSame(changeStack.getLastClosedChangeSet(), auto_1); + assertEquals(1, changeStack.sizeUndoStack()); + assertSame(auto_1, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertFalse(state.value()); // undo should not do anything now assertFalse(changeStack.undo()); - assertEquals(changeStack.sizeUndoStack(), 1); - assertSame(changeStack.getLastClosedChangeSet(), auto_1); + assertEquals(1, changeStack.sizeUndoStack()); + assertSame(auto_1, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertFalse(state.value()); } @@ -95,26 +95,26 @@ public class ChangeStackTest { // the state unitl now was checked in testUndo // now redo action_1 and auto_2 assertTrue(changeStack.redo()); - assertEquals(changeStack.sizeUndoStack(), 3); - assertSame(changeStack.getLastClosedChangeSet(), auto_2); + assertEquals(3, changeStack.sizeUndoStack()); + assertSame(auto_2, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertTrue(state.value()); // redo action_2 assertTrue(changeStack.redo()); - assertEquals(changeStack.sizeUndoStack(), 4); - assertSame(changeStack.getLastClosedChangeSet(), action_2); + assertEquals(4, changeStack.sizeUndoStack()); + assertSame(action_2, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertFalse(state.value()); // redo action_3 assertTrue(changeStack.redo()); - assertEquals(changeStack.sizeUndoStack(), 5); - assertSame(changeStack.getLastClosedChangeSet(), action_3); + assertEquals(5, changeStack.sizeUndoStack()); + assertSame(action_3, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertFalse(state.value()); // then it should do anything assertFalse(changeStack.redo()); - assertEquals(changeStack.sizeUndoStack(), 5); - assertSame(changeStack.getLastClosedChangeSet(), action_3); + assertEquals(5, changeStack.sizeUndoStack()); + assertSame(action_3, changeStack.getLastClosedChangeSet()); assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); assertFalse(state.value()); } diff --git a/junit/rails/game/state/ManagerTest.java b/junit/rails/game/state/ManagerTest.java index 0400718..95fd0c7 100644 --- a/junit/rails/game/state/ManagerTest.java +++ b/junit/rails/game/state/ManagerTest.java @@ -27,60 +27,59 @@ public class ManagerTest { @Test public void testGetId() { - assertEquals(manager.getId(), MANAGER_ID); - assertEquals(anotherManager.getId(), ANOTHER_MANAGER_ID); + assertEquals(MANAGER_ID, manager.getId()); + assertEquals(ANOTHER_MANAGER_ID, anotherManager.getId()); } @Test public void testGetParent() { - assertSame(manager.getParent(), item); - assertSame(anotherManager.getParent(), manager); + assertSame(item, manager.getParent()); + assertSame(manager, anotherManager.getParent()); } @Test public void testGetContext() { - System.out.println(); - assertSame(manager.getContext(), root); - assertSame(anotherManager.getContext(), manager); + assertSame(root, manager.getContext()); + assertSame(manager, anotherManager.getContext()); } @Test public void testGetURI() { - assertEquals(manager.getURI(), ITEM_ID + Item.SEP + MANAGER_ID); - assertEquals(anotherManager.getURI(), ANOTHER_MANAGER_ID); + assertEquals(ITEM_ID + Item.SEP + MANAGER_ID, manager.getURI()); + assertEquals(ANOTHER_MANAGER_ID, anotherManager.getURI()); } @Test public void testGetFullURI() { - assertEquals(manager.getFullURI(), Item.SEP + ITEM_ID + Item.SEP + MANAGER_ID); - assertEquals(anotherManager.getFullURI(), Item.SEP + ITEM_ID + Item.SEP + MANAGER_ID + Item.SEP + ANOTHER_MANAGER_ID); + assertEquals(Item.SEP + ITEM_ID + Item.SEP + MANAGER_ID, manager.getFullURI()); + assertEquals(Item.SEP + ITEM_ID + Item.SEP + MANAGER_ID + Item.SEP + ANOTHER_MANAGER_ID, anotherManager.getFullURI()); } @Test public void testLocate() { // anotherItem is local - assertSame(manager.locate(anotherItem.getURI()), anotherItem); - assertSame(manager.locate(anotherItem.getFullURI()), anotherItem); + assertSame(anotherItem, manager.locate(anotherItem.getURI())); + assertSame(anotherItem, manager.locate(anotherItem.getFullURI())); // item is not local assertNull(manager.locate(item.getURI())); - assertSame(manager.locate(item.getFullURI()), item); + assertSame(item, manager.locate(item.getFullURI())); // manager is not local in itself, but in root assertNull(manager.locate(manager.getURI())); - assertSame(root.locate(manager.getURI()), manager); - assertSame(manager.locate(manager.getFullURI()), manager); + assertSame(manager, root.locate(manager.getURI())); + assertSame(manager, manager.locate(manager.getFullURI())); // anotherManager is not local in itself, but in manager assertNull(anotherManager.locate(anotherManager.getURI())); - assertSame(manager.locate(anotherManager.getURI()), anotherManager); - assertSame(anotherManager.locate(anotherManager.getFullURI()), anotherManager); + assertSame(anotherManager, manager.locate(anotherManager.getURI())); + assertSame(anotherManager, anotherManager.locate(anotherManager.getFullURI())); } @Test public void testGetRoot() { - assertSame(manager.getRoot(), root); - assertSame(anotherManager.getRoot(), root); + assertSame(root, manager.getRoot()); + assertSame(root, anotherManager.getRoot()); } } diff --git a/junit/rails/game/state/RootTest.java b/junit/rails/game/state/RootTest.java index c98adfd..2f686c9 100644 --- a/junit/rails/game/state/RootTest.java +++ b/junit/rails/game/state/RootTest.java @@ -37,43 +37,43 @@ public class RootTest { @Test public void testGetId() { - assertEquals(root.getId(), Root.ID); + assertEquals(Root.ID, root.getId()); } @Test public void testGetContext() { - assertSame(root.getContext(), root); + assertSame(root, root.getContext()); } @Test public void testGetRoot() { - assertSame(root.getRoot(), root); + assertSame(root, root.getRoot()); } @Test public void testGetURI() { - assertSame(root.getURI(), Root.ID); + assertSame(Root.ID, root.getURI()); } @Test public void testGetFullURI() { - assertSame(root.getFullURI(), Root.ID); + assertSame(Root.ID, root.getFullURI()); } @Test public void testLocate() { // item is local - assertSame(root.locate(item.getURI()), item); - assertSame(root.locate(item.getFullURI()), item); + assertSame(item, root.locate(item.getURI())); + assertSame(item, root.locate(item.getFullURI())); // manager is local - assertSame(root.locate(manager.getURI()), manager); - assertSame(root.locate(manager.getFullURI()), manager); + assertSame(manager, root.locate(manager.getURI())); + assertSame(manager, root.locate(manager.getFullURI())); // anotherItem is not local assertNull(root.locate(anotherItem.getURI())); assertSame(root.locate(anotherItem.getFullURI()), anotherItem); // root is local in root - assertSame(root.locate(root.getURI()), root); - assertSame(root.locate(root.getFullURI()), root); + assertSame(root, root.locate(root.getURI())); + assertSame(root, root.locate(root.getFullURI())); // and if item is removed it is not found anymore root.removeItem(item); assertNull(root.locate(item.getURI())); @@ -88,7 +88,7 @@ public class RootTest { public void testAddItemSuccess() { root.removeItem(item); root.addItem(item); - assertSame(root.locate(item.getFullURI()), item); + assertSame(item, root.locate(item.getFullURI())); } public void testRemoveItemSuccess() { commit f324c698103cbc65d49fceecaf0b468d350e2d2e Author: Stefan Frey <ste...@we...> Date: Fri Jul 6 10:41:17 2012 +0200 added ObservableTest diff --git a/junit/rails/game/state/AbstractItemImpl.java b/junit/rails/game/state/AbstractItemImpl.java index 3aec737..5249e89 100644 --- a/junit/rails/game/state/AbstractItemImpl.java +++ b/junit/rails/game/state/AbstractItemImpl.java @@ -1,5 +1,6 @@ package rails.game.state; +// Implementation for Testing only class AbstractItemImpl extends AbstractItem { AbstractItemImpl(Item parent, String id) { super(parent, id); diff --git a/junit/rails/game/state/ManagerImpl.java b/junit/rails/game/state/ManagerImpl.java index a6fdf00..477fb3f 100644 --- a/junit/rails/game/state/ManagerImpl.java +++ b/junit/rails/game/state/ManagerImpl.java @@ -1,5 +1,6 @@ package rails.game.state; +// Implementation for Testing only class ManagerImpl extends Manager { ManagerImpl(Item parent, String id) { super(parent, id); diff --git a/junit/rails/game/state/ObservableTest.java b/junit/rails/game/state/ObservableTest.java new file mode 100644 index 0000000..2e2000b --- /dev/null +++ b/junit/rails/game/state/ObservableTest.java @@ -0,0 +1,166 @@ +package rails.game.state; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; +import static org.fest.assertions.api.Assertions.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ObservableTest { + + // Implementation for Testing only + private class ObservableImpl extends Observable { + ObservableImpl(Item parent, String id) { + super(parent, id); + } + + @Override + public String getText() { + return null; + } + } + + private final static String MANAGER_ID = "Manager"; + private final static String ITEM_ID = "Item"; + private final static String OBS_ID = "Observable"; + + private Root root; + private Manager manager; + private Item item; + private Observable observable, unobservable; + @Mock private Observer observer; + @Mock private Model model; + + @Before + public void setUp() { + root = Root.create(); + manager = new ManagerImpl(root, MANAGER_ID); + item = new AbstractItemImpl(manager, ITEM_ID); + observable = new ObservableImpl(item, OBS_ID); + unobservable = new ObservableImpl(root, null); + } + + + @Test + public void testObservers() { + // add observer and test if contained + observable.addObserver(observer); + assertThat(observable.getObservers()).contains(observer); + + // remove observer and test if not contained + assertTrue(observable.removeObserver(observer)); + assertThat(observable.getObservers()).doesNotContain(observer); + + // remove observer not contained anymore + assertFalse(observable.removeObserver(observer)); + + // Check failing on unobservable + try { + unobservable.addObserver(observer); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + try { + unobservable.removeObserver(observer); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + try { + unobservable.getObservers(); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + } + + @Test + public void testModels() { + // add observer and test if contained + observable.addModel(model); + assertThat(observable.getModels()).contains(model); + + // check update + observable.updateModels(); + verify(model).update(); + + // remove Model and test if not contained + assertTrue(observable.removeModel(model)); + assertThat(observable.getModels()).doesNotContain(model); + observable.updateModels(); + // still only called once(!) + verify(model).update(); + + // remove Model not contained anymore + assertFalse(observable.removeModel(model)); + + // Check failing on unobservable + try { + unobservable.addModel(model); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + try { + unobservable.removeModel(model); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + try { + unobservable.getModels(); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + + } + + @Test + public void testGetId() { + assertEquals(OBS_ID, observable.getId()); + assertEquals(null, unobservable.getId()); + } + + @Test + public void testGetParent() { + assertSame(item, observable.getParent()); + assertSame(root, unobservable.getParent()); + } + + @Test + public void testGetContext() { + assertSame(manager, observable.getContext()); + assertSame(root, unobservable.getContext()); + } + + @Test + public void testGetRoot() { + assertSame(root, observable.getRoot()); + assertSame(root, unobservable.getRoot()); + } + + @Test + public void testGetURI() { + assertEquals(ITEM_ID + Item.SEP + OBS_ID, observable.getURI()); + assertSame(observable, observable.getContext().locate(observable.getURI())); + try { + unobservable.getURI(); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + } + + @Test + public void testGetFullURI() { + assertEquals(Item.SEP + MANAGER_ID + Item.SEP + ITEM_ID + Item.SEP + OBS_ID, observable.getFullURI()); + assertSame(observable, observable.getContext().locate(observable.getURI())); + assertSame(observable, observable.getRoot().locate(observable.getFullURI())); + try { + unobservable.getFullURI(); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + } + +} diff --git a/src/rails/game/state/Observable.java b/src/rails/game/state/Observable.java index 3272391..0ac1ffb 100644 --- a/src/rails/game/state/Observable.java +++ b/src/rails/game/state/Observable.java @@ -33,7 +33,13 @@ public abstract class Observable implements Item { // defined standard fields this.parent = parent; this.id = id; - context = parent.getContext(); + + if (parent instanceof Context) { + context = (Context)parent; + } else { + // recursive definition + context = parent.getContext(); + } // if id is null this is an "unobservable" observable if (id == null) { @@ -42,6 +48,8 @@ public abstract class Observable implements Item { } else { observers = HashSetState.create(this, null); models = HashSetState.create(this, null); + // add item to context if it has an id + context.addItem(this); } } @@ -108,7 +116,7 @@ public abstract class Observable implements Item { public String getURI() { checkState(id != null, "Cannot get URI of unobservable object"); - if (parent instanceof Manager) { + if (parent instanceof Context) { return id; } else { // recursive definition |
From: Stefan F. <ste...@us...> - 2012-07-06 03:53:08
|
junit/rails/game/state/ActionChangeSetTest.java | 105 +---- junit/rails/game/state/AutoChangeSetTest.java | 68 +++ junit/rails/game/state/ChangeStackTest.java | 186 ++++----- junit/rails/game/state/ManagerTest.java | 86 ++++ junit/rails/game/state/RootTest.java | 18 src/rails/game/Company.java | 2 src/rails/game/GameManager.java | 76 ++- src/rails/game/MapHex.java | 6 src/rails/game/Player.java | 6 src/rails/game/PublicCompany.java | 18 src/rails/game/ReportBuffer.java | 16 src/rails/game/Round.java | 2 src/rails/game/StockRound.java | 6 src/rails/game/Train.java | 2 src/rails/game/TrainCertificateType.java | 4 src/rails/game/TrainManager.java | 2 src/rails/game/TreasuryShareRound.java | 8 src/rails/game/correct/CorrectionManager.java | 4 src/rails/game/model/CashMoneyModel.java | 6 src/rails/game/model/MoneyModel.java | 4 src/rails/game/special/SpecialProperty.java | 2 src/rails/game/specific/_1835/OperatingRound_1835.java | 6 src/rails/game/specific/_1856/CGRFormationRound.java | 2 src/rails/game/specific/_1856/OperatingRound_1856.java | 2 src/rails/game/specific/_1856/PublicCompany_CGR.java | 4 src/rails/game/specific/_1889/OperatingRound_1889.java | 8 src/rails/game/specific/_18EU/FinalMinorExchangeRound.java | 4 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 4 src/rails/game/specific/_18EU/StockRound_18EU.java | 10 src/rails/game/specific/_18TN/PublicCompany_18TN.java | 2 src/rails/game/state/AbstractItem.java | 10 src/rails/game/state/ActionChangeSet.java | 10 src/rails/game/state/AutoChangeSet.java | 19 src/rails/game/state/BooleanChange.java | 2 src/rails/game/state/BooleanState.java | 2 src/rails/game/state/Change.java | 2 src/rails/game/state/ChangeSet.java | 12 src/rails/game/state/ChangeStack.java | 265 ++++--------- src/rails/game/state/Context.java | 4 src/rails/game/state/Manager.java | 21 - src/rails/game/state/Root.java | 13 src/rails/game/state/StateManager.java | 9 src/rails/game/state/StringChange.java | 2 src/rails/game/state/StringState.java | 2 src/rails/ui/swing/GridPanel.java | 2 src/rails/ui/swing/ReportWindowDynamic.java | 7 46 files changed, 574 insertions(+), 477 deletions(-) New commits: commit 9556b67b9fd599445253dcef4ff9a4fc8041b811 Author: Stefan Frey <ste...@we...> Date: Thu Jul 5 17:28:06 2012 +0200 updated ChangeStack and ChangeSet and added tests diff --git a/junit/rails/game/state/AutoChangeSetTest.java b/junit/rails/game/state/AutoChangeSetTest.java index 384d702..83aee84 100644 --- a/junit/rails/game/state/AutoChangeSetTest.java +++ b/junit/rails/game/state/AutoChangeSetTest.java @@ -29,7 +29,7 @@ public class AutoChangeSetTest { state = BooleanState.create(root, STATE_ID); state.addModel(model); changeStack = root.getStateManager().getChangeStack(); - changeSet = changeStack.startAutoChangeSet(); + changeSet = changeStack.closeCurrentChangeSet(); } @Test diff --git a/junit/rails/game/state/ChangeStackTest.java b/junit/rails/game/state/ChangeStackTest.java new file mode 100644 index 0000000..d1d04ef --- /dev/null +++ b/junit/rails/game/state/ChangeStackTest.java @@ -0,0 +1,122 @@ +package rails.game.state; + +import static org.junit.Assert.*; +import static org.fest.assertions.api.Assertions.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import rails.game.Player; +import rails.game.action.PossibleAction; + +@RunWith(MockitoJUnitRunner.class) +public class ChangeStackTest { + + private final static String STATE_ID = "State"; + + private Root root; + private BooleanState state; + private ChangeStack changeStack; + + private AutoChangeSet auto_1, auto_2, auto_3; + private ActionChangeSet action_1, action_2, action_3; + @Mock Player player; + @Mock PossibleAction action; + + @Before + public void setUp() { + root = Root.create(); + state = BooleanState.create(root, STATE_ID); + changeStack = root.getStateManager().getChangeStack(); + auto_1 = (AutoChangeSet)changeStack.getCurrentChangeSet(); + action_1 = changeStack.startActionChangeSet(player, action); + auto_2 = changeStack.closeCurrentChangeSet(); + state.set(true); + auto_3 = changeStack.closeCurrentChangeSet(); + action_2 = changeStack.startActionChangeSet(player, action); + state.set(false); + action_3 = changeStack.startActionChangeSet(player, action); + } + + @Test + public void testGetCurrentChangeSet() { + assertSame(changeStack.getCurrentChangeSet(), action_3); + // on the stack there are auto_1, action_1, auto_2, action_2 + assertEquals(changeStack.sizeUndoStack(), 4); + } + + @Test + public void testCloseCurrentChangeSet() { + changeStack.closeCurrentChangeSet(); + assertTrue(action_3.isClosed()); + assertSame(changeStack.getLastClosedChangeSet(), action_3); + // and now action_3 is added + assertEquals(changeStack.sizeUndoStack(), 5); + } + + @Test + public void testUndo() { + assertFalse(state.value()); + // undo action 3 + assertTrue(changeStack.undo()); + assertEquals(changeStack.sizeUndoStack(), 4); + assertSame(changeStack.getLastClosedChangeSet(), action_2); + assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(state.value()); + // undo action 2 + assertTrue(changeStack.undo()); + assertEquals(changeStack.sizeUndoStack(), 3); + assertSame(changeStack.getLastClosedChangeSet(), auto_2); + assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertTrue(state.value()); + // undo auto_2 and action 1 + assertTrue(changeStack.undo()); + assertEquals(changeStack.sizeUndoStack(), 1); + assertSame(changeStack.getLastClosedChangeSet(), auto_1); + assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(state.value()); + // undo should not do anything now + assertFalse(changeStack.undo()); + |
From: Stefan F. <ste...@us...> - 2012-07-03 04:42:37
|
.classpath | 4 ++-- dev/null |binary junit/lib/junit-4.8.2/junit.jar |binary junit/lib/mockito-1.9.0/mockito-all-1.9.0.jar |binary 4 files changed, 2 insertions(+), 2 deletions(-) New commits: commit 3e374b0d5123b3da737cb84207110a6de56c48bb Author: Stefan Frey <ste...@we...> Date: Tue Jul 3 06:42:19 2012 +0200 moved junit and mockito libraries into junit path diff --git a/.classpath b/.classpath index 7893f0d..91fbdc8 100644 --- a/.classpath +++ b/.classpath @@ -12,12 +12,12 @@ <classpathentry kind="lib" path="src/lib/guava-r09/guava-r09.jar"/> <classpathentry kind="lib" path="src/lib/jgraph5/jgraph.jar"/> <classpathentry kind="lib" path="src/lib/jgrapht-0.7.3/jgrapht-jdk1.5.jar"/> - <classpathentry kind="lib" path="src/lib/junit-4.8.2/junit.jar"/> <classpathentry kind="lib" path="src/lib/logback-1.0.4/logback-classic-1.0.4.jar"/> <classpathentry kind="lib" path="src/lib/logback-1.0.4/logback-core-1.0.4.jar"/> <classpathentry kind="lib" path="src/lib/sl4j-1.6.5/slf4j-api-1.6.5.jar"/> - <classpathentry kind="lib" path="src/lib/mockito-1.9.0/mockito-all-1.9.0.jar"/> <classpathentry kind="lib" path="junit/lib/fest-2.0M5/fest-assert-core-2.0M5.jar"/> <classpathentry kind="lib" path="junit/lib/fest-2.0M5/fest-util-1.2.0.jar"/> + <classpathentry kind="lib" path="junit/lib/junit-4.8.2/junit.jar"/> + <classpathentry kind="lib" path="junit/lib/mockito-1.9.0/mockito-all-1.9.0.jar"/> <classpathentry kind="output" path="classes"/> </classpath> diff --git a/junit/lib/junit-4.8.2/junit.jar b/junit/lib/junit-4.8.2/junit.jar new file mode 100644 index 0000000..5b4bb84 Binary files /dev/null and b/junit/lib/junit-4.8.2/junit.jar differ diff --git a/junit/lib/mockito-1.9.0/mockito-all-1.9.0.jar b/junit/lib/mockito-1.9.0/mockito-all-1.9.0.jar new file mode 100644 index 0000000..273fd50 Binary files /dev/null and b/junit/lib/mockito-1.9.0/mockito-all-1.9.0.jar differ diff --git a/src/lib/junit-4.8.2/junit.jar b/src/lib/junit-4.8.2/junit.jar deleted file mode 100644 index 5b4bb84..0000000 Binary files a/src/lib/junit-4.8.2/junit.jar and /dev/null differ diff --git a/src/lib/mockito-1.9.0/mockito-all-1.9.0.jar b/src/lib/mockito-1.9.0/mockito-all-1.9.0.jar deleted file mode 100644 index 273fd50..0000000 Binary files a/src/lib/mockito-1.9.0/mockito-all-1.9.0.jar and /dev/null differ |
From: Stefan F. <ste...@us...> - 2012-07-03 04:37:20
|
.classpath | 2 junit/lib/fest-2.0M5/fest-assert-core-2.0M5.jar |binary junit/lib/fest-2.0M5/fest-util-1.2.0.jar |binary junit/rails/game/state/AbstractItemImpl.java | 7 + junit/rails/game/state/AbstractItemTest.java | 63 ++++++++++++++ junit/rails/game/state/ChangeStackTest.java | 7 - junit/rails/game/state/ManagerImpl.java | 7 + junit/rails/game/state/RootTest.java | 97 +++++++++++++++++++++ src/rails/common/parser/ComponentManager.java | 6 - src/rails/common/parser/GameFileParser.java | 4 src/rails/game/Game.java | 2 src/rails/game/GameManager.java | 2 src/rails/game/state/AbstractItem.java | 16 ++- src/rails/game/state/ArrayListChange.java | 4 src/rails/game/state/AutoChangeSet.java | 14 --- src/rails/game/state/BooleanChange.java | 2 src/rails/game/state/Change.java | 6 - src/rails/game/state/ChangeStack.java | 56 +++++------- src/rails/game/state/Context.java | 10 -- src/rails/game/state/GenericStateChange.java | 2 src/rails/game/state/HashMapChange.java | 4 src/rails/game/state/HashSetChange.java | 2 src/rails/game/state/IntegerChange.java | 2 src/rails/game/state/Item.java | 2 src/rails/game/state/Manager.java | 66 ++++---------- src/rails/game/state/MultimapChange.java | 2 src/rails/game/state/Observable.java | 106 ++++++++++++++++++------ src/rails/game/state/PortfolioChange.java | 2 src/rails/game/state/Root.java | 45 ++++------ src/rails/game/state/State.java | 19 +--- src/rails/game/state/StateManager.java | 39 +++----- src/rails/game/state/StringChange.java | 2 src/rails/game/state/WalletChange.java | 2 33 files changed, 390 insertions(+), 210 deletions(-) New commits: commit d776000fd05b1081b7ee4668fb91237553afe125 Author: Stefan Frey <ste...@we...> Date: Tue Jul 3 06:36:39 2012 +0200 further refactoring of item mechanisms, added tests for root and item, added FEST assertions libraries diff --git a/.classpath b/.classpath index 724802d..7893f0d 100644 --- a/.classpath +++ b/.classpath @@ -17,5 +17,7 @@ <classpathentry kind="lib" path="src/lib/logback-1.0.4/logback-core-1.0.4.jar"/> <classpathentry kind="lib" path="src/lib/sl4j-1.6.5/slf4j-api-1.6.5.jar"/> <classpathentry kind="lib" path="src/lib/mockito-1.9.0/mockito-all-1.9.0.jar"/> + <classpathentry kind="lib" path="junit/lib/fest-2.0M5/fest-assert-core-2.0M5.jar"/> + <classpathentry kind="lib" path="junit/lib/fest-2.0M5/fest-util-1.2.0.jar"/> <classpathentry kind="output" path="classes"/> </classpath> diff --git a/junit/lib/fest-2.0M5/fest-assert-core-2.0M5.jar b/junit/lib/fest-2.0M5/fest-assert-core-2.0M5.jar new file mode 100644 index 0000000..e7c4b78 Binary files /dev/null and b/junit/lib/fest-2.0M5/fest-assert-core-2.0M5.jar differ diff --git a/junit/lib/fest-2.0M5/fest-util-1.2.0.jar b/junit/lib/fest-2.0M5/fest-util-1.2.0.jar new file mode 100644 index 0000000..560c705 Binary files /dev/null and b/junit/lib/fest-2.0M5/fest-util-1.2.0.jar differ diff --git a/junit/rails/game/state/AbstractItemImpl.java b/junit/rails/game/state/AbstractItemImpl.java new file mode 100644 index 0000000..3aec737 --- /dev/null +++ b/junit/rails/game/state/AbstractItemImpl.java @@ -0,0 +1,7 @@ +package rails.game.state; + +class AbstractItemImpl extends AbstractItem { + AbstractItemImpl(Item parent, String id) { + super(parent, id); + } +} diff --git a/junit/rails/game/state/AbstractItemTest.java b/junit/rails/game/state/AbstractItemTest.java new file mode 100644 index 0000000..19c994e --- /dev/null +++ b/junit/rails/game/state/AbstractItemTest.java @@ -0,0 +1,63 @@ +package rails.game.state; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +public class AbstractItemTest { + + private static final String MANAGER_ID = "manager"; + private static final String ITEM_ID = "item"; + private static final String ANOTHER_ID = "anotherItem"; + + private Root root; + private Manager manager; + private Item item; + private Item anotherItem; + + @Before + public void setUp() { + root = Root.create(); + manager = new ManagerImpl(root, MANAGER_ID); + item = new AbstractItemImpl(manager, ITEM_ID); + anotherItem = new AbstractItemImpl(item, ANOTHER_ID); + } + + @Test + public void testGetId() { + assertEquals(item.getId(), ITEM_ID); + assertEquals(anotherItem.getId(), ANOTHER_ID); + } + + @Test + public void testGetParent() { + assertSame(item.getParent(), manager); + assertSame(anotherItem.getParent(), item); + } + + @Test + public void testGetContext() { + assertSame(item.getContext(), manager); + assertSame(anotherItem.getContext(), manager); + } + + @Test + public void testGetRoot() { + assertSame(item.getRoot(), root); + assertSame(anotherItem.getRoot(), root); + } + + @Test + public void testGetURI() { + assertEquals(item.getURI(), ITEM_ID); + assertEquals(anotherItem.getURI(), ITEM_ID + Item.SEP + ANOTHER_ID); + } + + @Test + public void testGetFullURI() { + assertEquals(item.getFullURI(), Item.SEP + MANAGER_ID + Item.SEP + ITEM_ID); + assertEquals(anotherItem.getFullURI(), Item.SEP + MANAGER_ID+ Item.SEP + ITEM_ID + Item.SEP + ANOTHER_ID); + } + +} diff --git a/junit/rails/game/state/ChangeStackTest.java b/junit/rails/game/state/ChangeStackTest.java index 04dbb87..67a8618 100644 --- a/junit/rails/game/state/ChangeStackTest.java +++ b/junit/rails/game/state/ChangeStackTest.java @@ -16,13 +16,6 @@ public class ChangeStackTest { assertNotNull(stack); } - @Test - public void testEnable() { - ChangeStack stack = ChangeStack.create(sm); - assertFalse(stack.isEnabled()); - stack.enable(); - assertTrue(stack.isEnabled()); - } @Test public void testIsEnabled() { diff --git a/junit/rails/game/state/ManagerImpl.java b/junit/rails/game/state/ManagerImpl.java new file mode 100644 index 0000000..a6fdf00 --- /dev/null +++ b/junit/rails/game/state/ManagerImpl.java @@ -0,0 +1,7 @@ +package rails.game.state; + +class ManagerImpl extends Manager { + ManagerImpl(Item parent, String id) { + super(parent, id); + } +} diff --git a/junit/rails/game/state/RootTest.java b/junit/rails/game/state/RootTest.java new file mode 100644 index 0000000..97b4482 --- /dev/null +++ b/junit/rails/game/state/RootTest.java @@ -0,0 +1,97 @@ +package rails.game.state; + +import static org.junit.Assert.*; +import static org.fest.assertions.api.Assertions.assertThat; + +import org.junit.Before; +import org.junit.Test; + +public class RootTest { + + private static final String MANAGER_ID = "manager"; + private static final String ITEM_ID = "item"; + private static final String ANOTHER_ID = "anotherItem"; + + private Root root; + private Manager manager; + private Item item; + private Item anotherItem; + + @Before + public void setUp() { + root = Root.create(); + manager = new ManagerImpl(root, MANAGER_ID); + item = new AbstractItemImpl(root, ITEM_ID); + anotherItem = new AbstractItemImpl(manager, ANOTHER_ID); + } + + @Test + public void testGetStateManager() { + assertThat(root.getStateManager()).isInstanceOf(StateManager.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void testGetParent() { + root.getParent(); + } + + @Test + public void testGetId() { + assertEquals(root.getId(), Root.ID); + } + + @Test + public void testGetContext() { + assertSame(root.getContext(), root); + } + + @Test + public void testGetRoot() { + assertSame(root.getRoot(), root); + } + + @Test + public void testGetURI() { + assertSame(root.getURI(), Root.ID); + } + + @Test + public void testGetFullURI() { + assertSame(root.getFullURI(), Root.ID); + } + + @Test + public void testLocate() { + assertSame(root.locate(item.getFullURI()), item); + assertSame(root.locate(anotherItem.getFullURI()), anotherItem); + } + + @Test + public void testLocateFail() { + root.removeItem(item); + assertNull(root.locate(item.getFullURI())); + } + + @Test(expected=IllegalArgumentException.class) + public void testAddItemFail() { + root.addItem(item); + } + + public void testAddItemSuccess() { + root.removeItem(item); + root.addItem(item); + assertSame(root.locate(item.getFullURI()), item); + } + + public void testRemoveItemSuccess() { + root.removeItem(item); + root.locate(item.getFullURI()); + } + + @Test(expected=IllegalArgumentException.class) + public void testRemoveItemFail() { + root.removeItem(item); + root.removeItem(item); + } + +} diff --git a/src/rails/common/parser/ComponentManager.java b/src/rails/common/parser/ComponentManager.java index 3e0d57f..daa7f30 100644 --- a/src/rails/common/parser/ComponentManager.java +++ b/src/rails/common/parser/ComponentManager.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; import rails.common.parser.XMLTags; -import rails.game.state.Manager; +import rails.game.state.Context; /** * ComponentManage - an implementation of ComponentManagerI, which handles the @@ -28,7 +28,7 @@ public class ComponentManager { private Map<String, ConfigurableComponent> mComponentMap = new HashMap<String, ConfigurableComponent>(); - public ComponentManager(Manager context, 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; @@ -41,7 +41,7 @@ public class ComponentManager { } } - private void configureComponent(Manager context, Tag componentTag) + private void configureComponent(Context context, Tag componentTag) throws ConfigurationException { // Extract the attributes of the Component diff --git a/src/rails/common/parser/GameFileParser.java b/src/rails/common/parser/GameFileParser.java index f4ebe84..c1b6fd5 100644 --- a/src/rails/common/parser/GameFileParser.java +++ b/src/rails/common/parser/GameFileParser.java @@ -15,7 +15,7 @@ import rails.game.PlayerManager; import rails.game.StockMarket; import rails.game.TileManager; import rails.game.TrainManager; -import rails.game.state.Manager; +import rails.game.state.Root; public class GameFileParser extends XMLParser { private static String GAME_XML_FILE = "Game.xml"; @@ -34,7 +34,7 @@ public class GameFileParser extends XMLParser { private RevenueManager revenueManager; private Bank bank; - public GameFileParser(Manager context, String name, Map<String, String> gameOptions) { + public GameFileParser(Root context, String name, Map<String, String> gameOptions) { directories.add("data/" + name); diff --git a/src/rails/game/Game.java b/src/rails/game/Game.java index b71533c..3140cb0 100644 --- a/src/rails/game/Game.java +++ b/src/rails/game/Game.java @@ -77,7 +77,7 @@ public class Game { public boolean setup() { // first define root GameContext to be able to define states - Root root = Root.create("states"); + Root root = Root.create(); GameFileParser gfp = new GameFileParser(root, name, gameOptions); playerManager = gfp.getPlayerManager(); diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index 9fa593e..db9d978 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -567,7 +567,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, } // Initialisation is complete. Undoability starts here. - changeStack.enable(); + // changeStack.enable(); } private void setGuiParameters () { diff --git a/src/rails/game/state/AbstractItem.java b/src/rails/game/state/AbstractItem.java index e76ec25..531724f 100644 --- a/src/rails/game/state/AbstractItem.java +++ b/src/rails/game/state/AbstractItem.java @@ -9,6 +9,7 @@ public abstract class AbstractItem implements Item { private final String id; private final Item parent; + private final Context context; protected AbstractItem(Item parent, String id){ checkNotNull(parent, "Parent cannot be null"); @@ -18,9 +19,10 @@ public abstract class AbstractItem implements Item { // defined standard fields this.parent = parent; this.id = id; + context = parent.getContext(); // add item to context - parent.getContext().addItem(this); + context.addItem(this); } public String getId() { @@ -32,12 +34,12 @@ public abstract class AbstractItem implements Item { } public Context getContext() { - if (parent instanceof Manager) { - return (Manager)parent; - } else { - // recursive definition - return parent.getContext(); - } + return context; + } + + public Root getRoot() { + // forward it to the context + return context.getRoot(); } public String getURI() { diff --git a/src/rails/game/state/ArrayListChange.java b/src/rails/game/state/ArrayListChange.java index 4e28257..f9016c1 100644 --- a/src/rails/game/state/ArrayListChange.java +++ b/src/rails/game/state/ArrayListChange.java @@ -21,22 +21,22 @@ final class ArrayListChange<E> extends Change { * Add object at the specified index */ ArrayListChange(ArrayListState<E> state, E object, int index) { - super(state); this.state = state; this.object = object; this.index = index; this.addToList = true; + super.init(state); } /** * Remove object at the specified index */ ArrayListChange(ArrayListState<E> state, int index) { - super(state); this.state = state; this.object = state.get(index); this.index = index; this.addToList = false; + super.init(state); } @Override diff --git a/src/rails/game/state/AutoChangeSet.java b/src/rails/game/state/AutoChangeSet.java index b1e8de8..11fe5a3 100644 --- a/src/rails/game/state/AutoChangeSet.java +++ b/src/rails/game/state/AutoChangeSet.java @@ -3,20 +3,12 @@ package rails.game.state; import rails.game.Player; /** - * AutoChangeSets are linked to previous ActionChangeSets - * @author freystef + * AutoChangeSets are ChangeSets that belong to no action directly */ final class AutoChangeSet extends ChangeSet { - private final ActionChangeSet previous; - AutoChangeSet(ActionChangeSet previous) { - this.previous = previous; - } - - ActionChangeSet getPrevious() { - return previous; - } + AutoChangeSet() {} @Override boolean isUndoableByPlayer(Player player) { @@ -25,7 +17,7 @@ final class AutoChangeSet extends ChangeSet { @Override public String toString() { - return "AutoChangeSet linked to action " + previous.getAction(); + return "AutoChangeSet"; } } diff --git a/src/rails/game/state/BooleanChange.java b/src/rails/game/state/BooleanChange.java index b899756..be51279 100644 --- a/src/rails/game/state/BooleanChange.java +++ b/src/rails/game/state/BooleanChange.java @@ -12,10 +12,10 @@ final class BooleanChange extends Change { private final boolean oldValue; BooleanChange(BooleanState state, boolean newValue) { - super(state); this.state = state; this.newValue = newValue; this.oldValue = state.booleanValue(); + super.init(state); } @Override diff --git a/src/rails/game/state/Change.java b/src/rails/game/state/Change.java index ec1d12a..8fd74c2 100644 --- a/src/rails/game/state/Change.java +++ b/src/rails/game/state/Change.java @@ -3,13 +3,11 @@ package rails.game.state; * Base Class for all Change Objects * * Replaces previous move interface - * - * @author freystef */ abstract class Change { - Change(State state){ - state.getStateManager().addChangeToStack(this); + protected void init(State state){ + state.getRoot().getStateManager().addChangeToStack(this); } abstract void execute(); diff --git a/src/rails/game/state/ChangeStack.java b/src/rails/game/state/ChangeStack.java index 3090ae0..7b7e52f 100644 --- a/src/rails/game/state/ChangeStack.java +++ b/src/rails/game/state/ChangeStack.java @@ -9,50 +9,32 @@ import rails.game.Player; import rails.game.ReportBuffer; import rails.game.action.PossibleAction; -public class ChangeStack extends AbstractItem { +public class ChangeStack { protected static Logger log = LoggerFactory.getLogger(ChangeStack.class.getPackage().getName()); private final LinkedList<ChangeSet> stack = new LinkedList<ChangeSet>(); - - private boolean enabled = false; + private final StateManager stateManager; - protected ChangeStack(Item parent, String id){ - super(parent, id); + private ChangeStack(StateManager parent) { + stateManager = parent; } /** * @param parent restricted to StateManager - * ID set to class name */ public static ChangeStack create(StateManager parent) { - return new ChangeStack(parent , ChangeStack.class.getSimpleName()); - } - - /** - * Start making moves undoable. Will be called once, after all - * initialisations are complete. - */ - public void enable() { - enabled = true; - } - - public boolean isEnabled() { - return enabled; + ChangeStack changeStack = new ChangeStack(parent); + changeStack.initAutoChangeSet(); + return changeStack; } - private void checkEnabled() { - if (!enabled) throw new IllegalStateException("ChangeStack is not enabled"); - } - /** * Returns a valid ChangeSet that is current for the ChangeStack * If the ChangeStack is not enabled or empty a IllegalStateExcpetion is thrown * @return the current changeSet */ public ChangeSet getAvailableChangeSet() { - // check preconditions - checkEnabled(); if (stack.isEmpty()) throw new IllegalStateException("No ChangeSet on ChangeStack"); // return the last on the @@ -77,6 +59,23 @@ public class ChangeStack extends AbstractItem { } return changeSet; } + + /** + * Creates new AutoChangeSet + */ + public AutoChangeSet initAutoChangeSet() { + if (stack.peekLast() != null && !stack.peekLast().isClosed()) + throw new IllegalStateException("Current ChangeSet not closed yet"); + + // create new ChangeSet + AutoChangeSet changeSet = new AutoChangeSet(); + + stack.offerLast(changeSet); + log.debug(">>> Start AutoChangeSet " + changeSet + " at index=" + stack.size() + " <<<"); + + return changeSet; + } + /** * Creates new ActionChangeSet @@ -85,9 +84,6 @@ public class ChangeStack extends AbstractItem { * @return the new current ChangeSet */ public ActionChangeSet start(Player player, PossibleAction action) { - - // check preconditions - checkEnabled(); if (stack.peekLast() != null && !stack.peekLast().isClosed()) throw new IllegalStateException("Current ChangeSet not closed yet"); @@ -159,11 +155,11 @@ public class ChangeStack extends AbstractItem { } public boolean isUndoableByManager() { - return enabled && stack.size() != 0; + return stack.size() != 0; } public boolean isOpen() { - return enabled && stack.size() != 0 && !getAvailableChangeSet().isClosed(); + return stack.size() != 0 && !getAvailableChangeSet().isClosed(); } // TODO: What is correct? diff --git a/src/rails/game/state/Context.java b/src/rails/game/state/Context.java index 487e1e3..9d5520c 100644 --- a/src/rails/game/state/Context.java +++ b/src/rails/game/state/Context.java @@ -2,14 +2,12 @@ package rails.game.state; /** * A context describe a service that allows to locate items */ -public interface Context extends Item { +public abstract class Context implements Item { - public Item localize(String uri); + public abstract Item locate(String uri); - public void addItem(Item item); + abstract void addItem(Item item); - public void removeItem(Item item); - - public Root getRoot(); + abstract void removeItem(Item item); } diff --git a/src/rails/game/state/GenericStateChange.java b/src/rails/game/state/GenericStateChange.java index 6922321..076f731 100644 --- a/src/rails/game/state/GenericStateChange.java +++ b/src/rails/game/state/GenericStateChange.java @@ -6,10 +6,10 @@ final class GenericStateChange<E> extends Change { final private E previous, next; public GenericStateChange(GenericState<E> state, E object) { - super(state); this.state = state; previous = state.get(); next = object; + super.init(state); } @Override diff --git a/src/rails/game/state/HashMapChange.java b/src/rails/game/state/HashMapChange.java index a3572bf..ac89844 100644 --- a/src/rails/game/state/HashMapChange.java +++ b/src/rails/game/state/HashMapChange.java @@ -16,26 +16,26 @@ final class HashMapChange<K,V> extends Change { * Put element into map */ HashMapChange(HashMapState<K,V> state, K key, V value) { - super(state); this.state = state; this.key = key; newValue = value; remove = false; oldValue = state.get(key); existed = state.containsKey(key); + super.init(state); } /** * Remove element from map */ HashMapChange(HashMapState<K,V> state, K key) { - super(state); this.state = state; this.key = key; newValue = null; remove = true; oldValue = state.get(key); existed = true; + super.init(state); } @Override diff --git a/src/rails/game/state/HashSetChange.java b/src/rails/game/state/HashSetChange.java index 31f260f..eaec2e4 100644 --- a/src/rails/game/state/HashSetChange.java +++ b/src/rails/game/state/HashSetChange.java @@ -12,10 +12,10 @@ final class HashSetChange<E> extends Change { * Add/Remove element to/from the set */ HashSetChange(HashSetState<E> state, E element, boolean addToSet){ - super(state); this.state = state; this.element = element; this.addToSet = addToSet; + super.init(state); } @Override diff --git a/src/rails/game/state/IntegerChange.java b/src/rails/game/state/IntegerChange.java index 55a56b3..0375d93 100644 --- a/src/rails/game/state/IntegerChange.java +++ b/src/rails/game/state/IntegerChange.java @@ -10,10 +10,10 @@ final class IntegerChange extends Change { private final int oldValue; IntegerChange(IntegerState state, int newValue) { - super(state); this.state = state; this.newValue = newValue; this.oldValue = state.value(); + super.init(state); } @Override diff --git a/src/rails/game/state/Item.java b/src/rails/game/state/Item.java index be16c84..d4a8877 100644 --- a/src/rails/game/state/Item.java +++ b/src/rails/game/state/Item.java @@ -21,6 +21,8 @@ public interface Item { Item getParent(); Context getContext(); + + Root getRoot(); /** * @return a string which allows to identify the item in the Context diff --git a/src/rails/game/state/Manager.java b/src/rails/game/state/Manager.java index 11d5a3b..2d995c5 100644 --- a/src/rails/game/state/Manager.java +++ b/src/rails/game/state/Manager.java @@ -4,36 +4,34 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; /** - * A Manager is an abstract implementation of a Context + * A Manager is a baseline implementation of a Context */ -public abstract class Manager implements Context { +public abstract class Manager extends Context { - // standard item fields + // item fields private final String id; private final Item parent; - - protected final Root root; - - // storage of items - protected final HashMapState<String, Item> items = HashMapState.create(this, "items"); + // context fields + private final Root root; + private final String fullURI; protected Manager(Item parent, String id) { checkNotNull(id, "Id cannot be null"); this.id = id; - if (this instanceof Root) { - this.parent = null; - this.root = null; - return; - } - // check arguments, parent can only be null for Root checkNotNull(parent, "Parent cannot be null"); this.parent = parent; + // URI defined recursively + fullURI = parent.getFullURI() + Item.SEP + id; + // find root and add context there root = parent.getContext().getRoot(); - root.addItem(this); + // add to root, except for StateManager, this is delayed + if (!(this instanceof StateManager)) { + root.addItem(this); + } } public String getId() { @@ -49,52 +47,30 @@ public abstract class Manager implements Context { } public String getURI() { - if (parent instanceof Manager) { - return id; - } else { - // recursive definition - return parent.getURI() + Item.SEP + id; - } + return ""; } public String getFullURI() { - // recursive definition - return parent.getFullURI() + Item.SEP + id; + return fullURI; } // Context methods - public Item localize(String uri) { - // either item can be found in the map - if (items.containsKey(uri)) { - return items.get(uri); - } else { - // otherwise search in root - return root.localize(uri); - } + public Item locate(String uri) { + return root.locate(fullURI + Item.SEP + uri); } - public void addItem(Item item) { + void addItem(Item item) { // check if this context is the containing one checkArgument(item.getContext() == this, "Context is not the container of the item to add"); - // check if it already exists - checkArgument(items.containsKey(item.getURI()), "Context already contains item with identical URI"); - - // all preconditions ok => add item - items.put(item.getURI(), item); // add item to root root.addItem(item); - } + } - public void removeItem(Item item) { + void removeItem(Item item) { // check if this context is the containing one checkArgument(item.getContext() == this, "Context is not the container of the item to add"); - // check if it is stored - checkArgument(!items.containsKey(item.getURI()), "Context does not contain item with that URI"); - - // all preconditions ok => remove item - items.remove(item.getURI()); - + // remove item from root root.removeItem(item); } diff --git a/src/rails/game/state/MultimapChange.java b/src/rails/game/state/MultimapChange.java index dedca99..115465e 100644 --- a/src/rails/game/state/MultimapChange.java +++ b/src/rails/game/state/MultimapChange.java @@ -7,11 +7,11 @@ final class MultimapChange<K,V> extends Change { final private boolean addToMap; MultimapChange(MultimapState<K,V> state, K key, V value, boolean addToMap) { - super(state); this.state = state; this.key = key; this.value = value; this.addToMap = addToMap; + super.init(state); } @Override diff --git a/src/rails/game/state/Observable.java b/src/rails/game/state/Observable.java index bc339cb..3272391 100644 --- a/src/rails/game/state/Observable.java +++ b/src/rails/game/state/Observable.java @@ -1,68 +1,128 @@ package rails.game.state; -import com.google.common.collect.ImmutableSet; - +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import com.google.common.collect.ImmutableSet; /** * Requirement: * The observable object has to call each observer per update() if the object has changed. - * - * @author freystef - * */ -public abstract class Observable extends AbstractItem { +public abstract class Observable implements Item { - // stores observers and models - private HashSetState<Observer> observers = null; // lazy initialization - private HashSetState<Model> models = null; // lazy initialization + // fields for Item implementation + private final String id; + private final Item parent; + private final Context context; + // stores observers and models if observable + // those are unobservable states themselves + private final HashSetState<Observer> observers; + private final HashSetState<Model> models; + + /** + * @param parent parent node in item hierarchy (cannot be null) + * @param id id of the observable + * If id is null it creates an "unobservable" observable + * This is required for the creation of states that are themselves stateless + */ + protected Observable(Item parent, String id) { - super(parent, id); + checkNotNull(parent, "Parent cannot be null"); + + // defined standard fields + this.parent = parent; + this.id = id; + context = parent.getContext(); + + // if id is null this is an "unobservable" observable + if (id == null) { + observers = null; + models = null; + } else { + observers = HashSetState.create(this, null); + models = HashSetState.create(this, null); + } + } public void addObserver(Observer o) { - if (observers == null) { - observers = HashSetState.create(this, "observers"); - } + checkState(id != null, "Cannot add observer to unobservable object"); observers.add(o); } public boolean removeObserver(Observer o) { - if (observers == null) return false; - + checkState(id != null, "Cannot remove observer from unobservable object"); return observers.remove(o); } public ImmutableSet<Observer> getObservers() { + checkState(id != null, "Cannot get observers of unobservable object"); return observers.view(); } public void addModel(Model m) { - if (models == null) { - models = HashSetState.create(this, "models"); - } - + checkState(id != null, "Cannot add model to unobservable object"); models.add(m); } public boolean removeModel(Model m) { - if (models == null) return false; - + checkState(id != null, "Cannot remove model from unobservable object"); return models.remove(m); } public ImmutableSet<Model> getModels() { + checkState(id != null, "Cannot get models of unobservable object"); return models.view(); } + /** + * Calls update() of registered Models + * Returns without error for unobservable models + */ public void updateModels() { - if (models == null) return; - + if (id == null) return; for (Model m:models) { m.update(); } } + // Item methods + + public String getId() { + return id; + } + + public Item getParent() { + return parent; + } + + public Context getContext() { + return context; + } + + public Root getRoot() { + // forward it to the context + return context.getRoot(); + } + + public String getURI() { + checkState(id != null, "Cannot get URI of unobservable object"); + if (parent instanceof Manager) { + return id; + } else { + // recursive definition + return parent.getURI() + Item.SEP + id; + } + } + + public String getFullURI() { + checkState(id != null, "Cannot get fullURI of unobservable object"); + // recursive definition + return parent.getFullURI() + Item.SEP + id; + } + + /** * @return text to be read by observers */ diff --git a/src/rails/game/state/PortfolioChange.java b/src/rails/game/state/PortfolioChange.java index f603789..eb1d3a8 100644 --- a/src/rails/game/state/PortfolioChange.java +++ b/src/rails/game/state/PortfolioChange.java @@ -7,10 +7,10 @@ final class PortfolioChange<T extends Ownable<T>> extends Change { private final T item; PortfolioChange(Portfolio<T> in, Portfolio<T> out, T item) { - super(in); this.in = in; this.out = out; this.item = item; + super.init(in); } @Override diff --git a/src/rails/game/state/Root.java b/src/rails/game/state/Root.java index 5f5a47d..8a177b8 100644 --- a/src/rails/game/state/Root.java +++ b/src/rails/game/state/Root.java @@ -4,48 +4,51 @@ import static com.google.common.base.Preconditions.checkArgument; /** * Root is the top node of the context/item hierachy */ -public final class Root extends Manager { +public final class Root extends Context { - public final static String ID = "/"; + public final static String ID = ""; private StateManager stateManager; + private final HashMapState<String, Item> items = HashMapState.create(this, null); - private Root() { - super(null, ID); - } + private Root() { } /** - * @param stateManagerId for the embedded StateManager * @return a Root object with initialized StateManager embedded */ - public static Root create(String stateManagerId) { + public static Root create() { Root root = new Root(); - StateManager stateManager = StateManager.create(root, stateManagerId); + StateManager stateManager = StateManager.create(root, "states"); root.addStateManager(stateManager); return root; } private void addStateManager(StateManager stateManager) { this.stateManager = stateManager; + this.addItem(stateManager); } public StateManager getStateManager() { return stateManager; } + + // Item methods /** * @throws UnsupportedOperationsException * Not supported for Root */ - @Override public Item getParent() { throw new UnsupportedOperationException(); } + + public String getId() { + return ""; + } /** * @return this */ - @Override public Context getContext() { return this; } @@ -53,41 +56,34 @@ public final class Root extends Manager { /** * @return this */ - @Override public Root getRoot() { return this; } - - @Override public String getURI() { - return ID; + return ""; } - @Override public String getFullURI() { - return ID; + return ""; } // Context methods - @Override - public Item localize(String uri) { + public Item locate(String uri) { return items.get(uri); } - @Override - public void addItem(Item item) { + void addItem(Item item) { // check if it already exists - checkArgument(items.containsKey(item.getFullURI()), "Root already contains item with identical fullURI"); + checkArgument(!items.containsKey(item.getFullURI()), "Root already contains item with identical fullURI"); // all preconditions ok => add items.put(item.getFullURI(), item); } - @Override - public void removeItem(Item item) { + void removeItem(Item item) { // check if it already exists - checkArgument(!items.containsKey(item.getFullURI()), "Root does not contain item with that fullURI"); + checkArgument(items.containsKey(item.getFullURI()), "Root does not contain item with that fullURI"); // all preconditions ok => remove items.remove(item.getFullURI()); @@ -97,5 +93,6 @@ public final class Root extends Manager { public String toString() { return ID; } + } diff --git a/src/rails/game/state/State.java b/src/rails/game/state/State.java index 0428a7e..fc2ef79 100644 --- a/src/rails/game/state/State.java +++ b/src/rails/game/state/State.java @@ -15,9 +15,6 @@ import static com.google.common.base.Preconditions.*; */ public abstract class State extends Observable { - // reference to StateManager - private StateManager stateManager; - // optional formatter private Formatter<State> formatter = null; @@ -28,11 +25,13 @@ public abstract class State extends Observable { addModel((Model)parent); } - // check if there is a StateManager available - checkState(getContext().getRoot().getStateManager() == null, "Root of state has no StateManager attached"); - // if so => register state there - stateManager = getContext().getRoot().getStateManager(); - stateManager.registerState(this); + // register if observable state + if (id != null) { + // check if there is a StateManager available + checkState(getContext().getRoot().getStateManager() != null, "Root of state has no StateManager attached"); + // if so => register state there + getRoot().getStateManager().registerState(this); + } } // Observable methods @@ -56,8 +55,4 @@ public abstract class State extends Observable { public void setFormatter(Formatter<State> formatter) { this.formatter = formatter; } - - StateManager getStateManager() { - return stateManager; - } } \ No newline at end of file diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java index 4526712..e48f17d 100644 --- a/src/rails/game/state/StateManager.java +++ b/src/rails/game/state/StateManager.java @@ -1,6 +1,5 @@ package rails.game.state; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -19,31 +18,29 @@ public final class StateManager extends Manager { LoggerFactory.getLogger(StateManager.class.getPackage().getName()); private final ChangeStack changeStack = ChangeStack.create(this); - private final PortfolioManager portfolioManager = PortfolioManager.create(this, "portfolioManager"); - private final WalletManager walletManager = WalletManager.create(this, "walletManager"); - - private final Set<State> allStates = new HashSet<State>(); + private final HashSetState<State> allStates = HashSetState.create(this, null); +// private final PortfolioManager portfolioManager = PortfolioManager.create(this, "portfolioManager"); +// private final WalletManager walletManager = WalletManager.create(this, "walletManager"); + private StateManager(Root parent, String id) { super(parent, id); } - public static StateManager create(Root parent, String id){ + static StateManager create(Root parent, String id){ return new StateManager(parent, id); } - /** * Register states * Remark: Portfolios and Wallets get added from their respective managers automatically */ - boolean registerState(State state) { - if (!allStates.add(state)) return false; - if (state instanceof Portfolio) { - return portfolioManager.addPortfolio((Portfolio<?>) state); - } else if (state instanceof Wallet) { - return walletManager.addWallet((Wallet<?>) state); - } - return true; + void registerState(State state) { + allStates.add(state); +// if (state instanceof Portfolio) { +// return portfolioManager.addPortfolio((Portfolio<?>) state); +// } else if (state instanceof Wallet) { +// return walletManager.addWallet((Wallet<?>) state); +// } } /** @@ -52,11 +49,11 @@ public final class StateManager extends Manager { */ boolean deRegisterState(State state) { if (!allStates.remove(state)) return false; - if (state instanceof PortfolioMap) { - return portfolioManager.removePortfolio((PortfolioMap<?>) state); - } else if (state instanceof Wallet) { - return walletManager.removeWallet((Wallet<?>) state); - } +// if (state instanceof PortfolioMap) { +// return portfolioManager.removePortfolio((PortfolioMap<?>) state); +// } else if (state instanceof Wallet) { +// return walletManager.removeWallet((Wallet<?>) state); +// } return true; } @@ -187,6 +184,4 @@ public final class StateManager extends Manager { return changeStack; } - - } diff --git a/src/rails/game/state/StringChange.java b/src/rails/game/state/StringChange.java index 1ca9680..ae551f6 100644 --- a/src/rails/game/state/StringChange.java +++ b/src/rails/game/state/StringChange.java @@ -12,10 +12,10 @@ final class StringChange extends Change { private final String oldValue; StringChange(StringState state, String newValue) { - super(state); this.state = state; this.newValue = newValue; this.oldValue = state.stringValue(); + super.init(state); } @Override diff --git a/src/rails/game/state/WalletChange.java b/src/rails/game/state/WalletChange.java index 59afb72..147fdaa 100644 --- a/src/rails/game/state/WalletChange.java +++ b/src/rails/game/state/WalletChange.java @@ -8,11 +8,11 @@ final class WalletChange<T extends CountableItem> extends Change { private final int amount; WalletChange(Wallet<T> in, Wallet<T> out, T item, int amount) { - super(in); this.in = in; this.out = out; this.item = item; this.amount = amount; + super.init(in); } @Override |
From: Dr. M. B. <neu...@us...> - 2012-07-01 14:29:00
|
rails/game/specific/_1880/OperatingRound_1880.java | 28 +-------------------- 1 file changed, 2 insertions(+), 26 deletions(-) New commits: commit 558a2bbf2500b660e27a76f4197ca7987378d6b9 Author: Martin Brumm <Dr....@t-...> Date: Sat Jun 30 22:57:29 2012 +0200 Fixed duplicated Code diff --git a/rails/game/specific/_1880/OperatingRound_1880.java b/rails/game/specific/_1880/OperatingRound_1880.java index adc4b3d..9af0f54 100644 --- a/rails/game/specific/_1880/OperatingRound_1880.java +++ b/rails/game/specific/_1880/OperatingRound_1880.java @@ -15,17 +15,14 @@ import rails.common.GuiDef; import rails.common.LocalText; import rails.game.Bank; import rails.game.BaseToken; -import rails.game.Bonus; import rails.game.CashHolder; import rails.game.GameDef; -import rails.game.GameManager; import rails.game.GameManagerI; import rails.game.MapHex; import rails.game.OperatingRound; import rails.game.PhaseI; import rails.game.Player; import rails.game.Portfolio; -import rails.game.PrivateCompanyI; import rails.game.PublicCertificateI; import rails.game.PublicCompanyI; import rails.game.ReportBuffer; @@ -47,7 +44,6 @@ import rails.game.special.SpecialTrainBuy; import rails.game.specific._1880.PublicCompany_1880; import rails.game.specific._1880.GameManager_1880; import rails.game.state.EnumState; -import rails.ui.swing.GameUIManager; import rails.util.SequenceUtil; /** @@ -497,7 +493,7 @@ public class OperatingRound_1880 extends OperatingRound { )); } else { int reducedCash = ((cash /10) * 2); //20 Percent of the Cash will move to the Owner - new CashMove (comp, owner, cash); + new CashMove (comp, owner, reducedCash); ReportBuffer.add(LocalText.getText("CashtransferfromInvestor", company.getName(), Bank.format(cash) @@ -505,27 +501,6 @@ public class OperatingRound_1880 extends OperatingRound { } company.setClosed(); - - // TODO: investorCashToOwner needs to be gotten from the Owner of the - // Investor... - // TODO: we need to automatically move 20% of the Cash to the owner if - // the Investor is still alive on Game end.. - if (investorCashToOwner != true) { - new CashMove(comp, controlCompany, cash); - ReportBuffer.add(LocalText.getText("CashtransferfromInvestor", - company.getName(), Bank.format(cash))); - } else { - if (cash > 0) { - int reducedCash = ((cash / 10) * 2); // 20 Percent of the Cash - // will move to the Owner - new CashMove(comp, owner, reducedCash); - ReportBuffer.add(LocalText.getText("CashTransferFromInvestor", - company.getName(), Bank.format(cash))); - } - ReportBuffer.add(LocalText.getText("NoCashTransferFromInvestor", - company.getName(), Bank.format(0))); - } - company.setClosed(); } /* (non-Javadoc) @@ -577,6 +552,7 @@ public class OperatingRound_1880 extends OperatingRound { * 4. LAYING TILES *=======================================*/ + @Override public boolean layTile(LayTile action) { String errMsg = null; |
From: Dr. M. B. <neu...@us...> - 2012-06-30 19:22:59
|
rails/game/specific/_1880/StartRound_1880.java | 34 ++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) New commits: commit 3e96281f14a2b0c08bfc015fb31d5a31d03e5601 Author: Martin Brumm <Dr....@t-...> Date: Sat Jun 30 21:22:07 2012 +0200 Fixed Startround bidding and passing routine. diff --git a/rails/game/specific/_1880/StartRound_1880.java b/rails/game/specific/_1880/StartRound_1880.java index 9591da8..69d5fd5 100644 --- a/rails/game/specific/_1880/StartRound_1880.java +++ b/rails/game/specific/_1880/StartRound_1880.java @@ -36,6 +36,8 @@ public class StartRound_1880 extends StartRound { private final IntegerState investorChosen = new IntegerState("InvestorChosen",0); + + protected IntegerState playersActed = new IntegerState("PlayersActedinStartround"); /** A company in need for a par price. */ PublicCompanyI companyNeedingPrice = null; @@ -80,6 +82,7 @@ public class StartRound_1880 extends StartRound { if (currentItem == null || currentItem.get() != item ) { // we haven't seen this item before numPasses.set(0); // new round so cancel all previous passes ! + playersActed.set(0); currentItem.set(item); item.setStatus(StartItem.BIDDABLE); item.setStatus(StartItem.BUYABLE); @@ -134,6 +137,7 @@ public class StartRound_1880 extends StartRound { } else { // Can't bid: Autopass numPasses.add(1); + playersActed.add(1); return false; } } else { // Item is not a private ! should be a major or minor in 1880 special rules apply. @@ -234,12 +238,16 @@ public class StartRound_1880 extends StartRound { moveStack.start(false); + if (! item.hasBid(player)) { + playersActed.add(1); + } item.setBid(bidAmount, player); ReportBuffer.add(LocalText.getText("BID_ITEM_LOG", playerName, Bank.format(bidAmount), item.getName(), Bank.format(player.getCash()) )); + if ((item.getBidders() >0) && (numPasses.intValue()== getNumberOfPlayers()-1)) { // All but the highest bidder have passed. int price = item.getBid(); @@ -253,6 +261,7 @@ public class StartRound_1880 extends StartRound { } auctionItemState.set(null); numPasses.set(0); + playersActed.set(0); setNextStartingPlayer(); return true; } else { @@ -293,6 +302,7 @@ public class StartRound_1880 extends StartRound { moveStack.start(false); numPasses.add(1); + playersActed.add(1); if (numPasses.intValue() >= numPlayers) { // All players have passed. @@ -307,6 +317,7 @@ public class StartRound_1880 extends StartRound { auctionItem.getName(), Bank.format(startPacket.getFirstItem().getBasePrice()) )); numPasses.set(0); + playersActed.set(0); if (auctionItem.getBasePrice() == 0) { assignItem((Player)startingPlayer.get(), auctionItem, 0, 0); @@ -315,6 +326,7 @@ public class StartRound_1880 extends StartRound { } } else { numPasses.set(0); + playersActed.set(0); finishRound(); } @@ -333,6 +345,7 @@ public class StartRound_1880 extends StartRound { } auctionItemState.set(null); numPasses.set(0); + playersActed.set(0); setNextStartingPlayer(); return true; } else { @@ -358,11 +371,26 @@ public class StartRound_1880 extends StartRound { } private void setNextBiddingPlayer(StartItem item, int currentIndex) { + boolean bidState = false; for (int i = currentIndex + 1; i < currentIndex + gameManager.getNumberOfPlayers(); i++) { - if (item.getBid(gameManager.getPlayerByIndex(i)) >0) { - setCurrentPlayerIndex(i); - break; + /* + * Ok we need to make sure that every one has at least the chance to bid once. + * We need to make sure that everyone that has passed cant bid again. + * Unfortunately getBid() or hasBid() return 0 so they cant be of use here until the second bidding round ! + * Now we only need a status indicator how many people have acted already.... + */ + if (playersActed.intValue() == numPlayers) { + bidState = item.hasBid(gameManager.getPlayerByIndex(i)); + if (bidState == true) { + setCurrentPlayerIndex(i); + break; + } else { + continue; + } + } else { + setCurrentPlayerIndex(i); + break; } } } |
From: Stefan F. <ste...@us...> - 2012-06-30 04:57:13
|
junit/rails/game/state/ChangeStackTest.java | 117 +++++++++ src/rails/algorithms/RevenueManager.java | 26 -- src/rails/common/GuiHints.java | 17 - src/rails/common/parser/ComponentManager.java | 6 src/rails/common/parser/GameFileParser.java | 4 src/rails/game/Bank.java | 32 -- src/rails/game/BankPortfolio.java | 21 - src/rails/game/BaseToken.java | 21 - src/rails/game/BonusToken.java | 19 - src/rails/game/Company.java | 15 - src/rails/game/CompanyManager.java | 10 src/rails/game/CompanyType.java | 17 - src/rails/game/EndOfGameRound.java | 12 - src/rails/game/Game.java | 6 src/rails/game/GameManager.java | 70 ++--- src/rails/game/MapHex.java | 30 +- src/rails/game/MapManager.java | 11 src/rails/game/OperatingRound.java | 39 +-- src/rails/game/PhaseManager.java | 18 - src/rails/game/Player.java | 122 ++++------ src/rails/game/PlayerManager.java | 13 - src/rails/game/PrivateCompany.java | 15 - src/rails/game/PublicCertificate.java | 9 src/rails/game/PublicCompany.java | 154 +++++-------- src/rails/game/Round.java | 23 - src/rails/game/ShareSellingRound.java | 35 -- src/rails/game/StartItem.java | 33 +- src/rails/game/StartPacket.java | 23 + src/rails/game/StartRound.java | 22 - src/rails/game/StartRound_1830.java | 14 - src/rails/game/StartRound_1835.java | 27 -- src/rails/game/StockMarket.java | 14 - src/rails/game/StockRound.java | 39 +-- src/rails/game/StockSpace.java | 30 -- src/rails/game/Stop.java | 26 -- src/rails/game/SwitchableUIRound.java | 6 src/rails/game/Tile.java | 10 src/rails/game/TileManager.java | 15 - src/rails/game/Token.java | 36 --- src/rails/game/Train.java | 17 - src/rails/game/TrainCertificateType.java | 24 -- src/rails/game/TrainManager.java | 28 +- src/rails/game/TreasuryShareRound.java | 33 -- src/rails/game/correct/CashCorrectionManager.java | 17 - src/rails/game/correct/CorrectionManager.java | 23 - src/rails/game/correct/CorrectionManagerI.java | 3 src/rails/game/correct/CorrectionType.java | 4 src/rails/game/correct/MapCorrectionManager.java | 14 - src/rails/game/model/BaseTokensModel.java | 27 -- src/rails/game/model/BonusModel.java | 11 src/rails/game/model/CalculatedMoneyModel.java | 22 - src/rails/game/model/CashMoneyModel.java | 25 -- src/rails/game/model/CertificateCountModel.java | 28 -- src/rails/game/model/CertificatesModel.java | 31 +- src/rails/game/model/MoneyModel.java | 10 src/rails/game/model/PortfolioModel.java | 46 +-- src/rails/game/model/PresidentModel.java | 22 - src/rails/game/model/PriceModel.java | 29 -- src/rails/game/model/PrivatesModel.java | 24 -- src/rails/game/model/TrainsModel.java | 24 -- src/rails/game/round/Activity.java | 4 src/rails/game/round/RoundContext.java | 9 src/rails/game/special/ExchangeForShare.java | 13 - src/rails/game/special/LocatedBonus.java | 13 - src/rails/game/special/SellBonusToken.java | 20 - src/rails/game/special/SpecialProperty.java | 15 + src/rails/game/special/SpecialRight.java | 11 src/rails/game/special/SpecialTileLay.java | 13 - src/rails/game/special/SpecialTokenLay.java | 11 src/rails/game/special/SpecialTrainBuy.java | 14 - src/rails/game/specific/_1825/OperatingRound_1825.java | 10 src/rails/game/specific/_1825/PublicCompany_1825.java | 12 - src/rails/game/specific/_1825/StartRound_1825.java | 13 - src/rails/game/specific/_1825/StockRound_1825.java | 17 - src/rails/game/specific/_1835/OperatingRound_1835.java | 24 -- src/rails/game/specific/_1835/PrussianFormationRound.java | 11 src/rails/game/specific/_1835/StockRound_1835.java | 16 - src/rails/game/specific/_1851/StartRound_1851.java | 19 - src/rails/game/specific/_1856/CGRFormationRound.java | 23 - src/rails/game/specific/_1856/OperatingRound_1856.java | 17 - src/rails/game/specific/_1856/PublicCompany_1856.java | 17 - src/rails/game/specific/_1856/PublicCompany_CGR.java | 16 - src/rails/game/specific/_1856/ShareSellingRound_1856.java | 21 - src/rails/game/specific/_1856/StockRound_1856.java | 18 - src/rails/game/specific/_1880/Investor_1880.java | 18 - src/rails/game/specific/_1880/OperatingRound_1880.java | 23 - src/rails/game/specific/_1880/PublicCompany_1880.java | 23 - src/rails/game/specific/_1880/StartRound_1880.java | 43 --- src/rails/game/specific/_1880/StockRound_1880.java | 16 - src/rails/game/specific/_1889/OperatingRound_1889.java | 26 -- src/rails/game/specific/_18AL/NameTrains.java | 10 src/rails/game/specific/_18AL/NameableTrain.java | 14 - src/rails/game/specific/_18AL/NamedTrainToken.java | 16 - src/rails/game/specific/_18AL/OperatingRound_18AL.java | 10 src/rails/game/specific/_18EU/FinalMinorExchangeRound.java | 11 src/rails/game/specific/_18EU/GameManager_18EU.java | 9 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 17 - src/rails/game/specific/_18EU/StartRound_18EU.java | 34 -- src/rails/game/specific/_18EU/StockRound_18EU.java | 28 -- src/rails/game/specific/_18GA/OperatingRound_18GA.java | 10 src/rails/game/specific/_18TN/OperatingRound_18TN.java | 15 - src/rails/game/specific/_18TN/PublicCompany_18TN.java | 12 - src/rails/game/state/AbstractItem.java | 38 --- src/rails/game/state/ArrayListChange.java | 12 - src/rails/game/state/ArrayListMultimapState.java | 10 src/rails/game/state/ArrayListState.java | 18 - src/rails/game/state/BooleanChange.java | 11 src/rails/game/state/BooleanState.java | 11 src/rails/game/state/Change.java | 16 - src/rails/game/state/ChangeStack.java | 27 +- src/rails/game/state/Context.java | 126 ---------- src/rails/game/state/GenericState.java | 13 - src/rails/game/state/GenericStateChange.java | 14 - src/rails/game/state/HashMapChange.java | 14 - src/rails/game/state/HashMapState.java | 21 - src/rails/game/state/HashMultimapState.java | 10 src/rails/game/state/HashSetChange.java | 13 - src/rails/game/state/HashSetState.java | 18 - src/rails/game/state/IntegerChange.java | 13 - src/rails/game/state/IntegerState.java | 13 - src/rails/game/state/Item.java | 20 - src/rails/game/state/Manager.java | 110 +++++++++ src/rails/game/state/Model.java | 4 src/rails/game/state/MultimapChange.java | 13 - src/rails/game/state/MultimapState.java | 4 src/rails/game/state/Observable.java | 8 src/rails/game/state/OwnableItem.java | 5 src/rails/game/state/OwnableManager.java | 5 src/rails/game/state/Portfolio.java | 18 - src/rails/game/state/PortfolioChange.java | 8 src/rails/game/state/PortfolioList.java | 8 src/rails/game/state/PortfolioManager.java | 15 - src/rails/game/state/PortfolioMap.java | 8 src/rails/game/state/Root.java | 101 ++++---- src/rails/game/state/State.java | 16 - src/rails/game/state/StateManager.java | 45 +-- src/rails/game/state/StringChange.java | 9 src/rails/game/state/StringState.java | 13 - src/rails/game/state/Wallet.java | 8 src/rails/game/state/WalletChange.java | 13 - src/rails/game/state/WalletManager.java | 11 141 files changed, 1436 insertions(+), 1715 deletions(-) New commits: commit 5ac0e9a3f06f1e9cce6ba3ecabd24f401082447b Author: Stefan Frey <ste...@we...> Date: Sat Jun 30 06:56:17 2012 +0200 Modified approach to Root, Manager and Context objects diff --git a/src/rails/common/parser/ComponentManager.java b/src/rails/common/parser/ComponentManager.java index daa7f30..3e0d57f 100644 --- a/src/rails/common/parser/ComponentManager.java +++ b/src/rails/common/parser/ComponentManager.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; import rails.common.parser.XMLTags; -import rails.game.state.Context; +import rails.game.state.Manager; /** * ComponentManage - an implementation of ComponentManagerI, which handles the @@ -28,7 +28,7 @@ public class ComponentManager { private Map<String, ConfigurableComponent> mComponentMap = new HashMap<String, ConfigurableComponent>(); - public ComponentManager(Context context, String gameName, Tag tag, Map<String, String> gameOptions) + public ComponentManager(Manager context, String gameName, Tag tag, Map<String, String> gameOptions) throws ConfigurationException { this.gameName = gameName; @@ -41,7 +41,7 @@ public class ComponentManager { } } - private void configureComponent(Context context, Tag componentTag) + private void configureComponent(Manager context, Tag componentTag) throws ConfigurationException { // Extract the attributes of the Component diff --git a/src/rails/common/parser/GameFileParser.java b/src/rails/common/parser/GameFileParser.java index 528892e..f4ebe84 100644 --- a/src/rails/common/parser/GameFileParser.java +++ b/src/rails/common/parser/GameFileParser.java @@ -15,7 +15,7 @@ import rails.game.PlayerManager; import rails.game.StockMarket; import rails.game.TileManager; import rails.game.TrainManager; -import rails.game.state.Context; +import rails.game.state.Manager; public class GameFileParser extends XMLParser { private static String GAME_XML_FILE = "Game.xml"; @@ -34,7 +34,7 @@ public class GameFileParser extends XMLParser { private RevenueManager revenueManager; private Bank bank; - public GameFileParser(Context context, String name, Map<String, String> gameOptions) { + public GameFileParser(Manager context, String name, Map<String, String> gameOptions) { directories.add("data/" + name); diff --git a/src/rails/game/Game.java b/src/rails/game/Game.java index 3279b26..b71533c 100644 --- a/src/rails/game/Game.java +++ b/src/rails/game/Game.java @@ -11,9 +11,7 @@ import rails.common.DisplayBuffer; import rails.common.LocalText; import rails.common.parser.*; import rails.game.action.PossibleAction; -import rails.game.state.Context; import rails.game.state.Root; -import rails.game.state.StateManager; import rails.util.GameFileIO; public class Game { @@ -79,10 +77,9 @@ public class Game { public boolean setup() { // first define root GameContext to be able to define states - StateManager stateManager = StateManager.create(parent, id) - Context context = Root.create(parent); + Root root = Root.create("states"); - GameFileParser gfp = new GameFileParser(context, name, gameOptions); + GameFileParser gfp = new GameFileParser(root, name, gameOptions); playerManager = gfp.getPlayerManager(); companyManager = gfp.getCompanyManager(); trainManager = gfp.getTrainManager(); diff --git a/src/rails/game/round/Activity.java b/src/rails/game/round/Activity.java index bea0143..812b7ca 100644 --- a/src/rails/game/round/Activity.java +++ b/src/rails/game/round/Activity.java @@ -3,7 +3,7 @@ package rails.game.round; import java.util.List; import rails.game.action.PossibleAction; -import rails.game.state.Context; +import rails.game.state.Manager; interface Activity { @@ -11,7 +11,7 @@ interface Activity { * creation based on a specific context * @param context */ - public void create(Context context); + public void create(Manager context); /** * @return true if activity is active diff --git a/src/rails/game/state/AbstractItem.java b/src/rails/game/state/AbstractItem.java index 7a8b0ac..e76ec25 100644 --- a/src/rails/game/state/AbstractItem.java +++ b/src/rails/game/state/AbstractItem.java @@ -32,8 +32,8 @@ public abstract class AbstractItem implements Item { } public Context getContext() { - if (parent instanceof Context) { - return (Context)parent; + if (parent instanceof Manager) { + return (Manager)parent; } else { // recursive definition return parent.getContext(); @@ -41,7 +41,7 @@ public abstract class AbstractItem implements Item { } public String getURI() { - if (parent instanceof Context) { + if (parent instanceof Manager) { return id; } else { // recursive definition diff --git a/src/rails/game/state/Context.java b/src/rails/game/state/Context.java index b4d5ae4..487e1e3 100644 --- a/src/rails/game/state/Context.java +++ b/src/rails/game/state/Context.java @@ -1,96 +1,15 @@ package rails.game.state; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - /** - * Contexts allow location of other items + * A context describe a service that allows to locate items */ -public class Context implements Item { - // standard item fields - protected final String id; - protected final Item parent; - // context reference to the root - protected final Root root; +public interface Context extends Item { - // storage of items - protected final HashMapState<String, Item> items = HashMapState.create(this, "items"); + public Item localize(String uri); - protected Context(Item parent, String id) { - // check arguments - checkNotNull(parent, "Parent cannot be null"); - checkNotNull(id, "Id cannot be null"); - checkArgument(id != Root.ID, "Id cannot equal " + Root.ID); - - // standard fields - this.parent = parent; - this.id = id; - - // find root and add context there - root = parent.getContext().getRoot(); - root.addItemToRoot(this); - } - - public static Context create(Item parent, String id) { - return new Context(parent, id); - } - - public String getId() { - return id; - } + public void addItem(Item item); - public Item getParent() { - return parent; - } + public void removeItem(Item item); - public Context getContext() { - return this; - } + public Root getRoot(); - public String getURI() { - if (parent instanceof Context) { - return id; - } else { - // recursive definition - return parent.getURI() + Item.SEP + id; - } - } - - public String getFullURI() { - // recursive definition - return parent.getFullURI() + Item.SEP + id; - } - - // Context methods - public Item localize(String uri) { - // either item can be found in the map - if (items.containsKey(uri)) { - return items.get(uri); - } else { - // otherwise search in root - return root.localize(uri); - } - } - - void addItem(AbstractItem item) { - // check if this context is the containing one - checkArgument(item.getContext() == this, "Context is not the container of the item to add"); - // check if it already exists - checkArgument(items.containsKey(item.getURI()), "Context already contains item with identical URI"); - - // all preconditions ok => add item - items.put(item.getURI(), item); - - // add item to root - root.addItemToRoot(item); - } - - public Root getRoot() { - return root; - } - - @Override - public String toString() { - return parent.toString(); - } } diff --git a/src/rails/game/state/Item.java b/src/rails/game/state/Item.java index f076822..be16c84 100644 --- a/src/rails/game/state/Item.java +++ b/src/rails/game/state/Item.java @@ -14,7 +14,7 @@ package rails.game.state; */ public interface Item { - static final char SEP = '.'; + public static final char SEP = '/'; String getId(); diff --git a/src/rails/game/state/Manager.java b/src/rails/game/state/Manager.java new file mode 100644 index 0000000..11d5a3b --- /dev/null +++ b/src/rails/game/state/Manager.java @@ -0,0 +1,110 @@ +package rails.game.state; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A Manager is an abstract implementation of a Context + */ +public abstract class Manager implements Context { + + // standard item fields + private final String id; + private final Item parent; + + protected final Root root; + + // storage of items + protected final HashMapState<String, Item> items = HashMapState.create(this, "items"); + + protected Manager(Item parent, String id) { + checkNotNull(id, "Id cannot be null"); + this.id = id; + + if (this instanceof Root) { + this.parent = null; + this.root = null; + return; + } + + // check arguments, parent can only be null for Root + checkNotNull(parent, "Parent cannot be null"); + this.parent = parent; + + // find root and add context there + root = parent.getContext().getRoot(); + root.addItem(this); + } + + public String getId() { + return id; + } + + public Item getParent() { + return parent; + } + + public Context getContext() { + return this; + } + + public String getURI() { + if (parent instanceof Manager) { + return id; + } else { + // recursive definition + return parent.getURI() + Item.SEP + id; + } + } + + public String getFullURI() { + // recursive definition + return parent.getFullURI() + Item.SEP + id; + } + + // Context methods + public Item localize(String uri) { + // either item can be found in the map + if (items.containsKey(uri)) { + return items.get(uri); + } else { + // otherwise search in root + return root.localize(uri); + } + } + + public void addItem(Item item) { + // check if this context is the containing one + checkArgument(item.getContext() == this, "Context is not the container of the item to add"); + // check if it already exists + checkArgument(items.containsKey(item.getURI()), "Context already contains item with identical URI"); + + // all preconditions ok => add item + items.put(item.getURI(), item); + + // add item to root + root.addItem(item); + } + + public void removeItem(Item item) { + // check if this context is the containing one + checkArgument(item.getContext() == this, "Context is not the container of the item to add"); + // check if it is stored + checkArgument(!items.containsKey(item.getURI()), "Context does not contain item with that URI"); + + // all preconditions ok => remove item + items.remove(item.getURI()); + + // remove item from root + root.removeItem(item); + } + + public Root getRoot() { + return root; + } + + @Override + public String toString() { + return parent.toString(); + } +} diff --git a/src/rails/game/state/Root.java b/src/rails/game/state/Root.java index d7fc154..5f5a47d 100644 --- a/src/rails/game/state/Root.java +++ b/src/rails/game/state/Root.java @@ -1,41 +1,64 @@ package rails.game.state; import static com.google.common.base.Preconditions.checkArgument; - /** - * Root is a context that serves as the top node - - * It also contains the StateManager if the object tree - * should be able to contain states + * Root is the top node of the context/item hierachy */ -public final class Root extends Context { +public final class Root extends Manager { + + public final static String ID = "/"; + + private StateManager stateManager; + + private Root() { + super(null, ID); + } /** - * The reserved id for a root + * @param stateManagerId for the embedded StateManager + * @return a Root object with initialized StateManager embedded */ - public static final String ID = "root"; - - private Root(StateManager parent) { - super(parent, ID); + public static Root create(String stateManagerId) { + Root root = new Root(); + StateManager stateManager = StateManager.create(root, stateManagerId); + root.addStateManager(stateManager); + return root; } - + + private void addStateManager(StateManager stateManager) { + this.stateManager = stateManager; + } + + public StateManager getStateManager() { + return stateManager; + } + /** - * @param the game used for this hierarchy + * @throws UnsupportedOperationsException + * Not supported for Root */ - public static Root create(Game parent) { - return new Root(parent); + @Override + public Item getParent() { + throw new UnsupportedOperationException(); } + /** + * @return this + */ @Override - public StateManager getParent() { - return null; + public Context getContext() { + return this; } + /** + * @return this + */ @Override - public Context getContext() { - return null; + public Root getRoot() { + return this; } + @Override public String getURI() { return ID; @@ -52,16 +75,25 @@ public final class Root extends Context { return items.get(uri); } - // Root methods - void addItemToRoot(Item item) { + @Override + public void addItem(Item item) { // check if it already exists checkArgument(items.containsKey(item.getFullURI()), "Root already contains item with identical fullURI"); - // all preconditions ok + // all preconditions ok => add items.put(item.getFullURI(), item); } @Override + public void removeItem(Item item) { + // check if it already exists + checkArgument(!items.containsKey(item.getFullURI()), "Root does not contain item with that fullURI"); + + // all preconditions ok => remove + items.remove(item.getFullURI()); + } + + @Override public String toString() { return ID; } diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java index cd7391c..4526712 100644 --- a/src/rails/game/state/StateManager.java +++ b/src/rails/game/state/StateManager.java @@ -13,7 +13,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; -public final class StateManager extends AbstractItem { +public final class StateManager extends Manager { protected static Logger log = LoggerFactory.getLogger(StateManager.class.getPackage().getName()); commit 16dee2d210cab07db6e73a10e3a5f70eeec1e39b Author: Stefan Frey <ste...@we...> Date: Fri Jun 22 12:38:31 2012 +0200 refactored Item interface again diff --git a/junit/rails/game/state/ChangeStackTest.java b/junit/rails/game/state/ChangeStackTest.java new file mode 100644 index 0000000..04dbb87 --- /dev/null +++ b/junit/rails/game/state/ChangeStackTest.java @@ -0,0 +1,117 @@ +package rails.game.state; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.mockito.Mock; + +public class ChangeStackTest { + + @Mock + private StateManager sm; + + @Test + public void testCreate() { + ChangeStack stack = ChangeStack.create(sm); + assertNotNull(stack); + } + + @Test + public void testEnable() { + ChangeStack stack = ChangeStack.create(sm); + assertFalse(stack.isEnabled()); + stack.enable(); + assertTrue(stack.isEnabled()); + } + + @Test + public void testIsEnabled() { + fail("Not yet implemented"); + } + + @Test + public void testGetAvailableChangeSet() { + fail("Not yet implemented"); + } + + @Test + public void testGetAvailableChangeSetBoolean() { + fail("Not yet implemented"); + } + + @Test + public void testStart() { + fail("Not yet implemented"); + } + + @Test + public void testFinish() { + fail("Not yet implemented"); + } + + @Test + public void testCancel() { + fail("Not yet implemented"); + } + + @Test + public void testAddChange() { + fail("Not yet implemented"); + } + + @Test + public void testIsUndoableByPlayer() { + fail("Not yet implemented"); + } + + @Test + public void testIsUndoableByManager() { + fail("Not yet implemented"); + } + + @Test + public void testIsOpen() { + fail("Not yet implemented"); + } + + @Test + public void testGetIndex() { + fail("Not yet implemented"); + } + + @Test + public void testSize() { + fail("Not yet implemented"); + } + + @Test + public void testGetCurrentIndex() { + fail("Not yet implemented"); + } + + @Test + public void testGotoIndex() { + fail("Not yet implemented"); + } + + @Test + public void testIsRedoable() { + fail("Not yet implemented"); + } + + @Test + public void testRedoMoveSet() { + fail("Not yet implemented"); + } + + @Test + public void testUndo() { + fail("Not yet implemented"); + } + + @Test + public void testAdd() { + fail("Not yet implemented"); + } + +} diff --git a/src/rails/algorithms/RevenueManager.java b/src/rails/algorithms/RevenueManager.java index 0c14e5d..6c70b91 100644 --- a/src/rails/algorithms/RevenueManager.java +++ b/src/rails/algorithms/RevenueManager.java @@ -22,11 +22,7 @@ import rails.game.state.Item; * which are permanent. * The conversion of Rails elements is in the responsibility of the RevenueAdapter. * For each GameManager instance only one RevenueManager is created. - * - * @author freystef - * */ - public final class RevenueManager extends AbstractItem implements ConfigurableComponent { protected static Logger log = @@ -34,15 +30,21 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo private final HashSet<ConfigurableComponent> configurableModifiers = new HashSet<ConfigurableComponent>(); - private final ArrayListState<NetworkGraphModifier> graphModifiers = ArrayListState.create(); - private final ArrayListState<RevenueStaticModifier> staticModifiers = ArrayListState.create(); - private final ArrayListState<RevenueDynamicModifier> dynamicModifiers = ArrayListState.create(); + private final ArrayListState<NetworkGraphModifier> graphModifiers = ArrayListState.create(this, "graphModifiers"); + private final ArrayListState<RevenueStaticModifier> staticModifiers = ArrayListState.create(this, "staticModifiers"); + private final ArrayListState<RevenueDynamicModifier> dynamicModifiers = ArrayListState.create(this, "dynamicModifiers"); private final ArrayList<RevenueStaticModifier> activeStaticModifiers = new ArrayList<RevenueStaticModifier>(); private final ArrayList<RevenueDynamicModifier> activeDynamicModifiers = new ArrayList<RevenueDynamicModifier>(); private RevenueDynamicModifier activeCalculator; - public RevenueManager() {} + private 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 { @@ -94,14 +96,6 @@ 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 (ConfigurableComponent modifier:configurableModifiers) { diff --git a/src/rails/common/GuiHints.java b/src/rails/common/GuiHints.java index a40d4ac..ddd3d1b 100644 --- a/src/rails/common/GuiHints.java +++ b/src/rails/common/GuiHints.java @@ -17,24 +17,25 @@ import rails.game.state.Item; * @author VosE * */ -public class GuiHints extends AbstractItem implements Serializable{ +public final 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 Round>> currentRoundType = GenericState.create(); + private GenericState<Class<? extends Round>> currentRoundType = GenericState.create(this, "currentRoundType"); /** Which windows should be visible? */ private List<VisibilityHint> visibilityHints; /** Which window type is active and should be on top? */ - private GenericState<GuiDef.Panel> activePanel = GenericState.create(); + private GenericState<GuiDef.Panel> activePanel = GenericState.create(this, "activePanel"); - @Override - public void init(Item parent, String id){ - super.init(parent, id); - currentRoundType.init(this, "CurrentRoundType"); - activePanel.init(this, "ActivePanel"); + private GuiHints(Item parent, String id) { + super(parent, id); + } + + public static GuiHints create(Item parent, String id){ + return new GuiHints(parent, id); } public Class<? extends Round> getCurrentRoundType() { diff --git a/src/rails/game/Bank.java b/src/rails/game/Bank.java index 392c62c..66b9d09 100644 --- a/src/rails/game/Bank.java +++ b/src/rails/game/Bank.java @@ -33,19 +33,19 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone private static final String DEFAULT_MONEY_FORMAT = "$@"; /** The Bank's amount of cash */ - private final CashMoneyModel cash = CashMoneyModel.create(); + private final CashMoneyModel cash = CashMoneyModel.create(this, "cash", false); /** The IPO */ - private final BankPortfolio ipo = BankPortfolio.create(); + private final BankPortfolio ipo = BankPortfolio.create(this, IPO_NAME); /** The Bank Pool */ - private final BankPortfolio pool = BankPortfolio.create(); + private final BankPortfolio pool = BankPortfolio.create(this, POOL_NAME); /** Collection of items that will (may) become available in the future */ - private final BankPortfolio unavailable = BankPortfolio.create(); + private final BankPortfolio unavailable = BankPortfolio.create(this, UNAVAILABLE_NAME); /** Collection of items that have been discarded (but are kept to allow Undo) */ - private final BankPortfolio scrapHeap = BankPortfolio.create(); + private final BankPortfolio scrapHeap = BankPortfolio.create(this, SCRAPHEAP_NAME); /** Is the bank broken */ - private final BooleanState broken = BooleanState.create(); + private final BooleanState broken = BooleanState.create(this, "broken"); /** * The money format template. '@' is replaced by the numeric amount, the @@ -56,8 +56,8 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone protected static Logger log = LoggerFactory.getLogger(Bank.class.getPackage().getName()); - public Bank() { - super(); + protected Bank(Item parent, String id) { + super(parent, id); instance = this; String configFormat = Config.get("money_format"); @@ -65,19 +65,9 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone moneyFormat = configFormat; } } - - @Override - public void init(Item parent, String id) { - super.init(parent, id); - - cash.init(this, "cash"); - broken.init(this, "broken"); - - // Init the IPO and the Bank Pool. - ipo.init(this, IPO_NAME); - pool.init(this, POOL_NAME); - unavailable.init(this, UNAVAILABLE_NAME); - scrapHeap.init(this, SCRAPHEAP_NAME); + + public static Bank create(Item parent, String id) { + return new Bank(parent, id); } /** diff --git a/src/rails/game/BankPortfolio.java b/src/rails/game/BankPortfolio.java index ce62f23..fd92cba 100644 --- a/src/rails/game/BankPortfolio.java +++ b/src/rails/game/BankPortfolio.java @@ -10,29 +10,28 @@ import rails.game.state.Item; */ public class BankPortfolio extends AbstractItem implements PortfolioOwner { - - private final PortfolioModel portfolio = PortfolioModel.create(); - private BankPortfolio() {} + private final PortfolioModel portfolio = PortfolioModel.create(this); - public static BankPortfolio create() { - BankPortfolio bp = new BankPortfolio(); - return bp; + protected BankPortfolio(Item parent, String id) { + super (parent, id); } /** - * parent is restricted to Bank + * @param parent restricted to bank */ + public static BankPortfolio create(Bank parent, String id) { + return new BankPortfolio(parent, id); + } + @Override - public void init(Item parent, String id) { - super.checkedInit(parent, id, Bank.class); - portfolio.init(this, "portfolio"); + public Bank getParent() { + return (Bank)super.getParent(); } // PortfolioOwner methods public PortfolioModel getPortfolioModel() { return portfolio; } - } diff --git a/src/rails/game/BaseToken.java b/src/rails/game/BaseToken.java index 253bad1..d2ccde2 100644 --- a/src/rails/game/BaseToken.java +++ b/src/rails/game/BaseToken.java @@ -1,7 +1,5 @@ package rails.game; -import rails.game.state.Item; - /** * A BaseToken object represents a token that a operating public company can * place on the map to act as a rail building and train running starting point. @@ -9,25 +7,20 @@ import rails.game.state.Item; * rails.game program as it most closely the function of such a token: to act as * a base from which a company can operate. Other names used in various games * and discussions are "railhead", "station", "garrison", or just "token". - * - * @author Erik Vos */ + +// FIXME: Check if PublicCompany is the parent of a token public final class BaseToken extends Token { - private BaseToken() {}; + private BaseToken(PublicCompany parent, String id) { + super(parent, id); + } public static BaseToken create(PublicCompany company) { - BaseToken token = new BaseToken(); - token.init(company); - return token; + String uniqueId = Token.createUniqueId(); + return new BaseToken(company, uniqueId); } - - @Override - public void init(Item parent) { - super.checkedInit(parent, null, PublicCompany.class); - } - @Override public PublicCompany getParent() { return (PublicCompany)super.getParent(); diff --git a/src/rails/game/BonusToken.java b/src/rails/game/BonusToken.java index acfcfe7..ce92c8e 100644 --- a/src/rails/game/BonusToken.java +++ b/src/rails/game/BonusToken.java @@ -3,7 +3,6 @@ package rails.game; import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; -import rails.game.state.Item; import rails.util.Util; /** @@ -11,10 +10,9 @@ import rails.util.Util; * place on the map to gain extra revenue or other privileges. * <p>Such tokens are usually not placed in city slots, * which are intended for base tokens, but on some unoccupied part of a tile. - * - * @author Erik Vos */ +//FIXME: Check if PublicCompany is the parent of a token public final class BonusToken extends Token implements Closeable, ConfigurableComponent { private int value; @@ -22,20 +20,17 @@ public final class BonusToken extends Token implements Closeable, ConfigurableCo private String removingObjectDesc = null; private Object removingObject = null; private PublicCompany user = null; - - private BonusToken() {}; + + private BonusToken(PublicCompany parent, String id) { + super(parent, id); + } public static BonusToken create(PublicCompany company) { - BonusToken token = new BonusToken(); - token.init(company); + String uniqueId = Token.createUniqueId(); + BonusToken token = new BonusToken(company, uniqueId); return token; } - @Override - public void init(Item parent) { - super.checkedInit(parent, null, PublicCompany.class); - } - public void configureFromXML(Tag tag) throws ConfigurationException { Tag bonusTokenTag = tag.getChild("BonusToken"); if (bonusTokenTag == null) { diff --git a/src/rails/game/Company.java b/src/rails/game/Company.java index 04f9658..c80d0dd 100644 --- a/src/rails/game/Company.java +++ b/src/rails/game/Company.java @@ -14,11 +14,12 @@ import rails.game.special.SpecialProperty; import rails.game.state.BooleanState; import rails.game.state.AbstractItem; import rails.game.state.Item; +import rails.game.state.PortfolioHolder; import rails.game.state.PortfolioList; import rails.util.Util; public abstract class Company extends AbstractItem implements ConfigurableComponent, -Cloneable, Comparable<Company> { +Cloneable, Comparable<Company>, PortfolioHolder { /** The name of the XML tag used to configure a company. */ public static final String COMPANY_ELEMENT_ID = "Company"; @@ -49,21 +50,17 @@ Cloneable, Comparable<Company> { protected int certLimitCount = 2; /** Closed state */ - protected final BooleanState closedObject = BooleanState.create(false); + protected final BooleanState closedObject = BooleanState.create(this, "closed", false); // Moved here from PrivayeCOmpany on behalf of 1835 - protected final PortfolioList<SpecialProperty> specialProperties = PortfolioList.create(); + protected final PortfolioList<SpecialProperty> specialProperties = PortfolioList.create(this, "specialProperties"); protected static Logger log = LoggerFactory.getLogger(Company.class.getPackage().getName()); - @Override - public void init(Item parent, String id) { - super.init(parent, id); - closedObject.init(this, "closed"); - specialProperties.init(this, "specialProperties"); + protected Company(Item parent, String id) { + super(parent, id); } - public void initType(CompanyType type) { this.type = type; } diff --git a/src/rails/game/CompanyManager.java b/src/rails/game/CompanyManager.java index 399e514..c91456c 100644 --- a/src/rails/game/CompanyManager.java +++ b/src/rails/game/CompanyManager.java @@ -13,6 +13,7 @@ import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; +import rails.game.state.Item; public class CompanyManager extends AbstractItem implements ConfigurableComponent { @@ -62,13 +63,16 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen protected GameManager gameManager; + protected CompanyManager(Item parent, String id) { + super(parent, id); + } + /* * NOTES: 1. we don't have a map over all companies, because some games have * duplicate names, e.g. B&O in 1830. 2. we have both a map and a list of * private/public companies to preserve configuration sequence while * allowing direct access. */ - public CompanyManager() { } /** * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) @@ -174,7 +178,7 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen if (packetTags != null) { for (Tag packetTag : tag.getChildren("StartPacket")) { // Extract the attributes of the Component - String name = packetTag.getAttributeAsString("name", StartPacket.DEFAULT_NAME); + String name = packetTag.getAttributeAsString("name", StartPacket.DEFAULT_ID); String roundClass = packetTag.getAttributeAsString("roundClass"); if (roundClass == null) { @@ -182,7 +186,7 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen "StartPacketHasNoClass", name)); } - StartPacket sp = new StartPacket(name, roundClass); + StartPacket sp = StartPacket.create(this, name, roundClass); startPackets.add(sp); startPacketMap.put(name, sp); diff --git a/src/rails/game/CompanyType.java b/src/rails/game/CompanyType.java index cae1e49..8025848 100644 --- a/src/rails/game/CompanyType.java +++ b/src/rails/game/CompanyType.java @@ -43,23 +43,18 @@ public class CompanyType extends AbstractItem { protected List<Company> companies = new ArrayList<Company>(); - /** - * The constructor. - * - */ - private CompanyType(String className) { + protected CompanyType(Item parent, String id, String className) { + super(parent, id); this.className = className; } /** - * @param name Company type name ("Private", "Public", "Minor" etc.). + * @param id Company type name ("Private", "Public", "Minor" etc.). * @param className Name of the class that will instantiate this type of * company. */ - public static CompanyType create(Item parent, String id, String className) { - CompanyType type = new CompanyType(className); - type.init(parent, id); - return type; + public static CompanyType create(CompanyManager parent, String id, String className) { + return new CompanyType(parent, id, className); } /** @@ -82,7 +77,7 @@ public class CompanyType extends AbstractItem { throw new ConfigurationException(LocalText.getText( "ClassCannotBeInstantiated", className), e); } - newCompany.init(this, name); + // newCompany.init(this, name); newCompany.configureFromXML(typeTag); newCompany.configureFromXML(tag); companies.add(newCompany); diff --git a/src/rails/game/EndOfGameRound.java b/src/rails/game/EndOfGameRound.java index 3b2326c..aa4773d 100644 --- a/src/rails/game/EndOfGameRound.java +++ b/src/rails/game/EndOfGameRound.java @@ -11,13 +11,17 @@ import rails.common.LocalText; * * */ -public class EndOfGameRound extends Round { +public final class EndOfGameRound extends Round { - public EndOfGameRound(GameManager gameManager) { - super(gameManager); + 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() { diff --git a/src/rails/game/Game.java b/src/rails/game/Game.java index 961c7b2..3279b26 100644 --- a/src/rails/game/Game.java +++ b/src/rails/game/Game.java @@ -12,6 +12,8 @@ import rails.common.LocalText; import rails.common.parser.*; import rails.game.action.PossibleAction; import rails.game.state.Context; +import rails.game.state.Root; +import rails.game.state.StateManager; import rails.util.GameFileIO; public class Game { @@ -77,7 +79,8 @@ public class Game { public boolean setup() { // first define root GameContext to be able to define states - Context context = Context.create(); + StateManager stateManager = StateManager.create(parent, id) + Context context = Root.create(parent); GameFileParser gfp = new GameFileParser(context, name, gameOptions); playerManager = gfp.getPlayerManager(); diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index 779fd84..9fa593e 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -27,7 +27,7 @@ import rails.util.Util; * 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 { +public class GameManager extends AbstractItem implements ConfigurableComponent, PortfolioHolder { /** Version ID of the Save file header, as written in save() */ private static final long saveFileHeaderVersionID = 3L; /** @@ -71,8 +71,9 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { protected List<Player> players; protected List<String> playerNames; protected int numberOfPlayers; - protected final GenericState<Player> currentPlayer = GenericState.create(); - protected final GenericState<Player> priorityPlayer = GenericState.create(); + protected final GenericState<Player> currentPlayer = GenericState.create(this, "currentPlayer"); + protected final GenericState<Player> priorityPlayer = GenericState.create(this, "priorityPlayer"); + /** Map relating portfolio names and objects, to enable deserialization. * OBSOLETE since Rails 1.3.1, but still required to enable reading old saved files */ @@ -82,7 +83,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { protected final Map<String, PortfolioModel> portfolioUniqueNameMap = new HashMap<String, PortfolioModel> (); - protected final IntegerState playerCertificateLimit = IntegerState.create(); + protected final IntegerState playerCertificateLimit = IntegerState.create(this, "playerCertificateLimit"); protected int currentNumberOfOperatingRounds = 1; protected boolean skipFirstStockRound = false; protected boolean showCompositeORNumber = true; @@ -107,21 +108,21 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { * been sold, it finishes by starting an Operating Round, which handles the * privates payout and then immediately starts a new Start Round. */ - protected final GenericState<Round> currentRound = GenericState.create(); + protected final GenericState<Round> currentRound = GenericState.create(this, "currentRound"); protected Round interruptedRound = null; - protected final IntegerState srNumber = IntegerState.create(); + protected final IntegerState srNumber = IntegerState.create(this, "srNumber"); - protected final IntegerState absoluteORNumber = IntegerState.create(); - protected final IntegerState relativeORNumber = IntegerState.create(); - protected final IntegerState numOfORs = IntegerState.create(); + protected final IntegerState absoluteORNumber = IntegerState.create(this, "absoluteORNUmber"); + protected final IntegerState relativeORNumber = IntegerState.create(this, "relativeORNumber"); + protected final IntegerState numOfORs = IntegerState.create(this, "numOfORs"); /** GameOver pending, a last OR or set of ORs must still be completed */ - protected final BooleanState gameOverPending = BooleanState.create(); + protected final BooleanState gameOverPending = BooleanState.create(this, "gameOverPending"); /** GameOver is executed, no more moves */ - protected final BooleanState gameOver = BooleanState.create(); + protected final BooleanState gameOver = BooleanState.create(this, "gameOver"); protected Boolean gameOverReportedUI = false; - protected final BooleanState endedByBankruptcy = BooleanState.create(); + protected final BooleanState endedByBankruptcy = BooleanState.create(this, "endedByBankruptcy"); /** UI display hints */ protected GuiHints guiHints; @@ -166,9 +167,10 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { /** * The MoveSet stack is maintained to enable Undo and Redo throughout the game. + * FIXME: ChangeStack moved to StateManager */ @Deprecated - protected final ChangeStack changeStack = ChangeStack.create(); + protected final ChangeStack changeStack = null; /** * The DisplayBuffer instance collects messages to be displayed in the UI. @@ -177,7 +179,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { /** * nextPlayerMessages collects all messages to be displayed to the next player */ - protected final ArrayListState<String> nextPlayerMessages = ArrayListState.create(); + protected final ArrayListState<String> nextPlayerMessages = ArrayListState.create(this, "nextPlayerMessages"); /** * The ReportBuffer collects messages to be shown in the Game Report. @@ -191,7 +193,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { protected PossibleActions possibleActions = PossibleActions.getInstance(); - protected final ArrayListState<PossibleAction> executedActions = ArrayListState.create(); + protected final ArrayListState<PossibleAction> executedActions = ArrayListState.create(this, "executedActions"); /** Special properties that can be used by other players or companies * than just the owner (such as buyable bonus tokens as in 1856). @@ -227,7 +229,9 @@ 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 gmName = GM_NAME; gmKey = GM_KEY; // NDC.clear(); @@ -235,7 +239,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { gameManagerMap.put(GM_KEY, this); displayBuffer = new DisplayBuffer(); reportBuffer = new ReportBuffer(); - guiHints = new GuiHints(); + guiHints = GuiHints.create(this, "guiHints"); } public void configureFromXML(Tag tag) throws ConfigurationException { @@ -495,24 +499,6 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { } } - @Override - public void init(Item parent, String id){ - super.init(parent, id); - currentPlayer.init(this, "CurrentPlayer"); - priorityPlayer.init(this, "PriorityPlayer"); - playerCertificateLimit.init(this, "PlayerCertificateLimit"); - currentRound.init(this, "CurrentRound"); - srNumber.init(this, "SRNumber"); - absoluteORNumber.init(this, "AbsoluteORNUmber"); - relativeORNumber.init(this, "RelativeORNumber"); - numOfORs.init(this, "numOfORs"); - gameOverPending.init(this, "GameOverPending"); - gameOver.init(this, "GameOver"); - endedByBankruptcy.init(this, "EndedByBankruptcy"); - nextPlayerMessages.init(this, "nextPlayerMessages"); - executedActions.init(this, "executedActions"); - } - public void finishConfiguration (GameManager gameManager) {} /** Check if a classname can be instantiated. @@ -570,7 +556,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { setGuiParameters(); if (startPacket == null) - startPacket = companyManager.getStartPacket(StartPacket.DEFAULT_NAME); + startPacket = companyManager.getStartPacket(StartPacket.DEFAULT_ID); if (startPacket != null && !startPacket.areAllSold()) { startPacket.init(this); @@ -1711,8 +1697,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { public boolean addSpecialProperty(SpecialProperty property) { if (commonSpecialProperties == null) { - commonSpecialProperties = PortfolioList.create(); - commonSpecialProperties.init(this, "CommonSpecialProperties"); + commonSpecialProperties = PortfolioList.create(this, "CommonSpecialProperties"); } return commonSpecialProperties.moveInto(property); } @@ -1886,6 +1871,16 @@ public class GameManager extends AbstractItem implements ConfigurableComponent { objectStorage = new HashMap<String, Object>(); storageIds = new HashMap<String, Integer>(); } + + /** + * get storage id + * @param name to identify the type of the object to retrieve + */ + public int getStorageId(String typeName) { + Integer id = storageIds.get(typeName); + if (id == null) id = 0; + return id; + } /** * store element in storage diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index e338c10..43168b4 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -22,7 +22,6 @@ import rails.game.model.CashMoneyModel; import rails.game.model.PortfolioModel; import rails.game.state.BooleanState; -import rails.game.state.Item; import rails.game.state.Observer; import rails.game.state.Portfolio; import rails.game.state.PortfolioHolder; @@ -110,7 +109,7 @@ StationHolder { * changed to state variable to fix undo bug #2954645 * null as default implies false - see isBlocked() */ - private final BooleanState isBlockedForTileLays = BooleanState.create(); + private final BooleanState isBlockedForTileLays = BooleanState.create(this, "isBlockedForTileLays"); /** * Is the hex initially blocked for token lays (e.g. when a home base @@ -121,13 +120,13 @@ StationHolder { * the absence of a PR token does not block the third slot * when the green tile is laid. */ - private final BooleanState isBlockedForTokenLays = BooleanState.create(); + private final BooleanState isBlockedForTokenLays = BooleanState.create(this, "isBlockedForTokenLays"); protected Map<PublicCompany, Stop> homes; protected List<PublicCompany> destinations; /** Tokens that are not bound to a Station (City), such as Bonus tokens */ - protected final PortfolioList<Token> offStationTokens = PortfolioList.create(); + protected final PortfolioList<Token> offStationTokens = PortfolioList.create(this, "offStationTokens"); /** Storage of revenueBonus that are bound to the hex */ protected List<RevenueBonusTemplate> revenueBonuses = null; @@ -176,22 +175,17 @@ StationHolder { protected static Logger log = LoggerFactory.getLogger(MapHex.class.getPackage().getName()); - // TODO: Rewrite the creation process of MapHex - - // public constructor - public MapHex() {} + private MapHex(MapManager parent, String id) { + super(parent, id); + } - /** - * MapHex only accepts MapManagers as parent - */ - @Override - public void init(Item parent, String id) { - super.checkedInit(parent, id, MapManager.class); - - isBlockedForTileLays.init(this, name+"_IsBlockedForTileLays"); - isBlockedForTokenLays.init(this, name+"_IsBlockedForTokenLays"); + public static MapHex create(MapManager parent, Tag tag) throws ConfigurationException { + // TODO: Rewrite the creation process of MapHex + MapHex hex = new MapHex(parent, null); + hex.configureFromXML(tag); + return hex; } - + /** * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ diff --git a/src/rails/game/MapManager.java b/src/rails/game/MapManager.java index de07282..7593568 100644 --- a/src/rails/game/MapManager.java +++ b/src/rails/game/MapManager.java @@ -64,7 +64,12 @@ public class MapManager extends AbstractItem implements ConfigurableComponent { protected static Logger log = LoggerFactory.getLogger(MapManager.class.getPackage().getName()); - public MapManager() { + private MapManager(GameManager parent, String id) { + super(parent, id); + } + + public static MapManager create(GameManager parent, String id) { + return new MapManager(parent, id); } /** @@ -121,9 +126,7 @@ public class MapManager extends AbstractItem implements ConfigurableComponent { maxX = maxY = maxCol = maxRow = Integer.MIN_VALUE; possibleTileCosts = new TreeSet<Integer>(); for (Tag hexTag : hexTags) { - hex = new MapHex(); - hex.configureFromXML(hexTag); - hex.init(this, hex.getName()); + hex = MapHex.create(this, hexTag); mHexes.put(hex.getId(), hex); minX = Math.min(minX, hex.getX()); minY = Math.min(minY, hex.getY()); diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java index c15acdc..4e2c305 100644 --- a/src/rails/game/OperatingRound.java +++ b/src/rails/game/OperatingRound.java @@ -1,6 +1,5 @@ package rails.game; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -30,12 +29,13 @@ import rails.util.SequenceUtil; public class OperatingRound extends Round implements Observer { /* Transient memory (per round only) */ - protected final GenericState<GameDef.OrStep> stepObject = GenericState.create(GameDef.OrStep.INITIAL); + protected final GenericState<GameDef.OrStep> stepObject = GenericState.create( + this, "ORStep", GameDef.OrStep.INITIAL); protected boolean actionPossible = true; - /* sfy: using rails without map support */ - protected boolean noMapMode = false; + /* flag for using rails without map support */ + protected final boolean noMapMode; // TODO: Check if thi... [truncated message content] |
From: Erik V. <ev...@us...> - 2012-06-25 15:02:37
|
data/1870/CompanyManager.xml | 260 +++++++++++++++++++++++-------------------- data/1870/Game.xml | 4 2 files changed, 148 insertions(+), 116 deletions(-) New commits: commit fb36421f18d09e7ad3fc2130c427b6e0f60c4f3e Author: Erik Vos <eri...@xs...> Date: Mon Jun 25 17:01:32 2012 +0200 Applied new style config of allowing two yellow tile lays to 1870. diff --git a/data/1870/CompanyManager.xml b/data/1870/CompanyManager.xml index 18251c7..2484ad2 100644 --- a/data/1870/CompanyManager.xml +++ b/data/1870/CompanyManager.xml @@ -1,118 +1,148 @@ <?xml version="1.0"?> <!-- 1870 CompanyManager.xml --> -<CompanyManager> - - <CompanyType name="Private" class="rails.game.PrivateCompany"> - <Tradeable toCompany="yes" lowerPriceFactor="0.5" upperPriceFactor="2.0"/> - </CompanyType> - - <CompanyType name="Public" class="rails.game.PublicCompany"> - <CanBuyPrivates/> - <IPOPaysOut/> - <Float percentage="60"/> - <CanSplitDividend/> - <ShareUnit percentage="10"/> - <Certificate type="President" shares="2"/> - <Certificate shares="1" number="8"/> - <!--NumberOfTileLays colour="yellow" phase="1,2,3,4,5,6,7,8" number="2"/--> - <TileLays> - <Number colour="yellow" phase="1,2,3,4,5,6,7,8" number="2"/> - </TileLays> - <BaseTokens> - <LayCost method="sequence" cost="0,40,100"/> - </BaseTokens> - <Trains limit="4,3,2"/> - <CanUseSpecialProperties/> - </CompanyType> - - <Company name="GRSC" type="Private" basePrice="20" revenue="5" longname="Great River Shipping Company"/> - - <Company name="Brdg" type="Private" basePrice="40" revenue="10" - longname="Mississippi River Bridge Company" > - <ClosingConditions><CloseManually/></ClosingConditions> - </Company> - - <Company name="Cattl" type="Private" tokens="1" basePrice="50" - revenue="10" longname="The Southern Cattle Company" /> - - <Company name="Gulf" type="Private" tokens="2" tokenValue="20/10,10" - basePrice="80" revenue="15" longname="The Gulf Shipping Company" /> - - <Company name="MKT" type="Private" basePrice="160" revenue="20" - longname="Missouri-Kansas-Texas Railroad"> - <Info key="ComesWithCertificate" parm="KATY,10"></Info> - </Company> - - <Company name="KATY" type="Public" tokens="4" fgColour="FFFFFF" - bgColour="00FF00" longname="Missouri-Kansas-Texas Railroad"> - <Home hex="B11" ></Home> - <Destination hex="N1" /> - </Company> - - <Company name="MP" type="Public" tokens="4" fgColour="FFFFFF" - bgColour="FF0000" longname="Missouri Pacific Railroad"> - <Home hex="C18" /> - <Destination hex="J5" /> - </Company> - - <Company name="ATSF" type="Public" tokens="4" fgColour="FFFFFF" - bgColour="0000FF" longname="Atchison, Topeka & Santa Fe Railway"> - <Home hex="B9" /> - <Destination hex="N1" /> - </Company> - - <Company name="SP" type="Public" tokens="4" fgColour="FF8000" - bgColour="000000" longname="Southern Pacific Railroad"> - <Home hex="N1" /> - <Destination hex="N17" /> - </Company> - - <Company name="GMO" type="Public" tokens="3" fgColour="FFFFFF" - bgColour="ff0040" longname="Gulf, Mobile & Ohio Railroad"> - <Home hex="M20" /> - <Destination hex="C18" /> - </Company> - - <Company name="SLSF" type="Public" tokens="4" fgColour="FFFFFF" - bgColour="d04000" longname="St. Louis-San Francisco Railway"> - <Home hex="E12" /> - <Float percentage="20"/> - <Destination hex="M22" /> - </Company> - - <Company name="TP" type="Public" tokens="3" fgColour="FFFFFF" - bgColour="000000" longname="Texas & Pacific Railway"> - <Home hex="J5" /> - <Destination hex="N17" /> - </Company> - - <Company name="FW" type="Public" tokens="3" fgColour="FF0000" - bgColour="000000" longname="Fort Worth & Denver City Railway"> - <Home hex="J3"></Home> - <Destination hex="A2" /> - </Company> - - <Company name="SSW" type="Public" tokens="3" fgColour="FFFFFF" - bgColour="6000ff" longname="St. Louis Southwestern Railway"> - <Home hex="H17" /> - <Destination hex="J3" /> - </Company> - - <Company name="IC" type="Public" tokens="3" fgColour="000000" - bgColour="c0ff40" longname="Illinois Central Railroad"> - <Home hex="K16" /> - <Destination hex="A22" /> - </Company> - - <StartPacket roundClass="rails.game.StartRound_1830"> - <Bidding initial="5" minimum="5" increment="1"/> - <Item name="GRSC" type="Private" basePrice="20"/> - <Item name="Brdg" type="Private" basePrice="40"/> - <Item name="Cattl" type="Private" basePrice="50"/> - <Item name="Gulf" type="Private" basePrice="80"/> - <Item name="SLSF" type="Public" president="yes" basePrice="140"/> - <Item name="MKT" type="Private" basePrice="160"> - <SubItem name="KATY" type="Public" /> - </Item> - </StartPacket> +<CompanyManager> + + <CompanyType name="Private" class="rails.game.PrivateCompany"> + <Tradeable toCompany="yes" lowerPriceFactor="0.5" upperPriceFactor="2.0"/> + </CompanyType> + + <CompanyType name="Public" class="rails.game.PublicCompany"> + <CanBuyPrivates/> + <IPOPaysOut/> + <Float percentage="60"/> + <CanSplitDividend/> + <ShareUnit percentage="10"/> + <Certificate type="President" shares="2"/> + <Certificate shares="1" number="8"/> + <BaseTokens> + <LayCost method="sequence" cost="0,40,100"/> + </BaseTokens> + <Trains limit="4,3,2"/> + <CanUseSpecialProperties/> + </CompanyType> + + <Company name="GRSC" type="Private" basePrice="20" revenue="5" + longname="Great River Shipping Company"/> + + <Company name="Brdg" type="Private" basePrice="40" revenue="10" + longname="Mississippi River Bridge Company"> + <Blocking + hex="A16,B17,C18,D17,E18,F19,G18,H17,I16,J15,K14,L13,M14,N15,N17"/> + <ClosingConditions> + <CloseManually/> + </ClosingConditions> + </Company> + + <Company name="Cattl" type="Private" tokens="1" basePrice="50" revenue="10" + longname="The Southern Cattle Company"> + <SpecialProperties> + <SpecialProperty condition="ifOwnedByCompany" + when="anyTimeDuringORTurn" + class="rails.game.special.SpecialTokenLay"> + <SpecialTokenLay class="rails.game.BonusToken" + location="B9,B11,D5,E12,F5,H13,H17,J3,J5,L11,M2,M6,N7" + connected="yes" extra="yes"> + <BonusToken name="Cattle" removed="Phase:5"/> + </SpecialTokenLay> + </SpecialProperty> + </SpecialProperties> + <ClosingConditions> + <SpecialProperties condition="ifExercised"/> + </ClosingConditions> + </Company> + + <Company name="Gulf" type="Private" tokens="2" tokenValue="20/10,10" + basePrice="80" revenue="15" longname="The Gulf Shipping Company"> + <SpecialProperties> + <SpecialProperty condition="ifOwnedByCompany" + when="anyTimeDuringORTurn" + class="rails.game.special.SpecialTokenLay"> + <SpecialTokenLay class="rails.game.BonusToken" + location="C18,H17,K16,M20,N7,N17" connected="yes" extra="yes"> + <BonusToken name="Port" removed="Phase:5"/> + </SpecialTokenLay> + </SpecialProperty> + </SpecialProperties> + <ClosingConditions> + <CloseManually/> + </ClosingConditions> + </Company> + + <Company name="MKT" type="Private" basePrice="160" revenue="20" + longname="Missouri-Kansas-Texas Railroad"> + <Info key="ComesWithCertificate" parm="KATY,10"></Info> + </Company> + + <Company name="KATY" type="Public" tokens="4" fgColour="FFFFFF" bgColour="00FF00" + longname="Missouri-Kansas-Texas Railroad"> + <Home hex="B11"></Home> + <Destination hex="N1"/> + </Company> + + <Company name="MP" type="Public" tokens="4" fgColour="FFFFFF" bgColour="FF0000" + longname="Missouri Pacific Railroad"> + <Home hex="C18"/> + <Destination hex="J5"/> + </Company> + + <Company name="ATSF" type="Public" tokens="4" fgColour="FFFFFF" bgColour="0000FF" + longname="Atchison, Topeka & Santa Fe Railway"> + <Home hex="B9"/> + <Destination hex="N1"/> + </Company> + + <Company name="SP" type="Public" tokens="4" fgColour="FF8000" bgColour="000000" + longname="Southern Pacific Railroad"> + <Home hex="N1"/> + <Destination hex="N17"/> + </Company> + + <Company name="GMO" type="Public" tokens="3" fgColour="FFFFFF" bgColour="ff0040" + longname="Gulf, Mobile & Ohio Railroad"> + <Home hex="M20"/> + <Destination hex="C18"/> + </Company> + + <Company name="SLSF" type="Public" tokens="4" fgColour="FFFFFF" bgColour="d04000" + longname="St. Louis-San Francisco Railway"> + <Home hex="E12"/> + <Float percentage="20"/> + <Destination hex="M22"/> + </Company> + + <Company name="TP" type="Public" tokens="3" fgColour="FFFFFF" bgColour="000000" + longname="Texas & Pacific Railway"> + <Home hex="J5"/> + <Destination hex="N17"/> + </Company> + + <Company name="FW" type="Public" tokens="3" fgColour="FF0000" bgColour="000000" + longname="Fort Worth & Denver City Railway"> + <Home hex="J3"></Home> + <Destination hex="A2"/> + </Company> + + <Company name="SSW" type="Public" tokens="3" fgColour="FFFFFF" bgColour="6000ff" + longname="St. Louis Southwestern Railway"> + <Home hex="H17"/> + <Destination hex="J3"/> + </Company> + + <Company name="IC" type="Public" tokens="3" fgColour="000000" bgColour="c0ff40" + longname="Illinois Central Railroad"> + <Home hex="K16"/> + <Destination hex="A22"/> + </Company> + + <StartPacket roundClass="rails.game.StartRound_1830"> + <Bidding initial="5" minimum="5" increment="1"/> + <Item name="GRSC" type="Private" basePrice="20"/> + <Item name="Brdg" type="Private" basePrice="40"/> + <Item name="Cattl" type="Private" basePrice="50"/> + <Item name="Gulf" type="Private" basePrice="80"/> + <Item name="SLSF" type="Public" president="yes" basePrice="140"/> + <Item name="MKT" type="Private" basePrice="160"> + <SubItem name="KATY" type="Public"/> + </Item> + </StartPacket> </CompanyManager> diff --git a/data/1870/Game.xml b/data/1870/Game.xml index 6ad4857..a1182b1 100644 --- a/data/1870/Game.xml +++ b/data/1870/Game.xml @@ -71,7 +71,9 @@ </Component> <Component name="PhaseManager" class="rails.game.PhaseManager"> <Phase name="2" realName="1"> - <Tiles colour="yellow"/> + <Tiles colour="yellow"> + <Lays companyType="Public" colour="yellow" number="2"/> + </Tiles> <OperatingRounds number="1"/> <Trains tradingAllowed="yes"/> </Phase> |
From: Dr. M. B. <neu...@us...> - 2012-06-20 19:18:46
|
LocalisedText.properties | 2 buildRails.xml | 1 data/1856/CompanyManager.xml | 73 data/1856/Game.xml | 25 data/18Lummer/CompanyManager.xml | 43 data/18Lummer/Game.xml | 102 data/18Lummer/Map.xml | 17 data/18Lummer/StockMarket.xml | 149 data/18Lummer/TileSet.xml | 145 data/18Lummer/Tiles.xml | 460 ++ data/GamesList.xml | 24 rails/game/ReportBuffer.java | 7 rails/game/Stop.java | 2 rails/game/specific/_18EU/OffBoardRevenueModifier.java | 93 readme.txt | 18 test/data/bugs/1830CF_obsoleteTrains.rails |binary test/data/bugs/1830CF_obsoleteTrains.report | 432 ++ test/data/bugs/1856_tokens.report | 1 test/data/bugs/1889_presidentContribution.report | 3 test/data/bugs/18EU_layhomeHex.report | 1 test/data/real/1830_A.report | 3 test/data/real/1856_A.report | 3 test/data/real/1889_A.report | 2 test/data/real/1889_B.report | 3 test/data/real/1889_C.report | 3 test/data/real/18AL_A.report | 1 test/data/real/18TN_A.report | 1229 +++--- test/data/test/1830_5forDtrainExchange.report | 3 test/data/test/1830_SellFullPresCert.report | 535 +- test/data/test/1830_SellHalfPresCert.report | 535 +- test/data/test/1835_NatDoubleShare.report | 1768 ++++----- test/data/test/1835_NatSingleShare.report | 700 +-- test/data/test/1835_PRHasTwoExcessTrains.report | 2283 +++++------ test/data/test/1835_PR_3rdTrain.report | 2211 +++++------ test/data/test/1835_SellDoubleShare.report | 3282 ++++++++--------- test/data/test/1851_Late.report | 2 test/data/test/1856_2nd6T+PrezCash2.report | 3 test/data/test/18EU_After2nd8Train.report | 3 version.number | 2 39 files changed, 7872 insertions(+), 6297 deletions(-) New commits: commit 2329a73fb9fbc1ac0247e438808de89dfa55ceb2 Merge: c1827cf 90ba592 Author: Martin Brumm <Dr....@t-...> Date: Wed Jun 20 21:18:18 2012 +0200 Merge remote-tracking branch '1880/rails1.7.x' into specific_1880 Conflicts: rails/game/specific/_18EU/OffBoardRevenueModifier.java test/data/real/18TN_A.report test/data/test/1835_PRHasTwoExcessTrains.report test/data/test/1835_PR_3rdTrain.report test/data/test/1835_SellDoubleShare.report diff --cc buildRails.xml index d626a97,64094c0..ac1e2a6 --- a/buildRails.xml +++ b/buildRails.xml @@@ -98,8 -97,8 +98,9 @@@ <fileset dir="."> <include name="LICENSE"/> <include name="README"/> + <include name="readme.txt"/> <include name="AUTHORS"/> + <include name="readme.txt"/> <include name="rails.bat"/> <include name="rails.sh"/> </fileset> diff --cc test/data/test/1835_PRHasTwoExcessTrains.report index c197783,1fd8626..840d05c --- a/test/data/test/1835_PRHasTwoExcessTrains.report +++ b/test/data/test/1835_PRHasTwoExcessTrains.report @@@ -1,1142 -1,1144 +1,1143 @@@ - GameIs,1835 - PlayerIs,1,Alice - PlayerIs,2,Bob - PlayerIs,3,Charlie - PlayerCash,600 - BankHas,10200 - StartOfPhase,2 - BankSizeIs,10200 - StartOfInitialRound - HasPriority,Alice - BuysItemFor,Alice,NF,100 - ALSO_GETS,Alice,CERT_NAME,BY,10 - BuysItemFor,Bob,M1,80 - FloatsWithCash,M1,80 - BuysItemFor,Charlie,LD,190 - ALSO_GETS,Charlie,PRES_CERT_NAME,SX,20 - BuysItemFor,Alice,M2,170 - FloatsWithCash,M2,170 - BuysItemFor,Bob,M3,80 - FloatsWithCash,M3,80 - BuysItemFor,Charlie,M4,160 - FloatsWithCash,M4,160 - BuysItemFor,Alice,PRES_CERT_NAME,BY,20,184 - BuysItemFor,Bob,BB,130 - BuysItemFor,Charlie,HB,160 - BuysItemFor,Alice,OBB,120 - ALSO_GETS,Alice,CERT_NAME,BY,10 - BuysItemFor,Bob,PfB,150 - ALSO_GETS,Bob,CERT_NAME,BY,10 - FloatsWithCash,BY,460 - BuysItemFor,Charlie,M5,80 - FloatsWithCash,M5,80 - CannotBuyAnything,Alice - BuysItemFor,Bob,M6,80 - FloatsWithCash,M6,80 - Has,M1,80 - Has,M2,170 - Has,M3,80 - Has,M4,160 - Has,M5,80 - Has,M6,80 - Has,BY,460 - Has,Alice,26 - Has,Bob,80 - Has,Charlie,10 - StartStockRound,1 - HasPriority,Charlie - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,1 - Has,M1,80 - Has,M2,170 - Has,M3,80 - Has,M4,160 - Has,M5,80 - Has,M6,80 - Has,BY,460 - Has,Alice,26 - Has,Bob,80 - Has,Charlie,10 - START_OR,1.1 - ReceivesFor,Alice,5,NF - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,202,H2,W - CompanyDoesNotPayDividend,M1 - BuysTrain,M1,2,IPO,80 - FirstTrainBought,2 - - CompanyOperates,M2,Alice - LaysTileAt,M2,8,E17,NW - CompanyDoesNotPayDividend,M2 - BuysTrain,M2,2,IPO,80 - - CompanyOperates,M3,Bob - LaysTileAt,M3,6,F14,NW - CompanyDoesNotPayDividend,M3 - BuysTrain,M3,2,IPO,80 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,57,G5,SW - CompanyDoesNotPayDividend,M4 - BuysTrain,M4,2,IPO,80 - BuysTrain,M4,2,IPO,80 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,D18,NE - CompanyDoesNotPayDividend,M5 - BuysTrain,M5,2,IPO,80 - - CompanyOperates,M6,Bob - LaysTileAt,M6,9,B10,NW - CompanyDoesNotPayDividend,M6 - BuysTrain,M6,2,IPO,80 - - CompanyOperates,BY,Alice - LAYS_FREE_TOKEN_ON,BY,L14 - PrivateCloses,NF - LaysTileAtFor,BY,9,K15,SW,70 - LaysTileAt,BY,1,I17,SW - LaysTileAt,BY,58,M15,SW - CompanyDoesNotPayDividend,BY - PRICE_MOVES_LOG,BY,92,C3,86,B3 - BuysTrain,BY,2,IPO,80 - BuysTrain,BY,2,IPO,80 - All 2-trains are sold out, 2+2-trains now available - BuysTrain,BY,2+2,IPO,120 - FirstTrainBought,2+2 - - EndOfOperatingRound,1.1 - ORWorthIncrease,Alice,1.1,-109 - ORWorthIncrease,Bob,1.1,34 - ORWorthIncrease,Charlie,1.1,50 - Has,M1,0 - Has,M2,90 - Has,M3,0 - Has,M4,0 - Has,M5,0 - Has,M6,0 - Has,BY,110 - Has,Alice,41 - Has,Bob,120 - Has,Charlie,60 - StartStockRound,2 - HasPriority,Charlie - PASSES,Charlie - PASSES,Alice - BUY_SHARE_LOG,Bob,10,BY,IPO,92 - PriceIsPaidTo,92,BY - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,2 - Has,M1,0 - Has,M2,90 - Has,M3,0 - Has,M4,0 - Has,M5,0 - Has,M6,0 - Has,BY,202 - Has,Alice,41 - Has,Bob,28 - Has,Charlie,60 - START_OR,2.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,69,H4,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - LaysTileAt,M2,8,D16,SE - CompanyRevenue,M2,0 - CompanyDoesNotPayDividend,M2 - - CompanyOperates,M3,Bob - LaysTileAt,M3,4,G15,NW - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,4,F6,SW - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,C19,E - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,6,A11,NW - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,202,H20,W - LaysTileAt,BY,9,F20,NW - LAYS_TOKEN_ON,BY,H20,160 - CompanyRevenue,BY,160 - CompanyPaysOutFull,BY,160 - Payout,Bob,32,2,10 - Payout,Alice,64,4,10 - PRICE_MOVES_LOG,BY,86,B3,92,C3 - - EndOfOperatingRound,2.1 - ORWorthIncrease,Alice,2.1,98 - ORWorthIncrease,Bob,2.1,154 - ORWorthIncrease,Charlie,2.1,105 - Has,M1,20 - Has,M2,90 - Has,M3,20 - Has,M4,30 - Has,M5,25 - Has,M6,30 - Has,BY,42 - Has,Alice,115 - Has,Bob,170 - Has,Charlie,165 - StartStockRound,3 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Alice,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Bob,10,BY,IPO,92 - PriceIsPaidTo,92,BY - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,3 - Has,M1,20 - Has,M2,90 - Has,M3,20 - Has,M4,30 - Has,M5,25 - Has,M6,30 - Has,BY,318 - Has,Alice,23 - Has,Bob,78 - Has,Charlie,73 - START_OR,3.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,9,J2,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - LaysTileAtFor,M2,8,D14,NW,50 - CompanyRevenue,M2,70 - CompanySplits,M2,70 - M2 receives 35 - Payout,Alice,35,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,6,H16,SE - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,9,E7,SW - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,58,B12,NW - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,8,N14,NE - LaysTileAt,BY,201,O15,NW - CompanyRevenue,BY,190 - CompanyPaysOutFull,BY,190 - Payout,Charlie,19,1,10 - Payout,Bob,57,3,10 - Payout,Alice,95,5,10 - PRICE_MOVES_LOG,BY,92,C3,100,D3 - BuysTrain,BY,2+2,IPO,120 - - EndOfOperatingRound,3.1 - ORWorthIncrease,Alice,3.1,180 - ORWorthIncrease,Bob,3.1,191 - ORWorthIncrease,Charlie,3.1,132 - Has,M1,40 - Has,M2,75 - Has,M3,40 - Has,M4,60 - Has,M5,50 - Has,M6,60 - Has,BY,198 - Has,Alice,163 - Has,Bob,245 - Has,Charlie,197 - StartStockRound,4 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,SX,IPO,88 - BUY_SHARE_LOG,Alice,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Bob,10,SX,IPO,88 - BUY_SHARE_LOG,Charlie,10,SX,IPO,88 - FloatsWithCash,SX,440 - PASSES,Alice - BUY_SHARE_LOG,Bob,10,SX,IPO,88 - PriceIsPaidTo,88,SX - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,4 - PRICE_MOVES_LOG,BY,100,D3,108,D2 - SoldOut,BY,100,D3,108,D2 - Has,M1,40 - Has,M2,75 - Has,M3,40 - Has,M4,60 - Has,M5,50 - Has,M6,60 - Has,BY,290 - Has,SX,528 - Has,Alice,71 - Has,Bob,69 - Has,Charlie,21 - START_OR,4.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,4,K3,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - CompanyRevenue,M2,70 - CompanySplits,M2,70 - M2 receives 35 - Payout,Alice,35,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,57,F10,W - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAtFor,M4,5,D8,W,50 - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,58,B14,SE - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAtFor,BY,9,J14,W,70 - LaysTileAt,BY,9,J12,W - CompanyRevenue,BY,200 - CompanyPaysOutFull,BY,200 - Payout,Bob,60,3,10 - Payout,Charlie,20,1,10 - Payout,Alice,120,6,10 - PRICE_MOVES_LOG,BY,108,D2,120,E2 - - CompanyOperates,SX,Charlie - LaysTileAt,SX,8,H18,SE - CompanyDoesNotPayDividend,SX - PRICE_MOVES_LOG,SX,88,C4,84,B4 - BuysTrain,SX,2+2,IPO,120 - PrivateCloses,LD - BuysTrain,SX,2+2,IPO,120 - All 2+2-trains are sold out, 3-trains now available - BuysTrain,SX,3,IPO,180 - FirstTrainBought,3 - StartOfPhase,3 - - EndOfOperatingRound,4.1 - ORWorthIncrease,Alice,4.1,237 - ORWorthIncrease,Bob,4.1,198 - ORWorthIncrease,Charlie,4.1,-69 - Has,M1,60 - Has,M2,110 - Has,M3,60 - Has,M4,40 - Has,M5,75 - Has,M6,90 - Has,BY,220 - Has,SX,108 - Has,Alice,236 - Has,Bob,239 - Has,Charlie,146 - StartStockRound,5 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,SX,IPO,88 - PriceIsPaidTo,88,SX - BUY_SHARE_LOG,Alice,10,SX,IPO,88 - PriceIsPaidTo,88,SX - BUY_SHARE_LOG,Bob,10,SX,IPO,88 - PriceIsPaidTo,88,SX - PASSES,Charlie - BUY_SHARE_LOG,Alice,10,SX,IPO,88 - PriceIsPaidTo,88,SX - SharesReleased,All,BA - PASSES,Bob - PASSES,Charlie - PASSES,Alice - - END_SR,5 - PRICE_MOVES_LOG,BY,120,E2,132,E1 - SoldOut,BY,120,E2,132,E1 - PRICE_MOVES_LOG,SX,84,B4,86,B3 - SoldOut,SX,84,B4,86,B3 - Has,M1,60 - Has,M2,110 - Has,M3,60 - Has,M4,40 - Has,M5,75 - Has,M6,90 - Has,BY,220 - Has,SX,460 - Has,Alice,60 - Has,Bob,151 - Has,Charlie,58 - START_OR,5.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,207,H2,E - CompanyRevenue,M1,50 - CompanySplits,M1,50 - M1 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M2,Alice - LaysTileAt,M2,209,E19,SW - CompanyRevenue,M2,80 - CompanySplits,M2,80 - M2 receives 40 - Payout,Alice,40,1,100 - BuysTrain,M2,2+2,BY,150 - - CompanyOperates,M3,Bob - LaysTileAt,M3,205,F14,SE - CompanyRevenue,M3,50 - CompanySplits,M3,50 - M3 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,14,G5,SW - CompanyRevenue,M4,80 - CompanySplits,M4,80 - M4 receives 40 - Payout,Charlie,40,1,100 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,208,H20,W - CompanyRevenue,M5,80 - CompanySplits,M5,80 - M5 receives 40 - Payout,Charlie,40,1,100 - BuysTrain,M5,2+2,SX,115 - - CompanyOperates,M6,Bob - LaysTileAt,M6,12,A11,W - CompanyRevenue,M6,70 - CompanySplits,M6,70 - M6 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,9,J10,W - LAYS_TOKEN_ON,BY,J8,120 - CompanyRevenue,BY,240 - CompanyPaysOutFull,BY,240 - Payout,Bob,72,3,10 - Payout,Alice,144,6,10 - Payout,Charlie,24,1,10 - PRICE_MOVES_LOG,BY,132,E1,148,F1 - BuysTrain,BY,3,IPO,180 - - CompanyOperates,SX,Charlie - LaysTileAt,SX,13,H16,W - LAYS_TOKEN_ON,SX,E19,60 - CompanyRevenue,SX,190 - CompanyPaysOutFull,SX,190 - Payout,Alice,38,2,10 - Payout,Bob,57,3,10 - Payout,Charlie,95,5,10 - PRICE_MOVES_LOG,SX,86,B3,92,C3 - BuysTrain,SX,3,IPO,180 - BuysTrain,SX,3,IPO,180 - All 3-trains are sold out, 3+3-trains now available - - EndOfOperatingRound,5.1 - ORWorthIncrease,Alice,5.1,340 - ORWorthIncrease,Bob,5.1,320 - ORWorthIncrease,Charlie,5.1,275 - Has,M1,85 - Has,M2,0 - Has,M3,85 - Has,M4,80 - Has,M5,0 - Has,M6,125 - Has,BY,70 - Has,SX,155 - Has,Alice,292 - Has,Bob,405 - Has,Charlie,287 - START_OR,5.2 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAtFor,M1,211,G3,E,50 - CompanyRevenue,M1,70 - CompanySplits,M1,70 - M1 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,M2,Alice - LaysTileAt,M2,23,D18,NW - CompanyRevenue,M2,180 - CompanySplits,M2,180 - M2 receives 90 - Payout,Alice,90,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,8,F8,E - CompanyRevenue,M3,50 - CompanySplits,M3,50 - M3 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,8,G7,W - CompanyRevenue,M4,110 - CompanySplits,M4,110 - M4 receives 55 - Payout,Charlie,55,1,100 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,C17,SE - CompanyRevenue,M5,180 - CompanySplits,M5,180 - M5 receives 90 - Payout,Charlie,90,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,8,C15,NW - CompanyRevenue,M6,70 - CompanySplits,M6,70 - M6 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,BY,Alice - LaysTileAtFor,BY,214,J6,SE,50 - CompanyRevenue,BY,330 - CompanyPaysOutFull,BY,330 - Payout,Alice,198,6,10 - Payout,Bob,99,3,10 - Payout,Charlie,33,1,10 - PRICE_MOVES_LOG,BY,148,F1,166,G1 - - CompanyOperates,SX,Charlie - LaysTileAt,SX,23,H18,E - LAYS_TOKEN_ON,SX,H20,40 - CompanyRevenue,SX,370 - CompanyPaysOutFull,SX,370 - Payout,Alice,74,2,10 - Payout,Bob,111,3,10 - Payout,Charlie,185,5,10 - PRICE_MOVES_LOG,SX,92,C3,100,D3 - - EndOfOperatingRound,5.2 - ORWorthIncrease,Alice,5.2,496 - ORWorthIncrease,Bob,5.2,423 - ORWorthIncrease,Charlie,5.2,451 - Has,M1,70 - Has,M2,90 - Has,M3,110 - Has,M4,135 - Has,M5,90 - Has,M6,160 - Has,BY,20 - Has,SX,115 - Has,Alice,664 - Has,Bob,750 - Has,Charlie,680 - StartStockRound,6 - HasPriority,Bob - START_COMPANY_LOG,Bob,BA,84,168,2,20,BANK - SharesReleased,4 10%,PR - BUY_SHARE_LOG,Charlie,10,BA,IPO,84 - BUY_SHARE_LOG,Alice,10,BA,IPO,84 - BUY_SHARE_LOG,Bob,10,BA,IPO,84 - FloatsWithCash,BA,420 - SharesReleased,All,WT - BUY_SHARE_LOG,Charlie,10,BA,IPO,84 - PriceIsPaidTo,84,BA - START_COMPANY_LOG,Alice,WT,84,168,2,20,BANK - BUY_SHARE_LOG,Bob,10,BA,IPO,84 - PriceIsPaidTo,84,BA - BUY_SHARE_LOG,Charlie,10,BA,IPO,84 - PriceIsPaidTo,84,BA - BUY_SHARE_LOG,Alice,10,WT,IPO,84 - BUY_SHARE_LOG,Bob,20,BA,IPO,168 - PriceIsPaidTo,168,BA - BUY_SHARE_LOG,Charlie,10,WT,IPO,84 - BUY_SHARE_LOG,Alice,10,WT,IPO,84 - FloatsWithCash,WT,420 - SharesReleased,All,HE - BUY_SHARE_LOG,Bob,10,WT,IPO,84 - PriceIsPaidTo,84,WT - START_COMPANY_LOG,Charlie,HE,84,168,2,20,BANK - BUY_SHARE_LOG,Alice,10,HE,IPO,84 - BUY_SHARE_LOG,Bob,10,HE,IPO,84 - BUY_SHARE_LOG,Charlie,10,HE,IPO,84 - FloatsWithCash,HE,420 - BUY_SHARE_LOG,Alice,10,HE,IPO,84 - PriceIsPaidTo,84,HE - PASSES,Bob - BUY_SHARE_LOG,Charlie,10,HE,IPO,84 - PriceIsPaidTo,84,HE - PASSES,Alice - PASSES,Bob - PASSES,Charlie - - END_SR,6 - PRICE_STAYS_LOG,BY,166,G1 - SoldOutNoRaise,BY,166,G1 - PRICE_MOVES_LOG,SX,100,D3,108,D2 - SoldOut,SX,100,D3,108,D2 - PRICE_MOVES_LOG,BA,84,B4,86,B3 - SoldOut,BA,84,B4,86,B3 - Has,M1,70 - Has,M2,90 - Has,M3,110 - Has,M4,135 - Has,M5,90 - Has,M6,160 - Has,BY,20 - Has,SX,115 - Has,BA,840 - Has,WT,504 - Has,HE,588 - Has,Alice,76 - Has,Bob,78 - Has,Charlie,8 - START_OR,6.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,9,I5,SE - CompanyRevenue,M1,70 - CompanySplits,M1,70 - M1 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,M2,Alice - CompanyRevenue,M2,180 - CompanySplits,M2,180 - M2 receives 90 - Payout,Alice,90,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,206,F10,SE - CompanyRevenue,M3,50 - CompanySplits,M3,50 - M3 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,15,D8,NE - CompanyRevenue,M4,110 - CompanySplits,M4,110 - M4 receives 55 - Payout,Charlie,55,1,100 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,180 - CompanySplits,M5,180 - M5 receives 90 - Payout,Charlie,90,1,100 - - CompanyOperates,M6,Bob - CompanyRevenue,M6,70 - CompanySplits,M6,70 - M6 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,8,K5,NE - CompanyRevenue,BY,330 - CompanyPaysOutFull,BY,330 - Payout,Alice,198,6,10 - Payout,Bob,99,3,10 - Payout,Charlie,33,1,10 - PRICE_MOVES_LOG,BY,166,G1,186,H1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,370 - CompanyPaysOutFull,SX,370 - Payout,Alice,74,2,10 - Payout,Bob,111,3,10 - Payout,Charlie,185,5,10 - PRICE_MOVES_LOG,SX,108,D2,120,E2 - - CompanyOperates,BA,Bob - LaysTileAt,BA,210,L6,E - CompanyDoesNotPayDividend,BA - PRICE_MOVES_LOG,BA,86,B3,82,A3 - BuysTrain,BA,3+3,IPO,270 - FirstTrainBought,3+3 - BuysTrain,BA,3+3,IPO,270 - BuysTrain,BA,3+3,IPO,270 - All 3+3-trains are sold out, 4-trains now available - - CompanyOperates,WT,Alice - LaysTileAt,WT,57,M9,W - CompanyDoesNotPayDividend,WT - PRICE_MOVES_LOG,WT,84,B4,78,A4 - BuysTrain,WT,4,IPO,360 - FirstTrainBought,4 - StartOfPhase,4 - CompanyDiscardsTrain,SX,2+2 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRound,PR,OperatingRound 6.1 - - CompanyOperates,HE,Charlie - LaysTileAtFor,HE,9,K7,SW,50 - CompanyDoesNotPayDividend,HE - PRICE_MOVES_LOG,HE,84,B4,78,A4 - BuysTrain,HE,4,IPO,360 - - EndOfOperatingRound,6.1 - ORWorthIncrease,Alice,6.1,476 - ORWorthIncrease,Bob,6.1,405 - ORWorthIncrease,Charlie,6.1,431 - Has,M1,105 - Has,M2,180 - Has,M3,135 - Has,M4,190 - Has,M5,180 - Has,M6,195 - Has,BY,20 - Has,SX,115 - Has,BA,30 - Has,WT,144 - Has,HE,178 - Has,Alice,448 - Has,Bob,423 - Has,Charlie,401 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRoundNoInterrupt,PR - START_OR,6.2 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,8,D10,W - CompanyDoesNotPayDividend,M1 - BuysTrain,M1,3+3,BA,105 - - CompanyOperates,M2,Alice - LaysTileAt,M2,203,B12,W - CompanyRevenue,M2,100 - CompanySplits,M2,100 - M2 receives 50 - Payout,Alice,50,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,9,F16,W - CompanyDoesNotPayDividend,M3 - - CompanyOperates,M4,Charlie - CompanyDoesNotPayDividend,M4 - BuysTrain,M4,3,SX,190 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,100 - CompanySplits,M5,100 - M5 receives 50 - Payout,Charlie,50,1,100 - - CompanyOperates,M6,Bob - CompanyDoesNotPayDividend,M6 - BuysTrain,M6,3+3,BA,195 - - CompanyOperates,BY,Alice - LaysTileAt,BY,23,F20,NW - CompanyRevenue,BY,180 - CompanyPaysOutFull,BY,180 - Payout,Alice,108,6,10 - Payout,Bob,54,3,10 - Payout,Charlie,18,1,10 - PRICE_MOVES_LOG,BY,186,H1,208,I1 - BuysTrain,BY,2+2,M2,1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,220 - CompanyPaysOutFull,SX,220 - Payout,Alice,44,2,10 - Payout,Bob,66,3,10 - Payout,Charlie,110,5,10 - PRICE_MOVES_LOG,SX,120,E2,134,F2 - BuysTrain,SX,2+2,M5,1 - - CompanyOperates,BA,Bob - CompanyRevenue,BA,120 - CompanyPaysOutFull,BA,120 - Payout,Alice,12,1,10 - Payout,Bob,72,6,10 - Payout,Charlie,36,3,10 - PRICE_MOVES_LOG,BA,82,A3,86,B3 - BuysTrain,BA,3+3,M1,1 - - CompanyOperates,WT,Alice - LaysTileAt,WT,9,M11,W - CompanyRevenue,WT,0 - CompanyDoesNotPayDividend,WT - PRICE_MOVES_LOG,WT,78,A4,72,A5 - - CompanyOperates,HE,Charlie - CompanyRevenue,HE,130 - CompanyPaysOutFull,HE,130 - Payout,Alice,26,2,10 - Payout,Bob,13,1,10 - Payout,Charlie,52,4,10 - PRICE_MOVES_LOG,HE,78,A4,84,B4 - BuysTrain,HE,3+3,M6,1 - - EndOfOperatingRound,6.2 - ORWorthIncrease,Alice,6.2,402 - ORWorthIncrease,Bob,6.2,377 - ORWorthIncrease,Charlie,6.2,418 - Has,M1,1 - Has,M2,231 - Has,M3,135 - Has,M4,0 - Has,M5,231 - Has,M6,1 - Has,BY,19 - Has,SX,304 - Has,BA,329 - Has,WT,144 - Has,HE,177 - Has,Alice,698 - Has,Bob,668 - Has,Charlie,697 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRoundNoInterrupt,PR - StartStockRound,7 - HasPriority,Alice - BUY_SHARE_LOG,Alice,10,PR,IPO,154 - BUY_SHARE_LOG,Bob,10,PR,IPO,154 - BUY_SHARE_LOG,Charlie,10,PR,IPO,154 - BUY_SHARE_LOG,Alice,10,PR,IPO,154 - SELL_SHARE_LOG,Bob,10,BY,208 - PRICE_MOVES_LOG,BY,208,I1,188,I2 - BUY_SHARE_LOG,Charlie,10,HE,IPO,84 - PriceIsPaidTo,84,HE - BUY_SHARE_LOG,Alice,10,BY,Pool,188 - BUY_SHARE_LOG,Bob,20,HE,IPO,168 - PriceIsPaidTo,168,HE - BUY_SHARE_LOG,Charlie,10,WT,IPO,84 - PriceIsPaidTo,84,WT - BUY_SHARE_LOG,Alice,10,WT,IPO,84 - PriceIsPaidTo,84,WT - PASSES,Bob - PASSES,Charlie - PASSES,Alice - - END_SR,7 - PRICE_MOVES_LOG,BY,188,I2,208,I1 - SoldOut,BY,188,I2,208,I1 - PRICE_MOVES_LOG,SX,134,F2,148,F1 - SoldOut,SX,134,F2,148,F1 - SoldOutNoRaise,BA,86,B3 - PRICE_MOVES_LOG,HE,84,B4,86,B3 - SoldOut,HE,84,B4,86,B3 - Has,M1,1 - Has,M2,231 - Has,M3,135 - Has,M4,0 - Has,M5,231 - Has,M6,1 - Has,BY,19 - Has,SX,304 - Has,BA,329 - Has,WT,312 - Has,HE,429 - Has,Alice,118 - Has,Bob,554 - Has,Charlie,375 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRoundNoInterrupt,PR - START_OR,7.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - CompanyDoesNotPayDividend,M1 - - CompanyOperates,M2,Alice - CompanyDoesNotPayDividend,M2 - BuysTrain,M2,2+2,BY,231 - - CompanyOperates,M3,Bob - CompanyDoesNotPayDividend,M3 - BuysTrain,M3,3+3,BA,135 - - CompanyOperates,M4,Charlie - CompanyRevenue,M4,90 - CompanySplits,M4,90 - M4 receives 45 - Payout,Charlie,45,1,100 - - CompanyOperates,M5,Charlie - CompanyDoesNotPayDividend,M5 - BuysTrain,M5,2+2,SX,231 - - CompanyOperates,M6,Bob - CompanyDoesNotPayDividend,M6 - - CompanyOperates,BY,Alice - CompanyRevenue,BY,190 - CompanyPaysOutFull,BY,190 - Payout,Alice,133,7,10 - Payout,Bob,38,2,10 - Payout,Charlie,19,1,10 - PRICE_MOVES_LOG,BY,208,I1,232,J1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,220 - CompanyPaysOutFull,SX,220 - Payout,Alice,44,2,10 - Payout,Bob,66,3,10 - Payout,Charlie,110,5,10 - PRICE_MOVES_LOG,SX,148,F1,166,G1 - BuysTrain,SX,4,IPO,360 - All 4-trains are sold out, 4+4-trains now available - - CompanyOperates,BA,Bob - CompanyRevenue,BA,120 - CompanyPaysOutFull,BA,120 - Payout,Alice,12,1,10 - Payout,Bob,72,6,10 - Payout,Charlie,36,3,10 - PRICE_MOVES_LOG,BA,86,B3,92,C3 - BuysTrain,BA,4+4,IPO,440 - All 4+4-trains are sold out, 5-trains now available - FirstTrainBought,4+4 - StartOfPhase,4+4 - StartFormationRound,PR - START_MERGED_COMPANY,PR,154,154 - FloatsWithCash,PR,616 - MERGE_MINOR_LOG,Alice,M2,PR,0,0 - GetShareForMinor,Alice,10,PR,IPO,M2 - ExchangesBaseToken,PR,M2,E19/1 - - EndOfFormationRound,PR,OperatingRound 7.1 - - CompanyOperates,HE,Charlie - LaysTileAt,HE,8,L4,NW - LAYS_TOKEN_ON,HE,G5,60 - CompanyRevenue,HE,260 - CompanyPaysOutFull,HE,260 - Payout,Alice,52,2,10 - Payout,Bob,78,3,10 - Payout,Charlie,130,5,10 - PRICE_MOVES_LOG,HE,86,B3,92,C3 - - CompanyOperates,WT,Alice - LaysTileAt,WT,69,M7,SE - CompanyRevenue,WT,280 - CompanyWithholds,WT,280 - PRICE_MOVES_LOG,WT,72,A5,64,A6 - - EndOfOperatingRound,7.1 - ORWorthIncrease,Alice,7.1,587 - ORWorthIncrease,Bob,7.1,442 - ORWorthIncrease,Charlie,7.1,516 - Has,M1,1 - Has,M3,0 - Has,M4,45 - Has,M5,0 - Has,M6,1 - Has,BY,250 - Has,SX,175 - Has,BA,24 - Has,WT,592 - Has,HE,369 - Has,PR,616 - Has,Alice,369 - Has,Bob,848 - Has,Charlie,745 - StartFormationRound,PR - - EndOfFormationRoundNoInterrupt,PR - START_OR,7.2 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - CompanyDoesNotPayDividend,M1 - BuysTrain,M1,3+3,BA,1 - - CompanyOperates,M3,Bob - CompanyRevenue,M3,90 - CompanySplits,M3,90 - M3 receives 45 - Payout,Bob,45,1,100 - - CompanyOperates,M4,Charlie - CompanyRevenue,M4,90 - CompanySplits,M4,90 - M4 receives 45 - Payout,Charlie,45,1,100 - - CompanyOperates,M5,Charlie - CompanyDoesNotPayDividend,M5 - - CompanyOperates,M6,Bob - CompanyDoesNotPayDividend,M6 - BuysTrain,M6,3,SX,1 - - CompanyOperates,BY,Alice - CompanyRevenue,BY,110 - CompanyPaysOutFull,BY,110 - Payout,Alice,77,7,10 - Payout,Bob,22,2,10 - Payout,Charlie,11,1,10 - PRICE_MOVES_LOG,BY,232,J1,258,K1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,240 - CompanyPaysOutFull,SX,240 - Payout,Alice,48,2,10 - Payout,Bob,72,3,10 - Payout,Charlie,120,5,10 - PRICE_MOVES_LOG,SX,166,G1,186,H1 - - CompanyOperates,PR,Alice - CompanyDoesNotPayDividend,PR - PRICE_MOVES_LOG,PR,154,I4,138,H4 - BuysTrain,PR,5,IPO,500 - FirstTrainBought,5 - StartOfPhase,5 - PhaseClosesAllPrivates, - PrivateCloses,OBB - PrivateCloses,PfB - StartFormationRound,PR - MERGE_MINOR_LOG,Bob,BB,PR,no,no - GetShareForMinor,Bob,10,PR,IPO,BB - PrivateCloses,BB - MERGE_MINOR_LOG,Charlie,HB,PR,no,no - GetShareForMinor,Charlie,10,PR,IPO,HB - PrivateCloses,HB - MERGE_MINOR_LOG,Bob,M1,PR,0,1 - GetShareForMinor,Bob,5,PR,IPO,M1 - ExchangesBaseToken,PR,M1,H2/1 - MERGE_MINOR_LOG,Bob,M3,PR,45,1 - GetShareForMinor,Bob,5,PR,IPO,M3 - ExchangesBaseToken,PR,M3,F14/1 - MERGE_MINOR_LOG,Charlie,M4,PR,90,1 - GetShareForMinor,Charlie,10,PR,IPO,M4 - ExchangesBaseToken,PR,M4,G5/1 - MERGE_MINOR_LOG,Charlie,M5,PR,0,0 - GetShareForMinor,Charlie,5,PR,IPO,M5 - MERGE_MINOR_LOG,Bob,M6,PR,0,1 - GetShareForMinor,Bob,5,PR,IPO,M6 - ExchangesBaseToken,PR,M6,C11/1 - CompanyDiscardsTrain,PR,3 - CompanyDiscardsTrain,PR,3 - - EndOfFormationRound,PR,OperatingRound 7.2 - IS_NOW_PRES_OF,Bob,PR - + GameIs,1835 + PlayerIs,1,Alice + PlayerIs,2,Bob + PlayerIs,3,Charlie + PlayerCash,600 + BankHas,10200 + StartOfPhase,2 + BankSizeIs,10200 + StartOfInitialRound + HasPriority,Alice + BuysItemFor,Alice,NF,100 + ALSO_GETS,Alice,CERT_NAME,BY,10 + BuysItemFor,Bob,M1,80 + FloatsWithCash,M1,80 + BuysItemFor,Charlie,LD,190 + ALSO_GETS,Charlie,PRES_CERT_NAME,SX,20 + BuysItemFor,Alice,M2,170 + FloatsWithCash,M2,170 + BuysItemFor,Bob,M3,80 + FloatsWithCash,M3,80 + BuysItemFor,Charlie,M4,160 + FloatsWithCash,M4,160 + BuysItemFor,Alice,PRES_CERT_NAME,BY,20,184 + BuysItemFor,Bob,BB,130 + BuysItemFor,Charlie,HB,160 + BuysItemFor,Alice,OBB,120 + ALSO_GETS,Alice,CERT_NAME,BY,10 + BuysItemFor,Bob,PfB,150 + ALSO_GETS,Bob,CERT_NAME,BY,10 + FloatsWithCash,BY,460 + BuysItemFor,Charlie,M5,80 + FloatsWithCash,M5,80 + CannotBuyAnything,Alice + BuysItemFor,Bob,M6,80 + FloatsWithCash,M6,80 + Has,M1,80 + Has,M2,170 + Has,M3,80 + Has,M4,160 + Has,M5,80 + Has,M6,80 + Has,BY,460 + Has,Alice,26 + Has,Bob,80 + Has,Charlie,10 + StartStockRound,1 + HasPriority,Charlie + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,1 + Has,M1,80 + Has,M2,170 + Has,M3,80 + Has,M4,160 + Has,M5,80 + Has,M6,80 + Has,BY,460 + Has,Alice,26 + Has,Bob,80 + Has,Charlie,10 + START_OR,1.1 + ReceivesFor,Alice,5,NF + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,202,H2,W + CompanyDoesNotPayDividend,M1 + BuysTrain,M1,2,IPO,80 + FirstTrainBought,2 + + CompanyOperates,M2,Alice + LaysTileAt,M2,8,E17,NW + CompanyDoesNotPayDividend,M2 + BuysTrain,M2,2,IPO,80 + + CompanyOperates,M3,Bob + LaysTileAt,M3,6,F14,NW + CompanyDoesNotPayDividend,M3 + BuysTrain,M3,2,IPO,80 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,57,G5,SW + CompanyDoesNotPayDividend,M4 + BuysTrain,M4,2,IPO,80 + BuysTrain,M4,2,IPO,80 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,8,D18,NE + CompanyDoesNotPayDividend,M5 + BuysTrain,M5,2,IPO,80 + + CompanyOperates,M6,Bob + LaysTileAt,M6,9,B10,NW + CompanyDoesNotPayDividend,M6 + BuysTrain,M6,2,IPO,80 + + CompanyOperates,BY,Alice + LAYS_FREE_TOKEN_ON,BY,L14 + PrivateCloses,NF + LaysTileAtFor,BY,9,K15,SW,70 + LaysTileAt,BY,1,I17,SW + LaysTileAt,BY,58,M15,SW + CompanyDoesNotPayDividend,BY + PRICE_MOVES_LOG,BY,92,C3,86,B3 + BuysTrain,BY,2,IPO,80 + BuysTrain,BY,2,IPO,80 + All 2-trains are sold out, 2+2-trains now available + BuysTrain,BY,2+2,IPO,120 + FirstTrainBought,2+2 + + EndOfOperatingRound,1.1 + ORWorthIncrease,Alice,1.1,-109 + ORWorthIncrease,Bob,1.1,34 + ORWorthIncrease,Charlie,1.1,50 + Has,M1,0 + Has,M2,90 + Has,M3,0 + Has,M4,0 + Has,M5,0 + Has,M6,0 + Has,BY,110 + Has,Alice,41 + Has,Bob,120 + Has,Charlie,60 + StartStockRound,2 + HasPriority,Charlie + PASSES,Charlie + PASSES,Alice + BUY_SHARE_LOG,Bob,10,BY,IPO,92 + PriceIsPaidTo,92,BY + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,2 + Has,M1,0 + Has,M2,90 + Has,M3,0 + Has,M4,0 + Has,M5,0 + Has,M6,0 + Has,BY,202 + Has,Alice,41 + Has,Bob,28 + Has,Charlie,60 + START_OR,2.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,69,H4,NW + CompanyRevenue,M1,40 + CompanySplits,M1,40 + M1 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M2,Alice + LaysTileAt,M2,8,D16,SE + CompanyRevenue,M2,0 + CompanyDoesNotPayDividend,M2 + + CompanyOperates,M3,Bob + LaysTileAt,M3,4,G15,NW + CompanyRevenue,M3,40 + CompanySplits,M3,40 + M3 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,4,F6,SW + CompanyRevenue,M4,60 + CompanySplits,M4,60 + M4 receives 30 + Payout,Charlie,30,1,100 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,8,C19,E + CompanyRevenue,M5,50 + CompanySplits,M5,50 + M5 receives 25 + Payout,Charlie,25,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,6,A11,NW + CompanyRevenue,M6,60 + CompanySplits,M6,60 + M6 receives 30 + Payout,Bob,30,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,202,H20,W + LaysTileAt,BY,9,F20,NW + LAYS_TOKEN_ON,BY,H20,160 + CompanyRevenue,BY,160 + CompanyPaysOutFull,BY,160 + Payout,Bob,32,2,10 + Payout,Alice,64,4,10 + PRICE_MOVES_LOG,BY,86,B3,92,C3 + + EndOfOperatingRound,2.1 + ORWorthIncrease,Alice,2.1,98 + ORWorthIncrease,Bob,2.1,154 + ORWorthIncrease,Charlie,2.1,105 + Has,M1,20 + Has,M2,90 + Has,M3,20 + Has,M4,30 + Has,M5,25 + Has,M6,30 + Has,BY,42 + Has,Alice,115 + Has,Bob,170 + Has,Charlie,165 + StartStockRound,3 + HasPriority,Charlie + BUY_SHARE_LOG,Charlie,10,BY,IPO,92 + PriceIsPaidTo,92,BY + BUY_SHARE_LOG,Alice,10,BY,IPO,92 + PriceIsPaidTo,92,BY + BUY_SHARE_LOG,Bob,10,BY,IPO,92 + PriceIsPaidTo,92,BY + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,3 + Has,M1,20 + Has,M2,90 + Has,M3,20 + Has,M4,30 + Has,M5,25 + Has,M6,30 + Has,BY,318 + Has,Alice,23 + Has,Bob,78 + Has,Charlie,73 + START_OR,3.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,9,J2,NW + CompanyRevenue,M1,40 + CompanySplits,M1,40 + M1 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M2,Alice + LaysTileAtFor,M2,8,D14,NW,50 + CompanyRevenue,M2,70 + CompanySplits,M2,70 + M2 receives 35 + Payout,Alice,35,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,6,H16,SE + CompanyRevenue,M3,40 + CompanySplits,M3,40 + M3 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,9,E7,SW + CompanyRevenue,M4,60 + CompanySplits,M4,60 + M4 receives 30 + Payout,Charlie,30,1,100 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,50 + CompanySplits,M5,50 + M5 receives 25 + Payout,Charlie,25,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,58,B12,NW + CompanyRevenue,M6,60 + CompanySplits,M6,60 + M6 receives 30 + Payout,Bob,30,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,8,N14,NE + LaysTileAt,BY,201,O15,NW + CompanyRevenue,BY,190 + CompanyPaysOutFull,BY,190 + Payout,Charlie,19,1,10 + Payout,Bob,57,3,10 + Payout,Alice,95,5,10 + PRICE_MOVES_LOG,BY,92,C3,100,D3 + BuysTrain,BY,2+2,IPO,120 + + EndOfOperatingRound,3.1 + ORWorthIncrease,Alice,3.1,180 + ORWorthIncrease,Bob,3.1,191 + ORWorthIncrease,Charlie,3.1,132 + Has,M1,40 + Has,M2,75 + Has,M3,40 + Has,M4,60 + Has,M5,50 + Has,M6,60 + Has,BY,198 + Has,Alice,163 + Has,Bob,245 + Has,Charlie,197 + StartStockRound,4 + HasPriority,Charlie + BUY_SHARE_LOG,Charlie,10,SX,IPO,88 + BUY_SHARE_LOG,Alice,10,BY,IPO,92 + PriceIsPaidTo,92,BY + BUY_SHARE_LOG,Bob,10,SX,IPO,88 + BUY_SHARE_LOG,Charlie,10,SX,IPO,88 + FloatsWithCash,SX,440 + PASSES,Alice + BUY_SHARE_LOG,Bob,10,SX,IPO,88 + PriceIsPaidTo,88,SX + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,4 + PRICE_MOVES_LOG,BY,100,D3,108,D2 + SoldOut,BY,100,D3,108,D2 + Has,M1,40 + Has,M2,75 + Has,M3,40 + Has,M4,60 + Has,M5,50 + Has,M6,60 + Has,BY,290 + Has,SX,528 + Has,Alice,71 + Has,Bob,69 + Has,Charlie,21 + START_OR,4.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,4,K3,NW + CompanyRevenue,M1,40 + CompanySplits,M1,40 + M1 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M2,Alice + CompanyRevenue,M2,70 + CompanySplits,M2,70 + M2 receives 35 + Payout,Alice,35,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,57,F10,W + CompanyRevenue,M3,40 + CompanySplits,M3,40 + M3 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M4,Charlie + LaysTileAtFor,M4,5,D8,W,50 + CompanyRevenue,M4,60 + CompanySplits,M4,60 + M4 receives 30 + Payout,Charlie,30,1,100 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,50 + CompanySplits,M5,50 + M5 receives 25 + Payout,Charlie,25,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,58,B14,SE + CompanyRevenue,M6,60 + CompanySplits,M6,60 + M6 receives 30 + Payout,Bob,30,1,100 + + CompanyOperates,BY,Alice + LaysTileAtFor,BY,9,J14,W,70 + LaysTileAt,BY,9,J12,W + CompanyRevenue,BY,200 + CompanyPaysOutFull,BY,200 + Payout,Bob,60,3,10 + Payout,Charlie,20,1,10 + Payout,Alice,120,6,10 + PRICE_MOVES_LOG,BY,108,D2,120,E2 + + CompanyOperates,SX,Charlie + LaysTileAt,SX,8,H18,SE + CompanyDoesNotPayDividend,SX + PRICE_MOVES_LOG,SX,88,C4,84,B4 + BuysTrain,SX,2+2,IPO,120 + PrivateCloses,LD + BuysTrain,SX,2+2,IPO,120 + All 2+2-trains are sold out, 3-trains now available + BuysTrain,SX,3,IPO,180 + FirstTrainBought,3 + StartOfPhase,3 + + EndOfOperatingRound,4.1 + ORWorthIncrease,Alice,4.1,237 + ORWorthIncrease,Bob,4.1,198 + ORWorthIncrease,Charlie,4.1,-69 + Has,M1,60 + Has,M2,110 + Has,M3,60 + Has,M4,40 + Has,M5,75 + Has,M6,90 + Has,BY,220 + Has,SX,108 + Has,Alice,236 + Has,Bob,239 + Has,Charlie,146 + StartStockRound,5 + HasPriority,Charlie + BUY_SHARE_LOG,Charlie,10,SX,IPO,88 + PriceIsPaidTo,88,SX + BUY_SHARE_LOG,Alice,10,SX,IPO,88 + PriceIsPaidTo,88,SX + BUY_SHARE_LOG,Bob,10,SX,IPO,88 + PriceIsPaidTo,88,SX + PASSES,Charlie + BUY_SHARE_LOG,Alice,10,SX,IPO,88 + PriceIsPaidTo,88,SX + SharesReleased,All,BA + PASSES,Bob + PASSES,Charlie + PASSES,Alice + + END_SR,5 + PRICE_MOVES_LOG,BY,120,E2,132,E1 + SoldOut,BY,120,E2,132,E1 + PRICE_MOVES_LOG,SX,84,B4,86,B3 + SoldOut,SX,84,B4,86,B3 + Has,M1,60 + Has,M2,110 + Has,M3,60 + Has,M4,40 + Has,M5,75 + Has,M6,90 + Has,BY,220 + Has,SX,460 + Has,Alice,60 + Has,Bob,151 + Has,Charlie,58 + START_OR,5.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,207,H2,E + CompanyRevenue,M1,50 + CompanySplits,M1,50 + M1 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M2,Alice + LaysTileAt,M2,209,E19,SW + CompanyRevenue,M2,80 + CompanySplits,M2,80 + M2 receives 40 + Payout,Alice,40,1,100 + BuysTrain,M2,2+2,BY,150 + + CompanyOperates,M3,Bob + LaysTileAt,M3,205,F14,SE + CompanyRevenue,M3,50 + CompanySplits,M3,50 + M3 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,14,G5,SW + CompanyRevenue,M4,80 + CompanySplits,M4,80 + M4 receives 40 + Payout,Charlie,40,1,100 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,208,H20,W + CompanyRevenue,M5,80 + CompanySplits,M5,80 + M5 receives 40 + Payout,Charlie,40,1,100 + BuysTrain,M5,2+2,SX,115 + + CompanyOperates,M6,Bob + LaysTileAt,M6,12,A11,W + CompanyRevenue,M6,70 + CompanySplits,M6,70 + M6 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,9,J10,W + LAYS_TOKEN_ON,BY,J8,120 + CompanyRevenue,BY,240 + CompanyPaysOutFull,BY,240 + Payout,Bob,72,3,10 + Payout,Alice,144,6,10 + Payout,Charlie,24,1,10 + PRICE_MOVES_LOG,BY,132,E1,148,F1 + BuysTrain,BY,3,IPO,180 + + CompanyOperates,SX,Charlie + LaysTileAt,SX,13,H16,W + LAYS_TOKEN_ON,SX,E19,60 + CompanyRevenue,SX,190 + CompanyPaysOutFull,SX,190 + Payout,Alice,38,2,10 + Payout,Bob,57,3,10 + Payout,Charlie,95,5,10 + PRICE_MOVES_LOG,SX,86,B3,92,C3 + BuysTrain,SX,3,IPO,180 + BuysTrain,SX,3,IPO,180 + All 3-trains are sold out, 3+3-trains now available + + EndOfOperatingRound,5.1 + ORWorthIncrease,Alice,5.1,340 + ORWorthIncrease,Bob,5.1,320 + ORWorthIncrease,Charlie,5.1,275 + Has,M1,85 + Has,M2,0 + Has,M3,85 + Has,M4,80 + Has,M5,0 + Has,M6,125 + Has,BY,70 + Has,SX,155 + Has,Alice,292 + Has,Bob,405 + Has,Charlie,287 + START_OR,5.2 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAtFor,M1,211,G3,E,50 + CompanyRevenue,M1,70 + CompanySplits,M1,70 + M1 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,M2,Alice + LaysTileAt,M2,23,D18,NW + CompanyRevenue,M2,180 + CompanySplits,M2,180 + M2 receives 90 + Payout,Alice,90,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,8,F8,E + CompanyRevenue,M3,50 + CompanySplits,M3,50 + M3 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,8,G7,W + CompanyRevenue,M4,110 + CompanySplits,M4,110 + M4 receives 55 + Payout,Charlie,55,1,100 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,8,C17,SE + CompanyRevenue,M5,180 + CompanySplits,M5,180 + M5 receives 90 + Payout,Charlie,90,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,8,C15,NW + CompanyRevenue,M6,70 + CompanySplits,M6,70 + M6 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,BY,Alice + LaysTileAtFor,BY,214,J6,SE,50 + CompanyRevenue,BY,330 + CompanyPaysOutFull,BY,330 + Payout,Alice,198,6,10 + Payout,Bob,99,3,10 + Payout,Charlie,33,1,10 + PRICE_MOVES_LOG,BY,148,F1,166,G1 + + CompanyOperates,SX,Charlie + LaysTileAt,SX,23,H18,E + LAYS_TOKEN_ON,SX,H20,40 + CompanyRevenue,SX,370 + CompanyPaysOutFull,SX,370 + Payout,Alice,74,2,10 + Payout,Bob,111,3,10 + Payout,Charlie,185,5,10 + PRICE_MOVES_LOG,SX,92,C3,100,D3 + + EndOfOperatingRound,5.2 + ORWorthIncrease,Alice,5.2,496 + ORWorthIncrease,Bob,5.2,423 + ORWorthIncrease,Charlie,5.2,451 + Has,M1,70 + Has,M2,90 + Has,M3,110 + Has,M4,135 + Has,M5,90 + Has,M6,160 + Has,BY,20 + Has,SX,115 + Has,Alice,664 + Has,Bob,750 + Has,Charlie,680 + StartStockRound,6 + HasPriority,Bob + START_COMPANY_LOG,Bob,BA,84,168,2,20,BANK + SharesReleased,4 10%,PR + BUY_SHARE_LOG,Charlie,10,BA,IPO,84 + BUY_SHARE_LOG,Alice,10,BA,IPO,84 + BUY_SHARE_LOG,Bob,10,BA,IPO,84 + FloatsWithCash,BA,420 + SharesReleased,All,WT + BUY_SHARE_LOG,Charlie,10,BA,IPO,84 + PriceIsPaidTo,84,BA + START_COMPANY_LOG,Alice,WT,84,168,2,20,BANK + BUY_SHARE_LOG,Bob,10,BA,IPO,84 + PriceIsPaidTo,84,BA + BUY_SHARE_LOG,Charlie,10,BA,IPO,84 + PriceIsPaidTo,84,BA + BUY_SHARE_LOG,Alice,10,WT,IPO,84 + BUY_SHARE_LOG,Bob,20,BA,IPO,168 + PriceIsPaidTo,168,BA + BUY_SHARE_LOG,Charlie,10,WT,IPO,84 + BUY_SHARE_LOG,Alice,10,WT,IPO,84 + FloatsWithCash,WT,420 + SharesReleased,All,HE + BUY_SHARE_LOG,Bob,10,WT,IPO,84 + PriceIsPaidTo,84,WT + START_COMPANY_LOG,Charlie,HE,84,168,2,20,BANK + BUY_SHARE_LOG,Alice,10,HE,IPO,84 + BUY_SHARE_LOG,Bob,10,HE,IPO,84 + BUY_SHARE_LOG,Charlie,10,HE,IPO,84 + FloatsWithCash,HE,420 + BUY_SHARE_LOG,Alice,10,HE,IPO,84 + PriceIsPaidTo,84,HE + PASSES,Bob + BUY_SHARE_LOG,Charlie,10,HE,IPO,84 + PriceIsPaidTo,84,HE + PASSES,Alice + PASSES,Bob + PASSES,Charlie + + END_SR,6 + PRICE_STAYS_LOG,BY,166,G1 + SoldOutNoRaise,BY,166,G1 + PRICE_MOVES_LOG,SX,100,D3,108,D2 + SoldOut,SX,100,D3,108,D2 + PRICE_MOVES_LOG,BA,84,B4,86,B3 + SoldOut,BA,84,B4,86,B3 + Has,M1,70 + Has,M2,90 + Has,M3,110 + Has,M4,135 + Has,M5,90 + Has,M6,160 + Has,BY,20 + Has,SX,115 + Has,BA,840 + Has,WT,504 + Has,HE,588 + Has,Alice,76 + Has,Bob,78 + Has,Charlie,8 + START_OR,6.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,9,I5,SE + CompanyRevenue,M1,70 + CompanySplits,M1,70 + M1 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,M2,Alice + CompanyRevenue,M2,180 + CompanySplits,M2,180 + M2 receives 90 + Payout,Alice,90,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,206,F10,SE + CompanyRevenue,M3,50 + CompanySplits,M3,50 + M3 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,15,D8,NE + CompanyRevenue,M4,110 + CompanySplits,M4,110 + M4 receives 55 + Payout,Charlie,55,1,100 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,180 + CompanySplits,M5,180 + M5 receives 90 + Payout,Charlie,90,1,100 + + CompanyOperates,M6,Bob + CompanyRevenue,M6,70 + CompanySplits,M6,70 + M6 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,8,K5,NE + CompanyRevenue,BY,330 + CompanyPaysOutFull,BY,330 + Payout,Alice,198,6,10 + Payout,Bob,99,3,10 + Payout,Charlie,33,1,10 + PRICE_MOVES_LOG,BY,166,G1,186,H1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,370 + CompanyPaysOutFull,SX,370 + Payout,Alice,74,2,10 + Payout,Bob,111,3,10 + Payout,Charlie,185,5,10 + PRICE_MOVES_LOG,SX,108,D2,120,E2 + + CompanyOperates,BA,Bob + LaysTileAt,BA,210,L6,E + CompanyDoesNotPayDividend,BA + PRICE_MOVES_LOG,BA,86,B3,82,A3 + BuysTrain,BA,3+3,IPO,270 + FirstTrainBought,3+3 + BuysTrain,BA,3+3,IPO,270 + BuysTrain,BA,3+3,IPO,270 + All 3+3-trains are sold out, 4-trains now available + + CompanyOperates,WT,Alice + LaysTileAt,WT,57,M9,W + CompanyDoesNotPayDividend,WT + PRICE_MOVES_LOG,WT,84,B4,78,A4 + BuysTrain,WT,4,IPO,360 + FirstTrainBought,4 + StartOfPhase,4 + TrainsRusted,2 + CompanyDiscardsTrain,SX,2+2 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRound,PR,OperatingRound 6.1 + + CompanyOperates,HE,Charlie + LaysTileAtFor,HE,9,K7,SW,50 + CompanyDoesNotPayDividend,HE + PRICE_MOVES_LOG,HE,84,B4,78,A4 + BuysTrain,HE,4,IPO,360 + + EndOfOperatingRound,6.1 + ORWorthIncrease,Alice,6.1,476 + ORWorthIncrease,Bob,6.1,405 + ORWorthIncrease,Charlie,6.1,431 + Has,M1,105 + Has,M2,180 + Has,M3,135 + Has,M4,190 + Has,M5,180 + Has,M6,195 + Has,BY,20 + Has,SX,115 + Has,BA,30 + Has,WT,144 + Has,HE,178 + Has,Alice,448 + Has,Bob,423 + Has,Charlie,401 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRoundNoInterrupt,PR + START_OR,6.2 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,8,D10,W + CompanyDoesNotPayDividend,M1 + BuysTrain,M1,3+3,BA,105 + + CompanyOperates,M2,Alice + LaysTileAt,M2,203,B12,W + CompanyRevenue,M2,100 + CompanySplits,M2,100 + M2 receives 50 + Payout,Alice,50,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,9,F16,W + CompanyDoesNotPayDividend,M3 + + CompanyOperates,M4,Charlie + CompanyDoesNotPayDividend,M4 + BuysTrain,M4,3,SX,190 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,100 + CompanySplits,M5,100 + M5 receives 50 + Payout,Charlie,50,1,100 + + CompanyOperates,M6,Bob + CompanyDoesNotPayDividend,M6 + BuysTrain,M6,3+3,BA,195 + + CompanyOperates,BY,Alice + LaysTileAt,BY,23,F20,NW + CompanyRevenue,BY,180 + CompanyPaysOutFull,BY,180 + Payout,Alice,108,6,10 + Payout,Bob,54,3,10 + Payout,Charlie,18,1,10 + PRICE_MOVES_LOG,BY,186,H1,208,I1 + BuysTrain,BY,2+2,M2,1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,220 + CompanyPaysOutFull,SX,220 + Payout,Alice,44,2,10 + Payout,Bob,66,3,10 + Payout,Charlie,110,5,10 + PRICE_MOVES_LOG,SX,120,E2,134,F2 + BuysTrain,SX,2+2,M5,1 + + CompanyOperates,BA,Bob + CompanyRevenue,BA,120 + CompanyPaysOutFull,BA,120 + Payout,Alice,12,1,10 + Payout,Bob,72,6,10 + Payout,Charlie,36,3,10 + PRICE_MOVES_LOG,BA,82,A3,86,B3 + BuysTrain,BA,3+3,M1,1 + + CompanyOperates,WT,Alice + LaysTileAt,WT,9,M11,W + CompanyRevenue,WT,0 + CompanyDoesNotPayDividend,WT + PRICE_MOVES_LOG,WT,78,A4,72,A5 + + CompanyOperates,HE,Charlie + CompanyRevenue,HE,130 + CompanyPaysOutFull,HE,130 + Payout,Alice,26,2,10 + Payout,Bob,13,1,10 + Payout,Charlie,52,4,10 + PRICE_MOVES_LOG,HE,78,A4,84,B4 + BuysTrain,HE,3+3,M6,1 + + EndOfOperatingRound,6.2 + ORWorthIncrease,Alice,6.2,402 + ORWorthIncrease,Bob,6.2,377 + ORWorthIncrease,Charlie,6.2,418 + Has,M1,1 + Has,M2,231 + Has,M3,135 + Has,M4,0 + Has,M5,231 + Has,M6,1 + Has,BY,19 + Has,SX,304 + Has,BA,329 + Has,WT,144 + Has,HE,177 + Has,Alice,698 + Has,Bob,668 + Has,Charlie,697 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRoundNoInterrupt,PR + StartStockRound,7 + HasPriority,Alice + BUY_SHARE_LOG,Alice,10,PR,IPO,154 + BUY_SHARE_LOG,Bob,10,PR,IPO,154 + BUY_SHARE_LOG,Charlie,10,PR,IPO,154 + BUY_SHARE_LOG,Alice,10,PR,IPO,154 + SELL_SHARE_LOG,Bob,10,BY,208 + PRICE_MOVES_LOG,BY,208,I1,188,I2 + BUY_SHARE_LOG,Charlie,10,HE,IPO,84 + PriceIsPaidTo,84,HE + BUY_SHARE_LOG,Alice,10,BY,Pool,188 + BUY_SHARE_LOG,Bob,20,HE,IPO,168 + PriceIsPaidTo,168,HE + BUY_SHARE_LOG,Charlie,10,WT,IPO,84 + PriceIsPaidTo,84,WT + BUY_SHARE_LOG,Alice,10,WT,IPO,84 + PriceIsPaidTo,84,WT + PASSES,Bob + PASSES,Charlie + PASSES,Alice + + END_SR,7 + PRICE_MOVES_LOG,BY,188,I2,208,I1 + SoldOut,BY,188,I2,208,I1 + PRICE_MOVES_LOG,SX,134,F2,148,F1 + SoldOut,SX,134,F2,148,F1 + SoldOutNoRaise,BA,86,B3 + PRICE_MOVES_LOG,HE,84,B4,86,B3 + SoldOut,HE,84,B4,86,B3 + Has,M1,1 + Has,M2,231 + Has,M3,135 + Has,M4,0 + Has,M5,231 + Has,M6,1 + Has,BY,19 + Has,SX,304 + Has,BA,329 + Has,WT,312 + Has,HE,429 + Has,Alice,118 + Has,Bob,554 + Has,Charlie,375 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRoundNoInterrupt,PR + START_OR,7.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + CompanyDoesNotPayDividend,M1 + + CompanyOperates,M2,Alice + CompanyDoesNotPayDividend,M2 + BuysTrain,M2,2+2,BY,231 + + CompanyOperates,M3,Bob + CompanyDoesNotPayDividend,M3 + BuysTrain,M3,3+3,BA,135 + + CompanyOperates,M4,Charlie + CompanyRevenue,M4,90 + CompanySplits,M4,90 + M4 receives 45 + Payout,Charlie,45,1,100 + + CompanyOperates,M5,Charlie + CompanyDoesNotPayDividend,M5 + BuysTrain,M5,2+2,SX,231 + + CompanyOperates,M6,Bob + CompanyDoesNotPayDividend,M6 + + CompanyOperates,BY,Alice + CompanyRevenue,BY,190 + CompanyPaysOutFull,BY,190 + Payout,Alice,133,7,10 + Payout,Bob,38,2,10 + Payout,Charlie,19,1,10 + PRICE_MOVES_LOG,BY,208,I1,232,J1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,220 + CompanyPaysOutFull,SX,220 + Payout,Alice,44,2,10 + Payout,Bob,66,3,10 + Payout,Charlie,110,5,10 + PRICE_MOVES_LOG,SX,148,F1,166,G1 + BuysTrain,SX,4,IPO,360 + All 4-trains are sold out, 4+4-trains now available + + CompanyOperates,BA,Bob + CompanyRevenue,BA,120 + CompanyPaysOutFull,BA,120 + Payout,Alice,12,1,10 + Payout,Bob,72,6,10 + Payout,Charlie,36,3,10 + PRICE_MOVES_LOG,BA,86,B3,92,C3 + BuysTrain,BA,4+4,IPO,440 + All 4+4-trains are sold out, 5-trains now available + FirstTrainBought,4+4 + StartOfPhase,4+4 + TrainsRusted,2+2 + StartFormationRound,PR + START_MERGED_COMPANY,PR,154,154 + FloatsWithCash,PR,616 + MERGE_MINOR_LOG,Alice,M2,PR,0,0 + GetShareForMinor,Alice,10,PR,IPO,M2 + ExchangesBaseToken,PR,M2,E19/1 + + EndOfFormationRound,PR,OperatingRound 7.1 + + CompanyOperates,HE,Charlie + LaysTileAt,HE,8,L4,NW + LAYS_TOKEN_ON,HE,G5,60 + CompanyRevenue,HE,260 + CompanyPaysOutFull,HE,260 + Payout,Alice,52,2,10 + Payout,Bob,78,3,10 + Payout,Charlie,130,5,10 + PRICE_MOVES_LOG,HE,86,B3,92,C3 + + CompanyOperates,WT,Alice + LaysTileAt,WT,69,M7,SE + CompanyRevenue,WT,280 + CompanyWithholds,WT,280 + PRICE_MOVES_LOG,WT,72,A5,64,A6 + + EndOfOperatingRound,7.1 + ORWorthIncrease,Alice,7.1,587 + ORWorthIncrease,Bob,7.1,442 + ORWorthIncrease,Charlie,7.1,516 + Has,M1,1 + Has,M3,0 + Has,M4,45 + Has,M5,0 + Has,M6,1 + Has,BY,250 + Has,SX,175 + Has,BA,24 + Has,WT,592 + Has,HE,369 + Has,PR,616 + Has,Alice,369 + Has,Bob,848 + Has,Charlie,745 + StartFormationRound,PR + + EndOfFormationRoundNoInterrupt,PR + START_OR,7.2 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + CompanyDoesNotPayDividend,M1 + BuysTrain,M1,3+3,BA,1 + + CompanyOperates,M3,Bob + CompanyRevenue,M3,90 + CompanySplits,M3,90 + M3 receives 45 + Payout,Bob,45,1,100 + + CompanyOperates,M4,Charlie + CompanyRevenue,M4,90 + CompanySplits,M4,90 + M4 receives 45 + Payout,Charlie,45,1,100 + + CompanyOperates,M5,Charlie + CompanyDoesNotPayDividend,M5 + + CompanyOperates,M6,Bob + CompanyDoesNotPayDividend,M6 + BuysTrain,M6,3,SX,1 + + CompanyOperates,BY,Alice + CompanyRevenue,BY,110 + CompanyPaysOutFull,BY,110 + Payout,Alice,77,7,10 + Payout,Bob,22,2,10 + Payout,Charlie,11,1,10 + PRICE_MOVES_LOG,BY,232,J1,258,K1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,240 + CompanyPaysOutFull,SX,240 + Payout,Alice,48,2,10 + Payout,Bob,72,3,10 + Payout,Charlie,120,5,10 + PRICE_MOVES_LOG,SX,166,G1,186,H1 + + CompanyOperates,PR,Alice + CompanyDoesNotPayDividend,PR + PRICE_MOVES_LOG,PR,154,I4,138,H4 + BuysTrain,PR,5,IPO,500 + FirstTrainBought,5 + StartOfPhase,5 + PhaseClosesAllPrivates, + PrivateCloses,OBB + PrivateCloses,PfB + StartFormationRound,PR + MERGE_MINOR_LOG,Bob,BB,PR,no,no + GetShareForMinor,Bob,10,PR,IPO,BB + PrivateCloses,BB + MERGE_MINOR_LOG,Charlie,HB,PR,no,no + GetShareForMinor,Charlie,10,PR,IPO,HB + PrivateCloses,HB + MERGE_MINOR_LOG,Bob,M1,PR,0,1 + GetShareForMinor,Bob,5,PR,IPO,M1 + ExchangesBaseToken,PR,M1,H2/1 + MERGE_MINOR_LOG,Bob,M3,PR,45,1 + GetShareForMinor,Bob,5,PR,IPO,M3 + ExchangesBaseToken,PR,M3,F14/1 + MERGE_MINOR_LOG,Charlie,M4,PR,90,1 + GetShareForMinor,Charlie,10,PR,IPO,M4 + ExchangesBaseToken,PR,M4,G5/1 + MERGE_MINOR_LOG,Charlie,M5,PR,0,0 + GetShareForMinor,Charlie,5,PR,IPO,M5 + MERGE_MINOR_LOG,Bob,M6,PR,0,1 + GetShareForMinor,Bob,5,PR,IPO,M6 + ExchangesBaseToken,PR,M6,C11/1 + CompanyDiscardsTrain,PR,3 + CompanyDiscardsTrain,PR,3 + + EndOfFormationRound,PR,OperatingRound 7.2 + IS_NOW_PRES_OF,Bob,PR - CompanyOperates,BA,Bob diff --cc version.number index 68ef9e4,60520e3..93cb0fa --- a/version.number +++ b/version.number @@@ -1,5 -1,5 +1,5 @@@ #Property file that contains version number and the develop indicator - version=1.7.2 + version=1.7.7 # the following string "@DEVELOP@ is replaced by an empty string in the release version # this is done automatically by ant -develop=@DEVELOP@ +develop=@DEVELOP@ commit 90ba59260b14c2a7d5f14a37c730d7d0cc5e0baf Author: Stefan Frey <ste...@we...> Date: Fri Jun 15 17:35:37 2012 +0200 prepared for release 1.7.7 diff --git a/readme.txt b/readme.txt index a1180ee..33de310 100644 --- a/readme.txt +++ b/readme.txt @@ -1,12 +1,18 @@ -Rails release 1.7.6: +Rails release 1.7.7: A new maintenance release for Rails 1.x series -This release fixes one sole bug. +This release fixes several bugs. -Contributors: Erik Vos +Contributors: Erik Vos, Stefan Frey -Bug reported by Antonio Baracca +Bug reported by Are-Harald Brenne, John David Galt -1856: Allowing selling a share just bought by the president. -(According to Steve Thomas rule clarification). \ No newline at end of file +New: +- Added little fun variant 18Lummer + +Lists of bugs fixed: +- Errors in UI after adding a comment at game start +- Fixed failure on reloading a just started game +- 1835: Manual close of Pfalzbahn is possible (to enable closing after token lay only) +- 1835 (and others): Fixed UI issues with token relays on OO-tiles diff --git a/version.number b/version.number index cde0424..60520e3 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.6 +version=1.7.7 # the following string "@DEVELOP@ is replaced by an empty string in the release version # this is done automatically by ant develop=@DEVELOP@ \ No newline at end of file commit bf16424ac310389b5b48fabfc11a86a6f2a93a29 Author: Erik Vos <eri...@xs...> Date: Fri Jun 15 13:48:48 2012 +0200 Fixed failure on reloading a null action list. GameFileIO.replayGame() was not protected against that condition. [IMO the list should have been created empty, not null; EV](cherry picked from commit ee3e580ae2efdb10c28bdfe0565566e39f17491a) diff --git a/rails/util/GameFileIO.java b/rails/util/GameFileIO.java index 16f1991..5ae75a4 100644 --- a/rails/util/GameFileIO.java +++ b/rails/util/GameFileIO.java @@ -224,13 +224,15 @@ public class GameFileIO { gameManager.setReloading(true); int count = -1; - for (PossibleAction action : gameData.actions) { - count++; - if (!gameManager.processOnReload(action)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted", count)); - ReportBuffer.add(LocalText.getText("LoadInterrupted", count)); - break; + if (gameData != null && gameData.actions != null) { + for (PossibleAction action : gameData.actions) { + count++; + if (!gameManager.processOnReload(action)) { + log.error ("Load interrupted"); + DisplayBuffer.add(LocalText.getText("LoadInterrupted", count)); + ReportBuffer.add(LocalText.getText("LoadInterrupted", count)); + break; + } } } commit 3892c7f2d7d9685cc3a1e5b69e4be900fe7bc4e7 Author: Erik Vos <eri...@xs...> Date: Thu Jun 14 15:44:15 2012 +0200 Fix to 1835 (etc.) token relay fix (previous commit). It failed in a typical 1830 Erie case.(cherry picked from commit ce10cb981aa82985380177433571aed4789f75ae) diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index 2252757..f3b6049 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -963,12 +963,14 @@ public class ORUIManager implements DialogOwner { if (stopsToQuery.size() == 2) { Collections.sort(stopsToQuery, new Comparator<Stop>() { public int compare (Stop s1, Stop s2) { - // Home stops on this hex go first. - boolean home1 = ((BaseToken)s1.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); - boolean home2 = ((BaseToken)s2.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); - if (home1 && !home2) { + List<TokenI> tokens; + boolean stop1IsHome = !((tokens = s1.getTokens()).isEmpty()) + && ((BaseToken)tokens.get(0)).getCompany().getHomeHexes().contains(hex); + boolean stop2IsHome = !((tokens = s2.getTokens()).isEmpty()) + && ((BaseToken)tokens.get(0)).getCompany().getHomeHexes().contains(hex); + if (stop1IsHome && !stop2IsHome) { return -1; - } else if (home2 && !home1) { + } else if (stop2IsHome && !stop1IsHome) { return 1; } else { return 0; // Doesn't matter commit 18b22dec3aeaa01d27250baf5b7dc0256c777d64 Author: Erik Vos <eri...@xs...> Date: Wed Jun 13 17:36:00 2012 +0200 Fixes for 1835 Pfalzbahnen. Manual closure made possible for PfB. If two tokens are laid on L6 (BA home) before the first tile, only the BA president will get asked where to put the BA home token. (cherry picked from commit f34c80df8dacc9f6381c2a0c615cec89aade704c) Conflicts: data/1835/CompanyManager.xml diff --git a/data/1835/CompanyManager.xml b/data/1835/CompanyManager.xml index 9f28099..bfdbb7f 100644 --- a/data/1835/CompanyManager.xml +++ b/data/1835/CompanyManager.xml @@ -55,7 +55,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> - <CloseManually/> <!-- If second tile is laid not via special property --> + <CloseManually/> <!-- Workaround, may be needed if one of the tiles is not laid via this special property --> </ClosingConditions> </Company> <Company name="PfB" longname="Pfalzbahnen" type="Private" basePrice="150" revenue="15"> @@ -70,7 +70,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> - <CloseManually/> <!-- If tile is laid not via special property--> + <CloseManually/> <!-- Workaround, may be needed if a tile or token is not laid via this special property --> </ClosingConditions> </Company> <Company name="LD" longname="Leipzig-Dresdner Bahn" type="Private" basePrice="190"> di... [truncated message content] |
LocalisedText.properties | 3 data/1835/CompanyManager.xml | 5 data/1837/CompanyManager.xml | 393 data/1837/Game.xml | 220 data/1837/Map.xml | 181 data/1837/StockMarket.xml | 114 data/1837/TileSet.xml | 243 data/1837/Tiles.xml | 617 data/18TN/Game.xml | 3 data/GamesList.xml | 10 rails/game/MapManager.java | 38 rails/game/Phase.java | 8 rails/game/PublicCompany.java | 54 rails/game/PublicCompanyI.java | 8 rails/game/StockRound.java | 14 rails/ui/swing/MapPanel.java | 79 rails/ui/swing/ORUIManager.java | 53 rails/ui/swing/elements/NonModalDialog.java | 1 rails/ui/swing/hexmap/GUIHex.java | 155 rails/util/GameFileIO.java | 16 test/data/real/18TN_A.report | 1225 test/data/test/1835_PRHasTwoExcessTrains.report | 2282 - test/data/test/1835_PR_3rdTrain.report | 2207 - test/data/test/1835_SellDoubleShare.rails |binary test/data/test/1835_SellDoubleShare.report | 1639 tiles/TileDictionary.18t | 361 tiles/TileDictionary.xml |48517 ++++++++++++------------ tiles/Tiles.xml | 8519 ++-- tiles/svg/tile-37001.svg | 2 tiles/svg/tile-37002.svg | 2 tiles/svg/tile-37003.svg | 2 tiles/svg/tile-37007.svg | 2 tiles/svg/tile-37008.svg | 2 tiles/svg/tile-37009.svg | 2 tiles/svg/tile-37010.svg | 2 tiles/svg/tile-37011.svg | 2 tiles/svg/tile-37012.svg | 2 tiles/svg/tile-37103.svg | 2 tiles/svg/tile-37109.svg | 2 tiles/svg/tile-37123.svg | 2 tiles/svg/tile-37156.svg | 2 tiles/svg/tile-37158.svg | 2 tiles/svg/tile-37206.svg | 2 tiles/svg/tile-37402.svg | 2 tiles/svg/tile-42.svg | 2 tiles/svg/tile-6000.svg | 8 tiles/svg/tile-6001.svg | 2 tiles/svg/tile-6007.svg | 2 48 files changed, 35801 insertions(+), 31210 deletions(-) New commits: commit c1827cf5bec7f70188958fca1e8f65715b075b13 Merge: 0ba698c ee3e580 Author: Martin Brumm <Dr....@t-...> Date: Wed Jun 20 21:02:48 2012 +0200 Merge remote-tracking branch '1880/master' into specific_1880 Conflicts: test/data/test/1835_PRHasTwoExcessTrains.report test/data/test/1835_PR_3rdTrain.report diff --cc data/18TN/Game.xml index a5957bf,334fdfb..e6fea04 --- a/data/18TN/Game.xml +++ b/data/18TN/Game.xml @@@ -129,4 -129,4 +130,4 @@@ <Component name="RevenueManager" class="rails.algorithms.RevenueManager"> <!-- Required for TN civil war '--> </Component> --</ComponentManager> ++</ComponentManager> diff --cc test/data/test/1835_PRHasTwoExcessTrains.report index b7e738e,3731c5c..c197783 --- a/test/data/test/1835_PRHasTwoExcessTrains.report +++ b/test/data/test/1835_PRHasTwoExcessTrains.report @@@ -1,1142 -1,1142 +1,1142 @@@ - GameIs,1835 - PlayerIs,1,Alice - PlayerIs,2,Bob - PlayerIs,3,Charlie - PlayerCash,600 - BankHas,10200 - StartOfPhase,2 - BankSizeIs,10200 - StartOfInitialRound - HasPriority,Alice - BuysItemFor,Alice,NF,100 - ALSO_GETS,Alice,CERT_NAME,BY,10 - BuysItemFor,Bob,M1,80 - FloatsWithCash,M1,80 - BuysItemFor,Charlie,LD,190 - ALSO_GETS,Charlie,PRES_CERT_NAME,SX,20 - BuysItemFor,Alice,M2,170 - FloatsWithCash,M2,170 - BuysItemFor,Bob,M3,80 - FloatsWithCash,M3,80 - BuysItemFor,Charlie,M4,160 - FloatsWithCash,M4,160 - BuysItemFor,Alice,PRES_CERT_NAME,BY,20,184 - BuysItemFor,Bob,BB,130 - BuysItemFor,Charlie,HB,160 - BuysItemFor,Alice,OBB,120 - ALSO_GETS,Alice,CERT_NAME,BY,10 - BuysItemFor,Bob,PfB,150 - ALSO_GETS,Bob,CERT_NAME,BY,10 - FloatsWithCash,BY,460 - BuysItemFor,Charlie,M5,80 - FloatsWithCash,M5,80 - CannotBuyAnything,Alice - BuysItemFor,Bob,M6,80 - FloatsWithCash,M6,80 - Has,M1,80 - Has,M2,170 - Has,M3,80 - Has,M4,160 - Has,M5,80 - Has,M6,80 - Has,BY,460 - Has,Alice,26 - Has,Bob,80 - Has,Charlie,10 - StartStockRound,1 - HasPriority,Charlie - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,1 - Has,M1,80 - Has,M2,170 - Has,M3,80 - Has,M4,160 - Has,M5,80 - Has,M6,80 - Has,BY,460 - Has,Alice,26 - Has,Bob,80 - Has,Charlie,10 - START_OR,1.1 - ReceivesFor,Alice,5,NF - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,202,H2,W - CompanyDoesNotPayDividend,M1 - BuysTrain,M1,2,IPO,80 - FirstTrainBought,2 - - CompanyOperates,M2,Alice - LaysTileAt,M2,8,E17,NW - CompanyDoesNotPayDividend,M2 - BuysTrain,M2,2,IPO,80 - - CompanyOperates,M3,Bob - LaysTileAt,M3,6,F14,NW - CompanyDoesNotPayDividend,M3 - BuysTrain,M3,2,IPO,80 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,57,G5,SW - CompanyDoesNotPayDividend,M4 - BuysTrain,M4,2,IPO,80 - BuysTrain,M4,2,IPO,80 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,D18,NE - CompanyDoesNotPayDividend,M5 - BuysTrain,M5,2,IPO,80 - - CompanyOperates,M6,Bob - LaysTileAt,M6,9,B10,NW - CompanyDoesNotPayDividend,M6 - BuysTrain,M6,2,IPO,80 - - CompanyOperates,BY,Alice - LAYS_FREE_TOKEN_ON,BY,L14 - PrivateCloses,NF - LaysTileAtFor,BY,9,K15,SW,70 - LaysTileAt,BY,1,I17,SW - LaysTileAt,BY,58,M15,SW - CompanyDoesNotPayDividend,BY - PRICE_MOVES_LOG,BY,92,C3,86,B3 - BuysTrain,BY,2,IPO,80 - BuysTrain,BY,2,IPO,80 - All 2-trains are sold out, 2+2-trains now available - BuysTrain,BY,2+2,IPO,120 - FirstTrainBought,2+2 - - EndOfOperatingRound,1.1 - ORWorthIncrease,Alice,1.1,-109 - ORWorthIncrease,Bob,1.1,34 - ORWorthIncrease,Charlie,1.1,50 - Has,M1,0 - Has,M2,90 - Has,M3,0 - Has,M4,0 - Has,M5,0 - Has,M6,0 - Has,BY,110 - Has,Alice,41 - Has,Bob,120 - Has,Charlie,60 - StartStockRound,2 - HasPriority,Charlie - PASSES,Charlie - PASSES,Alice - BUY_SHARE_LOG,Bob,10,BY,IPO,92 - PriceIsPaidTo,92,BY - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,2 - Has,M1,0 - Has,M2,90 - Has,M3,0 - Has,M4,0 - Has,M5,0 - Has,M6,0 - Has,BY,202 - Has,Alice,41 - Has,Bob,28 - Has,Charlie,60 - START_OR,2.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,69,H4,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - LaysTileAt,M2,8,D16,SE - CompanyRevenue,M2,0 - CompanyDoesNotPayDividend,M2 - - CompanyOperates,M3,Bob - LaysTileAt,M3,4,G15,NW - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,4,F6,SW - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,C19,E - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,6,A11,NW - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,202,H20,W - LaysTileAt,BY,9,F20,NW - LAYS_TOKEN_ON,BY,H20,160 - CompanyRevenue,BY,160 - CompanyPaysOutFull,BY,160 - Payout,Bob,32,2,10 - Payout,Alice,64,4,10 - PRICE_MOVES_LOG,BY,86,B3,92,C3 - - EndOfOperatingRound,2.1 - ORWorthIncrease,Alice,2.1,98 - ORWorthIncrease,Bob,2.1,154 - ORWorthIncrease,Charlie,2.1,105 - Has,M1,20 - Has,M2,90 - Has,M3,20 - Has,M4,30 - Has,M5,25 - Has,M6,30 - Has,BY,42 - Has,Alice,115 - Has,Bob,170 - Has,Charlie,165 - StartStockRound,3 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Alice,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Bob,10,BY,IPO,92 - PriceIsPaidTo,92,BY - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,3 - Has,M1,20 - Has,M2,90 - Has,M3,20 - Has,M4,30 - Has,M5,25 - Has,M6,30 - Has,BY,318 - Has,Alice,23 - Has,Bob,78 - Has,Charlie,73 - START_OR,3.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,9,J2,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - LaysTileAtFor,M2,8,D14,NW,50 - CompanyRevenue,M2,70 - CompanySplits,M2,70 - M2 receives 35 - Payout,Alice,35,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,6,H16,SE - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,9,E7,SW - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,58,B12,NW - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,8,N14,NE - LaysTileAt,BY,201,O15,NW - CompanyRevenue,BY,190 - CompanyPaysOutFull,BY,190 - Payout,Charlie,19,1,10 - Payout,Bob,57,3,10 - Payout,Alice,95,5,10 - PRICE_MOVES_LOG,BY,92,C3,100,D3 - BuysTrain,BY,2+2,IPO,120 - - EndOfOperatingRound,3.1 - ORWorthIncrease,Alice,3.1,180 - ORWorthIncrease,Bob,3.1,191 - ORWorthIncrease,Charlie,3.1,132 - Has,M1,40 - Has,M2,75 - Has,M3,40 - Has,M4,60 - Has,M5,50 - Has,M6,60 - Has,BY,198 - Has,Alice,163 - Has,Bob,245 - Has,Charlie,197 - StartStockRound,4 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,SX,IPO,88 - BUY_SHARE_LOG,Alice,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Bob,10,SX,IPO,88 - BUY_SHARE_LOG,Charlie,10,SX,IPO,88 - FloatsWithCash,SX,440 - PASSES,Alice - BUY_SHARE_LOG,Bob,10,SX,IPO,88 - PriceIsPaidTo,88,SX - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,4 - PRICE_MOVES_LOG,BY,100,D3,108,D2 - SoldOut,BY,100,D3,108,D2 - Has,M1,40 - Has,M2,75 - Has,M3,40 - Has,M4,60 - Has,M5,50 - Has,M6,60 - Has,BY,290 - Has,SX,528 - Has,Alice,71 - Has,Bob,69 - Has,Charlie,21 - START_OR,4.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,4,K3,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - CompanyRevenue,M2,70 - CompanySplits,M2,70 - M2 receives 35 - Payout,Alice,35,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,57,F10,W - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAtFor,M4,5,D8,W,50 - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,58,B14,SE - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAtFor,BY,9,J14,W,70 - LaysTileAt,BY,9,J12,W - CompanyRevenue,BY,200 - CompanyPaysOutFull,BY,200 - Payout,Bob,60,3,10 - Payout,Charlie,20,1,10 - Payout,Alice,120,6,10 - PRICE_MOVES_LOG,BY,108,D2,120,E2 - - CompanyOperates,SX,Charlie - LaysTileAt,SX,8,H18,SE - CompanyDoesNotPayDividend,SX - PRICE_MOVES_LOG,SX,88,C4,84,B4 - BuysTrain,SX,2+2,IPO,120 - PrivateCloses,LD - BuysTrain,SX,2+2,IPO,120 - All 2+2-trains are sold out, 3-trains now available - BuysTrain,SX,3,IPO,180 - FirstTrainBought,3 - StartOfPhase,3 - - EndOfOperatingRound,4.1 - ORWorthIncrease,Alice,4.1,237 - ORWorthIncrease,Bob,4.1,198 - ORWorthIncrease,Charlie,4.1,-69 - Has,M1,60 - Has,M2,110 - Has,M3,60 - Has,M4,40 - Has,M5,75 - Has,M6,90 - Has,BY,220 - Has,SX,108 - Has,Alice,236 - Has,Bob,239 - Has,Charlie,146 - StartStockRound,5 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,SX,IPO,88 - PriceIsPaidTo,88,SX - BUY_SHARE_LOG,Alice,10,SX,IPO,88 - PriceIsPaidTo,88,SX - BUY_SHARE_LOG,Bob,10,SX,IPO,88 - PriceIsPaidTo,88,SX - PASSES,Charlie - BUY_SHARE_LOG,Alice,10,SX,IPO,88 - PriceIsPaidTo,88,SX - SharesReleased,All,BA - PASSES,Bob - PASSES,Charlie - PASSES,Alice - - END_SR,5 - PRICE_MOVES_LOG,BY,120,E2,132,E1 - SoldOut,BY,120,E2,132,E1 - PRICE_MOVES_LOG,SX,84,B4,86,B3 - SoldOut,SX,84,B4,86,B3 - Has,M1,60 - Has,M2,110 - Has,M3,60 - Has,M4,40 - Has,M5,75 - Has,M6,90 - Has,BY,220 - Has,SX,460 - Has,Alice,60 - Has,Bob,151 - Has,Charlie,58 - START_OR,5.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,207,H2,E - CompanyRevenue,M1,50 - CompanySplits,M1,50 - M1 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M2,Alice - LaysTileAt,M2,209,E19,SW - CompanyRevenue,M2,80 - CompanySplits,M2,80 - M2 receives 40 - Payout,Alice,40,1,100 - BuysTrain,M2,2+2,BY,150 - - CompanyOperates,M3,Bob - LaysTileAt,M3,205,F14,SE - CompanyRevenue,M3,50 - CompanySplits,M3,50 - M3 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,14,G5,SW - CompanyRevenue,M4,80 - CompanySplits,M4,80 - M4 receives 40 - Payout,Charlie,40,1,100 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,208,H20,W - CompanyRevenue,M5,80 - CompanySplits,M5,80 - M5 receives 40 - Payout,Charlie,40,1,100 - BuysTrain,M5,2+2,SX,115 - - CompanyOperates,M6,Bob - LaysTileAt,M6,12,A11,W - CompanyRevenue,M6,70 - CompanySplits,M6,70 - M6 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,9,J10,W - LAYS_TOKEN_ON,BY,J8,120 - CompanyRevenue,BY,240 - CompanyPaysOutFull,BY,240 - Payout,Bob,72,3,10 - Payout,Alice,144,6,10 - Payout,Charlie,24,1,10 - PRICE_MOVES_LOG,BY,132,E1,148,F1 - BuysTrain,BY,3,IPO,180 - - CompanyOperates,SX,Charlie - LaysTileAt,SX,13,H16,W - LAYS_TOKEN_ON,SX,E19,60 - CompanyRevenue,SX,190 - CompanyPaysOutFull,SX,190 - Payout,Alice,38,2,10 - Payout,Bob,57,3,10 - Payout,Charlie,95,5,10 - PRICE_MOVES_LOG,SX,86,B3,92,C3 - BuysTrain,SX,3,IPO,180 - BuysTrain,SX,3,IPO,180 - All 3-trains are sold out, 3+3-trains now available - - EndOfOperatingRound,5.1 - ORWorthIncrease,Alice,5.1,340 - ORWorthIncrease,Bob,5.1,320 - ORWorthIncrease,Charlie,5.1,275 - Has,M1,85 - Has,M2,0 - Has,M3,85 - Has,M4,80 - Has,M5,0 - Has,M6,125 - Has,BY,70 - Has,SX,155 - Has,Alice,292 - Has,Bob,405 - Has,Charlie,287 - START_OR,5.2 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAtFor,M1,211,G3,E,50 - CompanyRevenue,M1,70 - CompanySplits,M1,70 - M1 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,M2,Alice - LaysTileAt,M2,23,D18,NW - CompanyRevenue,M2,180 - CompanySplits,M2,180 - M2 receives 90 - Payout,Alice,90,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,8,F8,E - CompanyRevenue,M3,50 - CompanySplits,M3,50 - M3 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,8,G7,W - CompanyRevenue,M4,110 - CompanySplits,M4,110 - M4 receives 55 - Payout,Charlie,55,1,100 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,C17,SE - CompanyRevenue,M5,180 - CompanySplits,M5,180 - M5 receives 90 - Payout,Charlie,90,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,8,C15,NW - CompanyRevenue,M6,70 - CompanySplits,M6,70 - M6 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,BY,Alice - LaysTileAtFor,BY,214,J6,SE,50 - CompanyRevenue,BY,330 - CompanyPaysOutFull,BY,330 - Payout,Alice,198,6,10 - Payout,Bob,99,3,10 - Payout,Charlie,33,1,10 - PRICE_MOVES_LOG,BY,148,F1,166,G1 - - CompanyOperates,SX,Charlie - LaysTileAt,SX,23,H18,E - LAYS_TOKEN_ON,SX,H20,40 - CompanyRevenue,SX,370 - CompanyPaysOutFull,SX,370 - Payout,Alice,74,2,10 - Payout,Bob,111,3,10 - Payout,Charlie,185,5,10 - PRICE_MOVES_LOG,SX,92,C3,100,D3 - - EndOfOperatingRound,5.2 - ORWorthIncrease,Alice,5.2,496 - ORWorthIncrease,Bob,5.2,423 - ORWorthIncrease,Charlie,5.2,451 - Has,M1,70 - Has,M2,90 - Has,M3,110 - Has,M4,135 - Has,M5,90 - Has,M6,160 - Has,BY,20 - Has,SX,115 - Has,Alice,664 - Has,Bob,750 - Has,Charlie,680 - StartStockRound,6 - HasPriority,Bob - START_COMPANY_LOG,Bob,BA,84,168,2,20,BANK - SharesReleased,4 10%,PR - BUY_SHARE_LOG,Charlie,10,BA,IPO,84 - BUY_SHARE_LOG,Alice,10,BA,IPO,84 - BUY_SHARE_LOG,Bob,10,BA,IPO,84 - FloatsWithCash,BA,420 - SharesReleased,All,WT - BUY_SHARE_LOG,Charlie,10,BA,IPO,84 - PriceIsPaidTo,84,BA - START_COMPANY_LOG,Alice,WT,84,168,2,20,BANK - BUY_SHARE_LOG,Bob,10,BA,IPO,84 - PriceIsPaidTo,84,BA - BUY_SHARE_LOG,Charlie,10,BA,IPO,84 - PriceIsPaidTo,84,BA - BUY_SHARE_LOG,Alice,10,WT,IPO,84 - BUY_SHARE_LOG,Bob,20,BA,IPO,168 - PriceIsPaidTo,168,BA - BUY_SHARE_LOG,Charlie,10,WT,IPO,84 - BUY_SHARE_LOG,Alice,10,WT,IPO,84 - FloatsWithCash,WT,420 - SharesReleased,All,HE - BUY_SHARE_LOG,Bob,10,WT,IPO,84 - PriceIsPaidTo,84,WT - START_COMPANY_LOG,Charlie,HE,84,168,2,20,BANK - BUY_SHARE_LOG,Alice,10,HE,IPO,84 - BUY_SHARE_LOG,Bob,10,HE,IPO,84 - BUY_SHARE_LOG,Charlie,10,HE,IPO,84 - FloatsWithCash,HE,420 - BUY_SHARE_LOG,Alice,10,HE,IPO,84 - PriceIsPaidTo,84,HE - PASSES,Bob - BUY_SHARE_LOG,Charlie,10,HE,IPO,84 - PriceIsPaidTo,84,HE - PASSES,Alice - PASSES,Bob - PASSES,Charlie - - END_SR,6 - PRICE_STAYS_LOG,BY,166,G1 - SoldOutNoRaise,BY,166,G1 - PRICE_MOVES_LOG,SX,100,D3,108,D2 - SoldOut,SX,100,D3,108,D2 - PRICE_MOVES_LOG,BA,84,B4,86,B3 - SoldOut,BA,84,B4,86,B3 - Has,M1,70 - Has,M2,90 - Has,M3,110 - Has,M4,135 - Has,M5,90 - Has,M6,160 - Has,BY,20 - Has,SX,115 - Has,BA,840 - Has,WT,504 - Has,HE,588 - Has,Alice,76 - Has,Bob,78 - Has,Charlie,8 - START_OR,6.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,9,I5,SE - CompanyRevenue,M1,70 - CompanySplits,M1,70 - M1 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,M2,Alice - CompanyRevenue,M2,180 - CompanySplits,M2,180 - M2 receives 90 - Payout,Alice,90,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,206,F10,SE - CompanyRevenue,M3,50 - CompanySplits,M3,50 - M3 receives 25 - Payout,Bob,25,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,15,D8,NE - CompanyRevenue,M4,110 - CompanySplits,M4,110 - M4 receives 55 - Payout,Charlie,55,1,100 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,180 - CompanySplits,M5,180 - M5 receives 90 - Payout,Charlie,90,1,100 - - CompanyOperates,M6,Bob - CompanyRevenue,M6,70 - CompanySplits,M6,70 - M6 receives 35 - Payout,Bob,35,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,8,K5,NE - CompanyRevenue,BY,330 - CompanyPaysOutFull,BY,330 - Payout,Alice,198,6,10 - Payout,Bob,99,3,10 - Payout,Charlie,33,1,10 - PRICE_MOVES_LOG,BY,166,G1,186,H1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,370 - CompanyPaysOutFull,SX,370 - Payout,Alice,74,2,10 - Payout,Bob,111,3,10 - Payout,Charlie,185,5,10 - PRICE_MOVES_LOG,SX,108,D2,120,E2 - + GameIs,1835 + PlayerIs,1,Alice + PlayerIs,2,Bob + PlayerIs,3,Charlie + PlayerCash,600 + BankHas,10200 + StartOfPhase,2 + BankSizeIs,10200 + StartOfInitialRound + HasPriority,Alice + BuysItemFor,Alice,NF,100 + ALSO_GETS,Alice,CERT_NAME,BY,10 + BuysItemFor,Bob,M1,80 + FloatsWithCash,M1,80 + BuysItemFor,Charlie,LD,190 + ALSO_GETS,Charlie,PRES_CERT_NAME,SX,20 + BuysItemFor,Alice,M2,170 + FloatsWithCash,M2,170 + BuysItemFor,Bob,M3,80 + FloatsWithCash,M3,80 + BuysItemFor,Charlie,M4,160 + FloatsWithCash,M4,160 + BuysItemFor,Alice,PRES_CERT_NAME,BY,20,184 + BuysItemFor,Bob,BB,130 + BuysItemFor,Charlie,HB,160 + BuysItemFor,Alice,OBB,120 + ALSO_GETS,Alice,CERT_NAME,BY,10 + BuysItemFor,Bob,PfB,150 + ALSO_GETS,Bob,CERT_NAME,BY,10 + FloatsWithCash,BY,460 + BuysItemFor,Charlie,M5,80 + FloatsWithCash,M5,80 + CannotBuyAnything,Alice + BuysItemFor,Bob,M6,80 + FloatsWithCash,M6,80 + Has,M1,80 + Has,M2,170 + Has,M3,80 + Has,M4,160 + Has,M5,80 + Has,M6,80 + Has,BY,460 + Has,Alice,26 + Has,Bob,80 + Has,Charlie,10 + StartStockRound,1 + HasPriority,Charlie + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,1 + Has,M1,80 + Has,M2,170 + Has,M3,80 + Has,M4,160 + Has,M5,80 + Has,M6,80 + Has,BY,460 + Has,Alice,26 + Has,Bob,80 + Has,Charlie,10 + START_OR,1.1 + ReceivesFor,Alice,5,NF + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,202,H2,W + CompanyDoesNotPayDividend,M1 + BuysTrain,M1,2,IPO,80 + FirstTrainBought,2 + + CompanyOperates,M2,Alice + LaysTileAt,M2,8,E17,NW + CompanyDoesNotPayDividend,M2 + BuysTrain,M2,2,IPO,80 + + CompanyOperates,M3,Bob + LaysTileAt,M3,6,F14,NW + CompanyDoesNotPayDividend,M3 + BuysTrain,M3,2,IPO,80 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,57,G5,SW + CompanyDoesNotPayDividend,M4 + BuysTrain,M4,2,IPO,80 + BuysTrain,M4,2,IPO,80 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,8,D18,NE + CompanyDoesNotPayDividend,M5 + BuysTrain,M5,2,IPO,80 + + CompanyOperates,M6,Bob + LaysTileAt,M6,9,B10,NW + CompanyDoesNotPayDividend,M6 + BuysTrain,M6,2,IPO,80 + + CompanyOperates,BY,Alice + LAYS_FREE_TOKEN_ON,BY,L14 + PrivateCloses,NF + LaysTileAtFor,BY,9,K15,SW,70 + LaysTileAt,BY,1,I17,SW + LaysTileAt,BY,58,M15,SW + CompanyDoesNotPayDividend,BY + PRICE_MOVES_LOG,BY,92,C3,86,B3 + BuysTrain,BY,2,IPO,80 + BuysTrain,BY,2,IPO,80 + All 2-trains are sold out, 2+2-trains now available + BuysTrain,BY,2+2,IPO,120 + FirstTrainBought,2+2 + + EndOfOperatingRound,1.1 + ORWorthIncrease,Alice,1.1,-109 + ORWorthIncrease,Bob,1.1,34 + ORWorthIncrease,Charlie,1.1,50 + Has,M1,0 + Has,M2,90 + Has,M3,0 + Has,M4,0 + Has,M5,0 + Has,M6,0 + Has,BY,110 + Has,Alice,41 + Has,Bob,120 + Has,Charlie,60 + StartStockRound,2 + HasPriority,Charlie + PASSES,Charlie + PASSES,Alice + BUY_SHARE_LOG,Bob,10,BY,IPO,92 + PriceIsPaidTo,92,BY + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,2 + Has,M1,0 + Has,M2,90 + Has,M3,0 + Has,M4,0 + Has,M5,0 + Has,M6,0 + Has,BY,202 + Has,Alice,41 + Has,Bob,28 + Has,Charlie,60 + START_OR,2.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,69,H4,NW + CompanyRevenue,M1,40 + CompanySplits,M1,40 + M1 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M2,Alice + LaysTileAt,M2,8,D16,SE + CompanyRevenue,M2,0 + CompanyDoesNotPayDividend,M2 + + CompanyOperates,M3,Bob + LaysTileAt,M3,4,G15,NW + CompanyRevenue,M3,40 + CompanySplits,M3,40 + M3 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,4,F6,SW + CompanyRevenue,M4,60 + CompanySplits,M4,60 + M4 receives 30 + Payout,Charlie,30,1,100 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,8,C19,E + CompanyRevenue,M5,50 + CompanySplits,M5,50 + M5 receives 25 + Payout,Charlie,25,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,6,A11,NW + CompanyRevenue,M6,60 + CompanySplits,M6,60 + M6 receives 30 + Payout,Bob,30,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,202,H20,W + LaysTileAt,BY,9,F20,NW + LAYS_TOKEN_ON,BY,H20,160 + CompanyRevenue,BY,160 + CompanyPaysOutFull,BY,160 + Payout,Bob,32,2,10 + Payout,Alice,64,4,10 + PRICE_MOVES_LOG,BY,86,B3,92,C3 + + EndOfOperatingRound,2.1 + ORWorthIncrease,Alice,2.1,98 + ORWorthIncrease,Bob,2.1,154 + ORWorthIncrease,Charlie,2.1,105 + Has,M1,20 + Has,M2,90 + Has,M3,20 + Has,M4,30 + Has,M5,25 + Has,M6,30 + Has,BY,42 + Has,Alice,115 + Has,Bob,170 + Has,Charlie,165 + StartStockRound,3 + HasPriority,Charlie + BUY_SHARE_LOG,Charlie,10,BY,IPO,92 + PriceIsPaidTo,92,BY + BUY_SHARE_LOG,Alice,10,BY,IPO,92 + PriceIsPaidTo,92,BY + BUY_SHARE_LOG,Bob,10,BY,IPO,92 + PriceIsPaidTo,92,BY + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,3 + Has,M1,20 + Has,M2,90 + Has,M3,20 + Has,M4,30 + Has,M5,25 + Has,M6,30 + Has,BY,318 + Has,Alice,23 + Has,Bob,78 + Has,Charlie,73 + START_OR,3.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,9,J2,NW + CompanyRevenue,M1,40 + CompanySplits,M1,40 + M1 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M2,Alice + LaysTileAtFor,M2,8,D14,NW,50 + CompanyRevenue,M2,70 + CompanySplits,M2,70 + M2 receives 35 + Payout,Alice,35,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,6,H16,SE + CompanyRevenue,M3,40 + CompanySplits,M3,40 + M3 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,9,E7,SW + CompanyRevenue,M4,60 + CompanySplits,M4,60 + M4 receives 30 + Payout,Charlie,30,1,100 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,50 + CompanySplits,M5,50 + M5 receives 25 + Payout,Charlie,25,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,58,B12,NW + CompanyRevenue,M6,60 + CompanySplits,M6,60 + M6 receives 30 + Payout,Bob,30,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,8,N14,NE + LaysTileAt,BY,201,O15,NW + CompanyRevenue,BY,190 + CompanyPaysOutFull,BY,190 + Payout,Charlie,19,1,10 + Payout,Bob,57,3,10 + Payout,Alice,95,5,10 + PRICE_MOVES_LOG,BY,92,C3,100,D3 + BuysTrain,BY,2+2,IPO,120 + + EndOfOperatingRound,3.1 + ORWorthIncrease,Alice,3.1,180 + ORWorthIncrease,Bob,3.1,191 + ORWorthIncrease,Charlie,3.1,132 + Has,M1,40 + Has,M2,75 + Has,M3,40 + Has,M4,60 + Has,M5,50 + Has,M6,60 + Has,BY,198 + Has,Alice,163 + Has,Bob,245 + Has,Charlie,197 + StartStockRound,4 + HasPriority,Charlie + BUY_SHARE_LOG,Charlie,10,SX,IPO,88 + BUY_SHARE_LOG,Alice,10,BY,IPO,92 + PriceIsPaidTo,92,BY + BUY_SHARE_LOG,Bob,10,SX,IPO,88 + BUY_SHARE_LOG,Charlie,10,SX,IPO,88 + FloatsWithCash,SX,440 + PASSES,Alice + BUY_SHARE_LOG,Bob,10,SX,IPO,88 + PriceIsPaidTo,88,SX + PASSES,Charlie + PASSES,Alice + PASSES,Bob + + END_SR,4 + PRICE_MOVES_LOG,BY,100,D3,108,D2 + SoldOut,BY,100,D3,108,D2 + Has,M1,40 + Has,M2,75 + Has,M3,40 + Has,M4,60 + Has,M5,50 + Has,M6,60 + Has,BY,290 + Has,SX,528 + Has,Alice,71 + Has,Bob,69 + Has,Charlie,21 + START_OR,4.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Charlie,20,LD + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,4,K3,NW + CompanyRevenue,M1,40 + CompanySplits,M1,40 + M1 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M2,Alice + CompanyRevenue,M2,70 + CompanySplits,M2,70 + M2 receives 35 + Payout,Alice,35,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,57,F10,W + CompanyRevenue,M3,40 + CompanySplits,M3,40 + M3 receives 20 + Payout,Bob,20,1,100 + + CompanyOperates,M4,Charlie + LaysTileAtFor,M4,5,D8,W,50 + CompanyRevenue,M4,60 + CompanySplits,M4,60 + M4 receives 30 + Payout,Charlie,30,1,100 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,50 + CompanySplits,M5,50 + M5 receives 25 + Payout,Charlie,25,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,58,B14,SE + CompanyRevenue,M6,60 + CompanySplits,M6,60 + M6 receives 30 + Payout,Bob,30,1,100 + + CompanyOperates,BY,Alice + LaysTileAtFor,BY,9,J14,W,70 + LaysTileAt,BY,9,J12,W + CompanyRevenue,BY,200 + CompanyPaysOutFull,BY,200 + Payout,Bob,60,3,10 + Payout,Charlie,20,1,10 + Payout,Alice,120,6,10 + PRICE_MOVES_LOG,BY,108,D2,120,E2 + + CompanyOperates,SX,Charlie + LaysTileAt,SX,8,H18,SE + CompanyDoesNotPayDividend,SX + PRICE_MOVES_LOG,SX,88,C4,84,B4 + BuysTrain,SX,2+2,IPO,120 + PrivateCloses,LD + BuysTrain,SX,2+2,IPO,120 + All 2+2-trains are sold out, 3-trains now available + BuysTrain,SX,3,IPO,180 + FirstTrainBought,3 + StartOfPhase,3 + + EndOfOperatingRound,4.1 + ORWorthIncrease,Alice,4.1,237 + ORWorthIncrease,Bob,4.1,198 + ORWorthIncrease,Charlie,4.1,-69 + Has,M1,60 + Has,M2,110 + Has,M3,60 + Has,M4,40 + Has,M5,75 + Has,M6,90 + Has,BY,220 + Has,SX,108 + Has,Alice,236 + Has,Bob,239 + Has,Charlie,146 + StartStockRound,5 + HasPriority,Charlie + BUY_SHARE_LOG,Charlie,10,SX,IPO,88 + PriceIsPaidTo,88,SX + BUY_SHARE_LOG,Alice,10,SX,IPO,88 + PriceIsPaidTo,88,SX + BUY_SHARE_LOG,Bob,10,SX,IPO,88 + PriceIsPaidTo,88,SX + PASSES,Charlie + BUY_SHARE_LOG,Alice,10,SX,IPO,88 + PriceIsPaidTo,88,SX + SharesReleased,All,BA + PASSES,Bob + PASSES,Charlie + PASSES,Alice + + END_SR,5 + PRICE_MOVES_LOG,BY,120,E2,132,E1 + SoldOut,BY,120,E2,132,E1 + PRICE_MOVES_LOG,SX,84,B4,86,B3 + SoldOut,SX,84,B4,86,B3 + Has,M1,60 + Has,M2,110 + Has,M3,60 + Has,M4,40 + Has,M5,75 + Has,M6,90 + Has,BY,220 + Has,SX,460 + Has,Alice,60 + Has,Bob,151 + Has,Charlie,58 + START_OR,5.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,207,H2,E + CompanyRevenue,M1,50 + CompanySplits,M1,50 + M1 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M2,Alice + LaysTileAt,M2,209,E19,SW + CompanyRevenue,M2,80 + CompanySplits,M2,80 + M2 receives 40 + Payout,Alice,40,1,100 + BuysTrain,M2,2+2,BY,150 + + CompanyOperates,M3,Bob + LaysTileAt,M3,205,F14,SE + CompanyRevenue,M3,50 + CompanySplits,M3,50 + M3 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,14,G5,SW + CompanyRevenue,M4,80 + CompanySplits,M4,80 + M4 receives 40 + Payout,Charlie,40,1,100 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,208,H20,W + CompanyRevenue,M5,80 + CompanySplits,M5,80 + M5 receives 40 + Payout,Charlie,40,1,100 + BuysTrain,M5,2+2,SX,115 + + CompanyOperates,M6,Bob + LaysTileAt,M6,12,A11,W + CompanyRevenue,M6,70 + CompanySplits,M6,70 + M6 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,9,J10,W + LAYS_TOKEN_ON,BY,J8,120 + CompanyRevenue,BY,240 + CompanyPaysOutFull,BY,240 + Payout,Bob,72,3,10 + Payout,Alice,144,6,10 + Payout,Charlie,24,1,10 + PRICE_MOVES_LOG,BY,132,E1,148,F1 + BuysTrain,BY,3,IPO,180 + + CompanyOperates,SX,Charlie + LaysTileAt,SX,13,H16,W + LAYS_TOKEN_ON,SX,E19,60 + CompanyRevenue,SX,190 + CompanyPaysOutFull,SX,190 + Payout,Alice,38,2,10 + Payout,Bob,57,3,10 + Payout,Charlie,95,5,10 + PRICE_MOVES_LOG,SX,86,B3,92,C3 + BuysTrain,SX,3,IPO,180 + BuysTrain,SX,3,IPO,180 + All 3-trains are sold out, 3+3-trains now available + + EndOfOperatingRound,5.1 + ORWorthIncrease,Alice,5.1,340 + ORWorthIncrease,Bob,5.1,320 + ORWorthIncrease,Charlie,5.1,275 + Has,M1,85 + Has,M2,0 + Has,M3,85 + Has,M4,80 + Has,M5,0 + Has,M6,125 + Has,BY,70 + Has,SX,155 + Has,Alice,292 + Has,Bob,405 + Has,Charlie,287 + START_OR,5.2 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAtFor,M1,211,G3,E,50 + CompanyRevenue,M1,70 + CompanySplits,M1,70 + M1 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,M2,Alice + LaysTileAt,M2,23,D18,NW + CompanyRevenue,M2,180 + CompanySplits,M2,180 + M2 receives 90 + Payout,Alice,90,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,8,F8,E + CompanyRevenue,M3,50 + CompanySplits,M3,50 + M3 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,8,G7,W + CompanyRevenue,M4,110 + CompanySplits,M4,110 + M4 receives 55 + Payout,Charlie,55,1,100 + + CompanyOperates,M5,Charlie + LaysTileAt,M5,8,C17,SE + CompanyRevenue,M5,180 + CompanySplits,M5,180 + M5 receives 90 + Payout,Charlie,90,1,100 + + CompanyOperates,M6,Bob + LaysTileAt,M6,8,C15,NW + CompanyRevenue,M6,70 + CompanySplits,M6,70 + M6 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,BY,Alice + LaysTileAtFor,BY,214,J6,SE,50 + CompanyRevenue,BY,330 + CompanyPaysOutFull,BY,330 + Payout,Alice,198,6,10 + Payout,Bob,99,3,10 + Payout,Charlie,33,1,10 + PRICE_MOVES_LOG,BY,148,F1,166,G1 + + CompanyOperates,SX,Charlie + LaysTileAt,SX,23,H18,E + LAYS_TOKEN_ON,SX,H20,40 + CompanyRevenue,SX,370 + CompanyPaysOutFull,SX,370 + Payout,Alice,74,2,10 + Payout,Bob,111,3,10 + Payout,Charlie,185,5,10 + PRICE_MOVES_LOG,SX,92,C3,100,D3 + + EndOfOperatingRound,5.2 + ORWorthIncrease,Alice,5.2,496 + ORWorthIncrease,Bob,5.2,423 + ORWorthIncrease,Charlie,5.2,451 + Has,M1,70 + Has,M2,90 + Has,M3,110 + Has,M4,135 + Has,M5,90 + Has,M6,160 + Has,BY,20 + Has,SX,115 + Has,Alice,664 + Has,Bob,750 + Has,Charlie,680 + StartStockRound,6 + HasPriority,Bob + START_COMPANY_LOG,Bob,BA,84,168,2,20,BANK + SharesReleased,4 10%,PR + BUY_SHARE_LOG,Charlie,10,BA,IPO,84 + BUY_SHARE_LOG,Alice,10,BA,IPO,84 + BUY_SHARE_LOG,Bob,10,BA,IPO,84 + FloatsWithCash,BA,420 + SharesReleased,All,WT + BUY_SHARE_LOG,Charlie,10,BA,IPO,84 + PriceIsPaidTo,84,BA + START_COMPANY_LOG,Alice,WT,84,168,2,20,BANK + BUY_SHARE_LOG,Bob,10,BA,IPO,84 + PriceIsPaidTo,84,BA + BUY_SHARE_LOG,Charlie,10,BA,IPO,84 + PriceIsPaidTo,84,BA + BUY_SHARE_LOG,Alice,10,WT,IPO,84 + BUY_SHARE_LOG,Bob,20,BA,IPO,168 + PriceIsPaidTo,168,BA + BUY_SHARE_LOG,Charlie,10,WT,IPO,84 + BUY_SHARE_LOG,Alice,10,WT,IPO,84 + FloatsWithCash,WT,420 + SharesReleased,All,HE + BUY_SHARE_LOG,Bob,10,WT,IPO,84 + PriceIsPaidTo,84,WT + START_COMPANY_LOG,Charlie,HE,84,168,2,20,BANK + BUY_SHARE_LOG,Alice,10,HE,IPO,84 + BUY_SHARE_LOG,Bob,10,HE,IPO,84 + BUY_SHARE_LOG,Charlie,10,HE,IPO,84 + FloatsWithCash,HE,420 + BUY_SHARE_LOG,Alice,10,HE,IPO,84 + PriceIsPaidTo,84,HE + PASSES,Bob + BUY_SHARE_LOG,Charlie,10,HE,IPO,84 + PriceIsPaidTo,84,HE + PASSES,Alice + PASSES,Bob + PASSES,Charlie + + END_SR,6 + PRICE_STAYS_LOG,BY,166,G1 + SoldOutNoRaise,BY,166,G1 + PRICE_MOVES_LOG,SX,100,D3,108,D2 + SoldOut,SX,100,D3,108,D2 + PRICE_MOVES_LOG,BA,84,B4,86,B3 + SoldOut,BA,84,B4,86,B3 + Has,M1,70 + Has,M2,90 + Has,M3,110 + Has,M4,135 + Has,M5,90 + Has,M6,160 + Has,BY,20 + Has,SX,115 + Has,BA,840 + Has,WT,504 + Has,HE,588 + Has,Alice,76 + Has,Bob,78 + Has,Charlie,8 + START_OR,6.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,9,I5,SE + CompanyRevenue,M1,70 + CompanySplits,M1,70 + M1 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,M2,Alice + CompanyRevenue,M2,180 + CompanySplits,M2,180 + M2 receives 90 + Payout,Alice,90,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,206,F10,SE + CompanyRevenue,M3,50 + CompanySplits,M3,50 + M3 receives 25 + Payout,Bob,25,1,100 + + CompanyOperates,M4,Charlie + LaysTileAt,M4,15,D8,NE + CompanyRevenue,M4,110 + CompanySplits,M4,110 + M4 receives 55 + Payout,Charlie,55,1,100 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,180 + CompanySplits,M5,180 + M5 receives 90 + Payout,Charlie,90,1,100 + + CompanyOperates,M6,Bob + CompanyRevenue,M6,70 + CompanySplits,M6,70 + M6 receives 35 + Payout,Bob,35,1,100 + + CompanyOperates,BY,Alice + LaysTileAt,BY,8,K5,NE + CompanyRevenue,BY,330 + CompanyPaysOutFull,BY,330 + Payout,Alice,198,6,10 + Payout,Bob,99,3,10 + Payout,Charlie,33,1,10 + PRICE_MOVES_LOG,BY,166,G1,186,H1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,370 + CompanyPaysOutFull,SX,370 + Payout,Alice,74,2,10 + Payout,Bob,111,3,10 + Payout,Charlie,185,5,10 + PRICE_MOVES_LOG,SX,108,D2,120,E2 + + CompanyOperates,BA,Bob + LaysTileAt,BA,210,L6,E + CompanyDoesNotPayDividend,BA + PRICE_MOVES_LOG,BA,86,B3,82,A3 + BuysTrain,BA,3+3,IPO,270 + FirstTrainBought,3+3 + BuysTrain,BA,3+3,IPO,270 + BuysTrain,BA,3+3,IPO,270 + All 3+3-trains are sold out, 4-trains now available + + CompanyOperates,WT,Alice + LaysTileAt,WT,57,M9,W + CompanyDoesNotPayDividend,WT + PRICE_MOVES_LOG,WT,84,B4,78,A4 + BuysTrain,WT,4,IPO,360 + FirstTrainBought,4 + StartOfPhase,4 + CompanyDiscardsTrain,SX,2+2 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRound,PR,OperatingRound 6.1 + + CompanyOperates,HE,Charlie + LaysTileAtFor,HE,9,K7,SW,50 + CompanyDoesNotPayDividend,HE + PRICE_MOVES_LOG,HE,84,B4,78,A4 + BuysTrain,HE,4,IPO,360 + + EndOfOperatingRound,6.1 + ORWorthIncrease,Alice,6.1,476 + ORWorthIncrease,Bob,6.1,405 + ORWorthIncrease,Charlie,6.1,431 + Has,M1,105 + Has,M2,180 + Has,M3,135 + Has,M4,190 + Has,M5,180 + Has,M6,195 + Has,BY,20 + Has,SX,115 + Has,BA,30 + Has,WT,144 + Has,HE,178 + Has,Alice,448 + Has,Bob,423 + Has,Charlie,401 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRoundNoInterrupt,PR + START_OR,6.2 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + LaysTileAt,M1,8,D10,W + CompanyDoesNotPayDividend,M1 + BuysTrain,M1,3+3,BA,105 + + CompanyOperates,M2,Alice + LaysTileAt,M2,203,B12,W + CompanyRevenue,M2,100 + CompanySplits,M2,100 + M2 receives 50 + Payout,Alice,50,1,100 + + CompanyOperates,M3,Bob + LaysTileAt,M3,9,F16,W + CompanyDoesNotPayDividend,M3 + + CompanyOperates,M4,Charlie + CompanyDoesNotPayDividend,M4 + BuysTrain,M4,3,SX,190 + + CompanyOperates,M5,Charlie + CompanyRevenue,M5,100 + CompanySplits,M5,100 + M5 receives 50 + Payout,Charlie,50,1,100 + + CompanyOperates,M6,Bob + CompanyDoesNotPayDividend,M6 + BuysTrain,M6,3+3,BA,195 + + CompanyOperates,BY,Alice + LaysTileAt,BY,23,F20,NW + CompanyRevenue,BY,180 + CompanyPaysOutFull,BY,180 + Payout,Alice,108,6,10 + Payout,Bob,54,3,10 + Payout,Charlie,18,1,10 + PRICE_MOVES_LOG,BY,186,H1,208,I1 + BuysTrain,BY,2+2,M2,1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,220 + CompanyPaysOutFull,SX,220 + Payout,Alice,44,2,10 + Payout,Bob,66,3,10 + Payout,Charlie,110,5,10 + PRICE_MOVES_LOG,SX,120,E2,134,F2 + BuysTrain,SX,2+2,M5,1 + + CompanyOperates,BA,Bob + CompanyRevenue,BA,120 + CompanyPaysOutFull,BA,120 + Payout,Alice,12,1,10 + Payout,Bob,72,6,10 + Payout,Charlie,36,3,10 + PRICE_MOVES_LOG,BA,82,A3,86,B3 + BuysTrain,BA,3+3,M1,1 + + CompanyOperates,WT,Alice + LaysTileAt,WT,9,M11,W + CompanyRevenue,WT,0 + CompanyDoesNotPayDividend,WT + PRICE_MOVES_LOG,WT,78,A4,72,A5 + + CompanyOperates,HE,Charlie + CompanyRevenue,HE,130 + CompanyPaysOutFull,HE,130 + Payout,Alice,26,2,10 + Payout,Bob,13,1,10 + Payout,Charlie,52,4,10 + PRICE_MOVES_LOG,HE,78,A4,84,B4 + BuysTrain,HE,3+3,M6,1 + + EndOfOperatingRound,6.2 + ORWorthIncrease,Alice,6.2,402 + ORWorthIncrease,Bob,6.2,377 + ORWorthIncrease,Charlie,6.2,418 + Has,M1,1 + Has,M2,231 + Has,M3,135 + Has,M4,0 + Has,M5,231 + Has,M6,1 + Has,BY,19 + Has,SX,304 + Has,BA,329 + Has,WT,144 + Has,HE,177 + Has,Alice,698 + Has,Bob,668 + Has,Charlie,697 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRoundNoInterrupt,PR + StartStockRound,7 + HasPriority,Alice + BUY_SHARE_LOG,Alice,10,PR,IPO,154 + BUY_SHARE_LOG,Bob,10,PR,IPO,154 + BUY_SHARE_LOG,Charlie,10,PR,IPO,154 + BUY_SHARE_LOG,Alice,10,PR,IPO,154 + SELL_SHARE_LOG,Bob,10,BY,208 + PRICE_MOVES_LOG,BY,208,I1,188,I2 + BUY_SHARE_LOG,Charlie,10,HE,IPO,84 + PriceIsPaidTo,84,HE + BUY_SHARE_LOG,Alice,10,BY,Pool,188 + BUY_SHARE_LOG,Bob,20,HE,IPO,168 + PriceIsPaidTo,168,HE + BUY_SHARE_LOG,Charlie,10,WT,IPO,84 + PriceIsPaidTo,84,WT + BUY_SHARE_LOG,Alice,10,WT,IPO,84 + PriceIsPaidTo,84,WT + PASSES,Bob + PASSES,Charlie + PASSES,Alice + + END_SR,7 + PRICE_MOVES_LOG,BY,188,I2,208,I1 + SoldOut,BY,188,I2,208,I1 + PRICE_MOVES_LOG,SX,134,F2,148,F1 + SoldOut,SX,134,F2,148,F1 + SoldOutNoRaise,BA,86,B3 + PRICE_MOVES_LOG,HE,84,B4,86,B3 + SoldOut,HE,84,B4,86,B3 + Has,M1,1 + Has,M2,231 + Has,M3,135 + Has,M4,0 + Has,M5,231 + Has,M6,1 + Has,BY,19 + Has,SX,304 + Has,BA,329 + Has,WT,312 + Has,HE,429 + Has,Alice,118 + Has,Bob,554 + Has,Charlie,375 + StartFormationRound,PR + StartingPlayer,Alice + + EndOfFormationRoundNoInterrupt,PR + START_OR,7.1 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + CompanyDoesNotPayDividend,M1 + + CompanyOperates,M2,Alice + CompanyDoesNotPayDividend,M2 + BuysTrain,M2,2+2,BY,231 + + CompanyOperates,M3,Bob + CompanyDoesNotPayDividend,M3 + BuysTrain,M3,3+3,BA,135 + + CompanyOperates,M4,Charlie + CompanyRevenue,M4,90 + CompanySplits,M4,90 + M4 receives 45 + Payout,Charlie,45,1,100 + + CompanyOperates,M5,Charlie + CompanyDoesNotPayDividend,M5 + BuysTrain,M5,2+2,SX,231 + + CompanyOperates,M6,Bob + CompanyDoesNotPayDividend,M6 + + CompanyOperates,BY,Alice + CompanyRevenue,BY,190 + CompanyPaysOutFull,BY,190 + Payout,Alice,133,7,10 + Payout,Bob,38,2,10 + Payout,Charlie,19,1,10 + PRICE_MOVES_LOG,BY,208,I1,232,J1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,220 + CompanyPaysOutFull,SX,220 + Payout,Alice,44,2,10 + Payout,Bob,66,3,10 + Payout,Charlie,110,5,10 + PRICE_MOVES_LOG,SX,148,F1,166,G1 + BuysTrain,SX,4,IPO,360 + All 4-trains are sold out, 4+4-trains now available + + CompanyOperates,BA,Bob + CompanyRevenue,BA,120 + CompanyPaysOutFull,BA,120 + Payout,Alice,12,1,10 + Payout,Bob,72,6,10 + Payout,Charlie,36,3,10 + PRICE_MOVES_LOG,BA,86,B3,92,C3 + BuysTrain,BA,4+4,IPO,440 + All 4+4-trains are sold out, 5-trains now available + FirstTrainBought,4+4 + StartOfPhase,4+4 + StartFormationRound,PR + START_MERGED_COMPANY,PR,154,154 + FloatsWithCash,PR,616 + MERGE_MINOR_LOG,Alice,M2,PR,0,0 + GetShareForMinor,Alice,10,PR,IPO,M2 + ExchangesBaseToken,PR,M2,E19/1 + + EndOfFormationRound,PR,OperatingRound 7.1 + + CompanyOperates,HE,Charlie + LaysTileAt,HE,8,L4,NW + LAYS_TOKEN_ON,HE,G5,60 + CompanyRevenue,HE,260 + CompanyPaysOutFull,HE,260 + Payout,Alice,52,2,10 + Payout,Bob,78,3,10 + Payout,Charlie,130,5,10 + PRICE_MOVES_LOG,HE,86,B3,92,C3 + + CompanyOperates,WT,Alice + LaysTileAt,WT,69,M7,SE + CompanyRevenue,WT,280 + CompanyWithholds,WT,280 + PRICE_MOVES_LOG,WT,72,A5,64,A6 + + EndOfOperatingRound,7.1 + ORWorthIncrease,Alice,7.1,587 + ORWorthIncrease,Bob,7.1,442 + ORWorthIncrease,Charlie,7.1,516 + Has,M1,1 + Has,M3,0 + Has,M4,45 + Has,M5,0 + Has,M6,1 + Has,BY,250 + Has,SX,175 + Has,BA,24 + Has,WT,592 + Has,HE,369 + Has,PR,616 + Has,Alice,369 + Has,Bob,848 + Has,Charlie,745 + StartFormationRound,PR + + EndOfFormationRoundNoInterrupt,PR + START_OR,7.2 + ReceivesFor,Alice,10,OBB + ReceivesFor,Bob,15,PfB + ReceivesFor,Bob,25,BB + ReceivesFor,Charlie,30,HB + + CompanyOperates,M1,Bob + CompanyDoesNotPayDividend,M1 + BuysTrain,M1,3+3,BA,1 + + CompanyOperates,M3,Bob + CompanyRevenue,M3,90 + CompanySplits,M3,90 + M3 receives 45 + Payout,Bob,45,1,100 + + CompanyOperates,M4,Charlie + CompanyRevenue,M4,90 + CompanySplits,M4,90 + M4 receives 45 + Payout,Charlie,45,1,100 + + CompanyOperates,M5,Charlie + CompanyDoesNotPayDividend,M5 + + CompanyOperates,M6,Bob + CompanyDoesNotPayDividend,M6 + BuysTrain,M6,3,SX,1 + + CompanyOperates,BY,Alice + CompanyRevenue,BY,110 + CompanyPaysOutFull,BY,110 + Payout,Alice,77,7,10 + Payout,Bob,22,2,10 + Payout,Charlie,11,1,10 + PRICE_MOVES_LOG,BY,232,J1,258,K1 + + CompanyOperates,SX,Charlie + CompanyRevenue,SX,240 + CompanyPaysOutFull,SX,240 + Payout,Alice,48,2,10 + Payout,Bob,72,3,10 + Payout,Charlie,120,5,10 + PRICE_MOVES_LOG,SX,166,G1,186,H1 + + CompanyOperates,PR,Alice + CompanyDoesNotPayDividend,PR + PRICE_MOVES_LOG,PR,154,I4,138,H4 + BuysTrain,PR,5,IPO,500 + FirstTrainBought,5 + StartOfPhase,5 + PhaseClosesAllPrivates, + PrivateCloses,OBB + PrivateCloses,PfB + StartFormationRound,PR + MERGE_MINOR_LOG,Bob,BB,PR,no,no + GetShareForMinor,Bob,10,PR,IPO,BB + PrivateCloses,BB + MERGE_MINOR_LOG,Charlie,HB,PR,no,no + GetShareForMinor,Charlie,10,PR,IPO,HB + PrivateCloses,HB + MERGE_MINOR_LOG,Bob,M1,PR,0,1 + GetShareForMinor,Bob,5,PR,IPO,M1 + ExchangesBaseToken,PR,M1,H2/1 + MERGE_MINOR_LOG,Bob,M3,PR,45,1 + GetShareForMinor,Bob,5,PR,IPO,M3 + ExchangesBaseToken,PR,M3,F14/1 + MERGE_MINOR_LOG,Charlie,M4,PR,90,1 + GetShareForMinor,Charlie,10,PR,IPO,M4 + ExchangesBaseToken,PR,M4,G5/1 + MERGE_MINOR_LOG,Charlie,M5,PR,0,0 + GetShareForMinor,Charlie,5,PR,IPO,M5 + MERGE_MINOR_LOG,Bob,M6,PR,0,1 + GetShareForMinor,Bob,5,PR,IPO,M6 + ExchangesBaseToken,PR,M6,C11/1 + CompanyDiscardsTrain,PR,3 + CompanyDiscardsTrain,PR,3 + + EndOfFormationRound,PR,OperatingRound 7.2 + IS_NOW_PRES_OF,Bob,PR + -CompanyOperates,BA,Bob +CompanyOperates,BA,Bob - LaysTileAt,BA,210,L6,E - CompanyDoesNotPayDividend,BA - PRICE_MOVES_LOG,BA,86,B3,82,A3 - BuysTrain,BA,3+3,IPO,270 - FirstTrainBought,3+3 - BuysTrain,BA,3+3,IPO,270 - BuysTrain,BA,3+3,IPO,270 - All 3+3-trains are sold out, 4-trains now available - - CompanyOperates,WT,Alice - LaysTileAt,WT,57,M9,W - CompanyDoesNotPayDividend,WT - PRICE_MOVES_LOG,WT,84,B4,78,A4 - BuysTrain,WT,4,IPO,360 - FirstTrainBought,4 - StartOfPhase,4 - CompanyDiscardsTrain,SX,2+2 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRound,PR,OperatingRound 6.1 - - CompanyOperates,HE,Charlie - LaysTileAtFor,HE,9,K7,SW,50 - CompanyDoesNotPayDividend,HE - PRICE_MOVES_LOG,HE,84,B4,78,A4 - BuysTrain,HE,4,IPO,360 - - EndOfOperatingRound,6.1 - ORWorthIncrease,Alice,6.1,476 - ORWorthIncrease,Bob,6.1,405 - ORWorthIncrease,Charlie,6.1,431 - Has,M1,105 - Has,M2,180 - Has,M3,135 - Has,M4,190 - Has,M5,180 - Has,M6,195 - Has,BY,20 - Has,SX,115 - Has,BA,30 - Has,WT,144 - Has,HE,178 - Has,Alice,448 - Has,Bob,423 - Has,Charlie,401 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRoundNoInterrupt,PR - START_OR,6.2 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,8,D10,W - CompanyDoesNotPayDividend,M1 - BuysTrain,M1,3+3,BA,105 - - CompanyOperates,M2,Alice - LaysTileAt,M2,203,B12,W - CompanyRevenue,M2,100 - CompanySplits,M2,100 - M2 receives 50 - Payout,Alice,50,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,9,F16,W - CompanyDoesNotPayDividend,M3 - - CompanyOperates,M4,Charlie - CompanyDoesNotPayDividend,M4 - BuysTrain,M4,3,SX,190 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,100 - CompanySplits,M5,100 - M5 receives 50 - Payout,Charlie,50,1,100 - - CompanyOperates,M6,Bob - CompanyDoesNotPayDividend,M6 - BuysTrain,M6,3+3,BA,195 - - CompanyOperates,BY,Alice - LaysTileAt,BY,23,F20,NW - CompanyRevenue,BY,180 - CompanyPaysOutFull,BY,180 - Payout,Alice,108,6,10 - Payout,Bob,54,3,10 - Payout,Charlie,18,1,10 - PRICE_MOVES_LOG,BY,186,H1,208,I1 - BuysTrain,BY,2+2,M2,1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,220 - CompanyPaysOutFull,SX,220 - Payout,Alice,44,2,10 - Payout,Bob,66,3,10 - Payout,Charlie,110,5,10 - PRICE_MOVES_LOG,SX,120,E2,134,F2 - BuysTrain,SX,2+2,M5,1 - - CompanyOperates,BA,Bob - CompanyRevenue,BA,120 - CompanyPaysOutFull,BA,120 - Payout,Alice,12,1,10 - Payout,Bob,72,6,10 - Payout,Charlie,36,3,10 - PRICE_MOVES_LOG,BA,82,A3,86,B3 - BuysTrain,BA,3+3,M1,1 - - CompanyOperates,WT,Alice - LaysTileAt,WT,9,M11,W - CompanyRevenue,WT,0 - CompanyDoesNotPayDividend,WT - PRICE_MOVES_LOG,WT,78,A4,72,A5 - - CompanyOperates,HE,Charlie - CompanyRevenue,HE,130 - CompanyPaysOutFull,HE,130 - Payout,Alice,26,2,10 - Payout,Bob,13,1,10 - Payout,Charlie,52,4,10 - PRICE_MOVES_LOG,HE,78,A4,84,B4 - BuysTrain,HE,3+3,M6,1 - - EndOfOperatingRound,6.2 - ORWorthIncrease,Alice,6.2,402 - ORWorthIncrease,Bob,6.2,377 - ORWorthIncrease,Charlie,6.2,418 - Has,M1,1 - Has,M2,231 - Has,M3,135 - Has,M4,0 - Has,M5,231 - Has,M6,1 - Has,BY,19 - Has,SX,304 - Has,BA,329 - Has,WT,144 - Has,HE,177 - Has,Alice,698 - Has,Bob,668 - Has,Charlie,697 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRoundNoInterrupt,PR - StartStockRound,7 - HasPriority,Alice - BUY_SHARE_LOG,Alice,10,PR,IPO,154 - BUY_SHARE_LOG,Bob,10,PR,IPO,154 - BUY_SHARE_LOG,Charlie,10,PR,IPO,154 - BUY_SHARE_LOG,Alice,10,PR,IPO,154 - SELL_SHARE_LOG,Bob,10,BY,208 - PRICE_MOVES_LOG,BY,208,I1,188,I2 - BUY_SHARE_LOG,Charlie,10,HE,IPO,84 - PriceIsPaidTo,84,HE - BUY_SHARE_LOG,Alice,10,BY,Pool,188 - BUY_SHARE_LOG,Bob,20,HE,IPO,168 - PriceIsPaidTo,168,HE - BUY_SHARE_LOG,Charlie,10,WT,IPO,84 - PriceIsPaidTo,84,WT - BUY_SHARE_LOG,Alice,10,WT,IPO,84 - PriceIsPaidTo,84,WT - PASSES,Bob - PASSES,Charlie - PASSES,Alice - - END_SR,7 - PRICE_MOVES_LOG,BY,188,I2,208,I1 - SoldOut,BY,188,I2,208,I1 - PRICE_MOVES_LOG,SX,134,F2,148,F1 - SoldOut,SX,134,F2,148,F1 - SoldOutNoRaise,BA,86,B3 - PRICE_MOVES_LOG,HE,84,B4,86,B3 - SoldOut,HE,84,B4,86,B3 - Has,M1,1 - Has,M2,231 - Has,M3,135 - Has,M4,0 - Has,M5,231 - Has,M6,1 - Has,BY,19 - Has,SX,304 - Has,BA,329 - Has,WT,312 - Has,HE,429 - Has,Alice,118 - Has,Bob,554 - Has,Charlie,375 - StartFormationRound,PR - StartingPlayer,Alice - - EndOfFormationRoundNoInterrupt,PR - START_OR,7.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - CompanyDoesNotPayDividend,M1 - - CompanyOperates,M2,Alice - CompanyDoesNotPayDividend,M2 - BuysTrain,M2,2+2,BY,231 - - CompanyOperates,M3,Bob - CompanyDoesNotPayDividend,M3 - BuysTrain,M3,3+3,BA,135 - - CompanyOperates,M4,Charlie - CompanyRevenue,M4,90 - CompanySplits,M4,90 - M4 receives 45 - Payout,Charlie,45,1,100 - - CompanyOperates,M5,Charlie - CompanyDoesNotPayDividend,M5 - BuysTrain,M5,2+2,SX,231 - - CompanyOperates,M6,Bob - CompanyDoesNotPayDividend,M6 - - CompanyOperates,BY,Alice - CompanyRevenue,BY,190 - CompanyPaysOutFull,BY,190 - Payout,Alice,133,7,10 - Payout,Bob,38,2,10 - Payout,Charlie,19,1,10 - PRICE_MOVES_LOG,BY,208,I1,232,J1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,220 - CompanyPaysOutFull,SX,220 - Payout,Alice,44,2,10 - Payout,Bob,66,3,10 - Payout,Charlie,110,5,10 - PRICE_MOVES_LOG,SX,148,F1,166,G1 - BuysTrain,SX,4,IPO,360 - All 4-trains are sold out, 4+4-trains now available - - CompanyOperates,BA,Bob - CompanyRevenue,BA,120 - CompanyPaysOutFull,BA,120 - Payout,Alice,12,1,10 - Payout,Bob,72,6,10 - Payout,Charlie,36,3,10 - PRICE_MOVES_LOG,BA,86,B3,92,C3 - BuysTrain,BA,4+4,IPO,440 - All 4+4-trains are sold out, 5-trains now available - FirstTrainBought,4+4 - StartOfPhase,4+4 - StartFormationRound,PR - START_MERGED_COMPANY,PR,154,154 - FloatsWithCash,PR,616 - MERGE_MINOR_LOG,Alice,M2,PR,0,0 - GetShareForMinor,Alice,10,PR,IPO,M2 - ExchangesBaseToken,PR,M2,E19/1 - - EndOfFormationRound,PR,OperatingRound 7.1 - - CompanyOperates,HE,Charlie - LaysTileAt,HE,8,L4,NW - LAYS_TOKEN_ON,HE,G5,60 - CompanyRevenue,HE,260 - CompanyPaysOutFull,HE,260 - Payout,Alice,52,2,10 - Payout,Bob,78,3,10 - Payout,Charlie,130,5,10 - PRICE_MOVES_LOG,HE,86,B3,92,C3 - - CompanyOperates,WT,Alice - LaysTileAt,WT,69,M7,SE - CompanyRevenue,WT,280 - CompanyWithholds,WT,280 - PRICE_MOVES_LOG,WT,72,A5,64,A6 - - EndOfOperatingRound,7.1 - ORWorthIncrease,Alice,7.1,587 - ORWorthIncrease,Bob,7.1,442 - ORWorthIncrease,Charlie,7.1,516 - Has,M1,1 - Has,M3,0 - Has,M4,45 - Has,M5,0 - Has,M6,1 - Has,BY,250 - Has,SX,175 - Has,BA,24 - Has,WT,592 - Has,HE,369 - Has,PR,616 - Has,Alice,369 - Has,Bob,848 - Has,Charlie,745 - StartFormationRound,PR - - EndOfFormationRoundNoInterrupt,PR - START_OR,7.2 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - CompanyDoesNotPayDividend,M1 - BuysTrain,M1,3+3,BA,1 - - CompanyOperates,M3,Bob - CompanyRevenue,M3,90 - CompanySplits,M3,90 - M3 receives 45 - Payout,Bob,45,1,100 - - CompanyOperates,M4,Charlie - CompanyRevenue,M4,90 - CompanySplits,M4,90 - M4 receives 45 - Payout,Charlie,45,1,100 - - CompanyOperates,M5,Charlie - CompanyDoesNotPayDividend,M5 - - CompanyOperates,M6,Bob - CompanyDoesNotPayDividend,M6 - BuysTrain,M6,3,SX,1 - - CompanyOperates,BY,Alice - CompanyRevenue,BY,110 - CompanyPaysOutFull,BY,110 - Payout,Alice,77,7,10 - Payout,Bob,22,2,10 - Payout,Charlie,11,1,10 - PRICE_MOVES_LOG,BY,232,J1,258,K1 - - CompanyOperates,SX,Charlie - CompanyRevenue,SX,240 - CompanyPaysOutFull,SX,240 - Payout,Alice,48,2,10 - Payout,Bob,72,3,10 - Payout,Charlie,120,5,10 - PRICE_MOVES_LOG,SX,166,G1,186,H1 - - CompanyOperates,PR,Alice - CompanyDoesNotPayDividend,PR - PRICE_MOVES_LOG,PR,154,I4,138,H4 - BuysTrain,PR,5,IPO,500 - FirstTrainBought,5 - StartOfPhase,5 - PrivateCloses,OBB - PrivateCloses,PfB - StartFormationRound,PR - MERGE_MINOR_LOG,Bob,BB,PR,no,no - GetShareForMinor,Bob,10,PR,IPO,BB - PrivateCloses,BB - MERGE_MINOR_LOG,Charlie,HB,PR,no,no - GetShareForMinor,Charlie,10,PR,IPO,HB - PrivateCloses,HB - MERGE_MINOR_LOG,Bob,M1,PR,0,1 - GetShareForMinor,Bob,5,PR,IPO,M1 - ExchangesBaseToken,PR,M1,H2/1 - MERGE_MINOR_LOG,Bob,M3,PR,45,1 - GetShareForMinor,Bob,5,PR,IPO,M3 - ExchangesBaseToken,PR,M3,F14/1 - MERGE_MINOR_LOG,Charlie,M4,PR,90,1 - GetShareForMinor,Charlie,10,PR,IPO,M4 - ExchangesBaseToken,PR,M4,G5/1 - MERGE_MINOR_LOG,Charlie,M5,PR,0,0 - GetShareForMinor,Charlie,5,PR,IPO,M5 - MERGE_MINOR_LOG,Bob,M6,PR,0,1 - GetShareForMinor,Bob,5,PR,IPO,M6 - ExchangesBaseToken,PR,M6,C11/1 - CompanyDiscardsTrain,PR,3 - CompanyDiscardsTrain,PR,3 - - EndOfFormationRound,PR,OperatingRound 7.2 - IS_NOW_PRES_OF,Bob,PR - - CompanyOperates,BA,Bob - >>>>>>> refs/remotes/origin/rails1.7.x diff --cc test/data/test/1835_PR_3rdTrain.report index ede7755,a3c344f..e08be7e --- a/test/data/test/1835_PR_3rdTrain.report +++ b/test/data/test/1835_PR_3rdTrain.report @@@ -1,1104 -1,1104 +1,1105 @@@ - GameIs,1835 - PlayerIs,1,Alice - PlayerIs,2,Bob - PlayerIs,3,Charlie - PlayerCash,600 - BankHas,10200 - StartOfPhase,2 - BankSizeIs,10200 - StartOfInitialRound - HasPriority,Alice - BuysItemFor,Alice,NF,100 - ALSO_GETS,Alice,CERT_NAME,BY,10 - BuysItemFor,Bob,M1,80 - FloatsWithCash,M1,80 - BuysItemFor,Charlie,LD,190 - ALSO_GETS,Charlie,PRES_CERT_NAME,SX,20 - BuysItemFor,Alice,M2,170 - FloatsWithCash,M2,170 - BuysItemFor,Bob,M3,80 - FloatsWithCash,M3,80 - BuysItemFor,Charlie,M4,160 - FloatsWithCash,M4,160 - BuysItemFor,Alice,PRES_CERT_NAME,BY,20,184 - BuysItemFor,Bob,BB,130 - BuysItemFor,Charlie,HB,160 - BuysItemFor,Alice,OBB,120 - ALSO_GETS,Alice,CERT_NAME,BY,10 - BuysItemFor,Bob,PfB,150 - ALSO_GETS,Bob,CERT_NAME,BY,10 - FloatsWithCash,BY,460 - BuysItemFor,Charlie,M5,80 - FloatsWithCash,M5,80 - CannotBuyAnything,Alice - BuysItemFor,Bob,M6,80 - FloatsWithCash,M6,80 - Has,M1,80 - Has,M2,170 - Has,M3,80 - Has,M4,160 - Has,M5,80 - Has,M6,80 - Has,BY,460 - Has,Alice,26 - Has,Bob,80 - Has,Charlie,10 - StartStockRound,1 - HasPriority,Charlie - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,1 - Has,M1,80 - Has,M2,170 - Has,M3,80 - Has,M4,160 - Has,M5,80 - Has,M6,80 - Has,BY,460 - Has,Alice,26 - Has,Bob,80 - Has,Charlie,10 - START_OR,1.1 - ReceivesFor,Alice,5,NF - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,202,H2,W - CompanyDoesNotPayDividend,M1 - BuysTrain,M1,2,IPO,80 - FirstTrainBought,2 - - CompanyOperates,M2,Alice - LaysTileAt,M2,8,E17,NW - CompanyDoesNotPayDividend,M2 - BuysTrain,M2,2,IPO,80 - - CompanyOperates,M3,Bob - LaysTileAt,M3,6,F14,NW - CompanyDoesNotPayDividend,M3 - BuysTrain,M3,2,IPO,80 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,57,G5,SW - CompanyDoesNotPayDividend,M4 - BuysTrain,M4,2,IPO,80 - BuysTrain,M4,2,IPO,80 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,D18,NE - CompanyDoesNotPayDividend,M5 - BuysTrain,M5,2,IPO,80 - - CompanyOperates,M6,Bob - LaysTileAt,M6,9,B10,NW - CompanyDoesNotPayDividend,M6 - BuysTrain,M6,2,IPO,80 - - CompanyOperates,BY,Alice - LAYS_FREE_TOKEN_ON,BY,L14 - PrivateCloses,NF - LaysTileAtFor,BY,9,K15,SW,70 - LaysTileAt,BY,1,I17,SW - LaysTileAt,BY,58,M15,SW - CompanyDoesNotPayDividend,BY - PRICE_MOVES_LOG,BY,92,C3,86,B3 - BuysTrain,BY,2,IPO,80 - BuysTrain,BY,2,IPO,80 - All 2-trains are sold out, 2+2-trains now available - BuysTrain,BY,2+2,IPO,120 - FirstTrainBought,2+2 - - EndOfOperatingRound,1.1 - ORWorthIncrease,Alice,1.1,-109 - ORWorthIncrease,Bob,1.1,34 - ORWorthIncrease,Charlie,1.1,50 - Has,M1,0 - Has,M2,90 - Has,M3,0 - Has,M4,0 - Has,M5,0 - Has,M6,0 - Has,BY,110 - Has,Alice,41 - Has,Bob,120 - Has,Charlie,60 - StartStockRound,2 - HasPriority,Charlie - PASSES,Charlie - PASSES,Alice - BUY_SHARE_LOG,Bob,10,BY,IPO,92 - PriceIsPaidTo,92,BY - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,2 - Has,M1,0 - Has,M2,90 - Has,M3,0 - Has,M4,0 - Has,M5,0 - Has,M6,0 - Has,BY,202 - Has,Alice,41 - Has,Bob,28 - Has,Charlie,60 - START_OR,2.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,69,H4,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - LaysTileAt,M2,8,D16,SE - CompanyRevenue,M2,0 - CompanyDoesNotPayDividend,M2 - - CompanyOperates,M3,Bob - LaysTileAt,M3,4,G15,NW - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,4,F6,SW - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - LaysTileAt,M5,8,C19,E - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,6,A11,NW - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,202,H20,W - LaysTileAt,BY,9,F20,NW - LAYS_TOKEN_ON,BY,H20,160 - CompanyRevenue,BY,160 - CompanyPaysOutFull,BY,160 - Payout,Bob,32,2,10 - Payout,Alice,64,4,10 - PRICE_MOVES_LOG,BY,86,B3,92,C3 - - EndOfOperatingRound,2.1 - ORWorthIncrease,Alice,2.1,98 - ORWorthIncrease,Bob,2.1,154 - ORWorthIncrease,Charlie,2.1,105 - Has,M1,20 - Has,M2,90 - Has,M3,20 - Has,M4,30 - Has,M5,25 - Has,M6,30 - Has,BY,42 - Has,Alice,115 - Has,Bob,170 - Has,Charlie,165 - StartStockRound,3 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Alice,10,BY,IPO,92 - PriceIsPaidTo,92,BY - BUY_SHARE_LOG,Bob,10,BY,IPO,92 - PriceIsPaidTo,92,BY - PASSES,Charlie - PASSES,Alice - PASSES,Bob - - END_SR,3 - Has,M1,20 - Has,M2,90 - Has,M3,20 - Has,M4,30 - Has,M5,25 - Has,M6,30 - Has,BY,318 - Has,Alice,23 - Has,Bob,78 - Has,Charlie,73 - START_OR,3.1 - ReceivesFor,Alice,10,OBB - ReceivesFor,Bob,15,PfB - ReceivesFor,Charlie,20,LD - ReceivesFor,Bob,25,BB - ReceivesFor,Charlie,30,HB - - CompanyOperates,M1,Bob - LaysTileAt,M1,9,J2,NW - CompanyRevenue,M1,40 - CompanySplits,M1,40 - M1 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M2,Alice - LaysTileAtFor,M2,8,D14,NW,50 - CompanyRevenue,M2,70 - CompanySplits,M2,70 - M2 receives 35 - Payout,Alice,35,1,100 - - CompanyOperates,M3,Bob - LaysTileAt,M3,6,H16,SE - CompanyRevenue,M3,40 - CompanySplits,M3,40 - M3 receives 20 - Payout,Bob,20,1,100 - - CompanyOperates,M4,Charlie - LaysTileAt,M4,9,E7,SW - CompanyRevenue,M4,60 - CompanySplits,M4,60 - M4 receives 30 - Payout,Charlie,30,1,100 - - CompanyOperates,M5,Charlie - CompanyRevenue,M5,50 - CompanySplits,M5,50 - M5 receives 25 - Payout,Charlie,25,1,100 - - CompanyOperates,M6,Bob - LaysTileAt,M6,58,B12,NW - CompanyRevenue,M6,60 - CompanySplits,M6,60 - M6 receives 30 - Payout,Bob,30,1,100 - - CompanyOperates,BY,Alice - LaysTileAt,BY,8,N14,NE - LaysTileAt,BY,201,O15,NW - CompanyRevenue,BY,190 - CompanyPaysOutFull,BY,190 - Payout,Charlie,19,1,10 - Payout,Bob,57,3,10 - Payout,Alice,95,5,10 - PRICE_MOVES_LOG,BY,92,C3,100,D3 - BuysTrain,BY,2+2,IPO,120 - - EndOfOperatingRound,3.1 - ORWorthIncrease,Alice,3.1,180 - ORWorthIncrease,Bob,3.1,191 - ORWorthIncrease,Charlie,3.1,132 - Has,M1,40 - Has,M2,75 - Has,M3,40 - Has,M4,60 - Has,M5,50 - Has,M6,60 - Has,BY,198 - Has,Alice,163 - Has,Bob,245 - Has,Charlie,197 - StartStockRound,4 - HasPriority,Charlie - BUY_SHARE_LOG,Charlie,10,SX,IPO,88 - BUY_SHARE_LOG,Alic... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-06-15 15:46:14
|
data/1835/CompanyManager.xml | 4 +-- rails/ui/swing/ORUIManager.java | 53 ++++++++++++++++++++++++++++++++++++---- rails/util/GameFileIO.java | 16 ++++++------ readme.txt | 18 +++++++++---- version.number | 2 - 5 files changed, 73 insertions(+), 20 deletions(-) New commits: commit 90ba59260b14c2a7d5f14a37c730d7d0cc5e0baf Author: Stefan Frey <ste...@we...> Date: Fri Jun 15 17:35:37 2012 +0200 prepared for release 1.7.7 diff --git a/readme.txt b/readme.txt index a1180ee..33de310 100644 --- a/readme.txt +++ b/readme.txt @@ -1,12 +1,18 @@ -Rails release 1.7.6: +Rails release 1.7.7: A new maintenance release for Rails 1.x series -This release fixes one sole bug. +This release fixes several bugs. -Contributors: Erik Vos +Contributors: Erik Vos, Stefan Frey -Bug reported by Antonio Baracca +Bug reported by Are-Harald Brenne, John David Galt -1856: Allowing selling a share just bought by the president. -(According to Steve Thomas rule clarification). \ No newline at end of file +New: +- Added little fun variant 18Lummer + +Lists of bugs fixed: +- Errors in UI after adding a comment at game start +- Fixed failure on reloading a just started game +- 1835: Manual close of Pfalzbahn is possible (to enable closing after token lay only) +- 1835 (and others): Fixed UI issues with token relays on OO-tiles diff --git a/version.number b/version.number index cde0424..60520e3 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.6 +version=1.7.7 # the following string "@DEVELOP@ is replaced by an empty string in the release version # this is done automatically by ant develop=@DEVELOP@ \ No newline at end of file commit bf16424ac310389b5b48fabfc11a86a6f2a93a29 Author: Erik Vos <eri...@xs...> Date: Fri Jun 15 13:48:48 2012 +0200 Fixed failure on reloading a null action list. GameFileIO.replayGame() was not protected against that condition. [IMO the list should have been created empty, not null; EV](cherry picked from commit ee3e580ae2efdb10c28bdfe0565566e39f17491a) diff --git a/rails/util/GameFileIO.java b/rails/util/GameFileIO.java index 16f1991..5ae75a4 100644 --- a/rails/util/GameFileIO.java +++ b/rails/util/GameFileIO.java @@ -224,13 +224,15 @@ public class GameFileIO { gameManager.setReloading(true); int count = -1; - for (PossibleAction action : gameData.actions) { - count++; - if (!gameManager.processOnReload(action)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted", count)); - ReportBuffer.add(LocalText.getText("LoadInterrupted", count)); - break; + if (gameData != null && gameData.actions != null) { + for (PossibleAction action : gameData.actions) { + count++; + if (!gameManager.processOnReload(action)) { + log.error ("Load interrupted"); + DisplayBuffer.add(LocalText.getText("LoadInterrupted", count)); + ReportBuffer.add(LocalText.getText("LoadInterrupted", count)); + break; + } } } commit 3892c7f2d7d9685cc3a1e5b69e4be900fe7bc4e7 Author: Erik Vos <eri...@xs...> Date: Thu Jun 14 15:44:15 2012 +0200 Fix to 1835 (etc.) token relay fix (previous commit). It failed in a typical 1830 Erie case.(cherry picked from commit ce10cb981aa82985380177433571aed4789f75ae) diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index 2252757..f3b6049 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -963,12 +963,14 @@ public class ORUIManager implements DialogOwner { if (stopsToQuery.size() == 2) { Collections.sort(stopsToQuery, new Comparator<Stop>() { public int compare (Stop s1, Stop s2) { - // Home stops on this hex go first. - boolean home1 = ((BaseToken)s1.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); - boolean home2 = ((BaseToken)s2.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); - if (home1 && !home2) { + List<TokenI> tokens; + boolean stop1IsHome = !((tokens = s1.getTokens()).isEmpty()) + && ((BaseToken)tokens.get(0)).getCompany().getHomeHexes().contains(hex); + boolean stop2IsHome = !((tokens = s2.getTokens()).isEmpty()) + && ((BaseToken)tokens.get(0)).getCompany().getHomeHexes().contains(hex); + if (stop1IsHome && !stop2IsHome) { return -1; - } else if (home2 && !home1) { + } else if (stop2IsHome && !stop1IsHome) { return 1; } else { return 0; // Doesn't matter commit 18b22dec3aeaa01d27250baf5b7dc0256c777d64 Author: Erik Vos <eri...@xs...> Date: Wed Jun 13 17:36:00 2012 +0200 Fixes for 1835 Pfalzbahnen. Manual closure made possible for PfB. If two tokens are laid on L6 (BA home) before the first tile, only the BA president will get asked where to put the BA home token. (cherry picked from commit f34c80df8dacc9f6381c2a0c615cec89aade704c) Conflicts: data/1835/CompanyManager.xml diff --git a/data/1835/CompanyManager.xml b/data/1835/CompanyManager.xml index 9f28099..bfdbb7f 100644 --- a/data/1835/CompanyManager.xml +++ b/data/1835/CompanyManager.xml @@ -55,7 +55,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> - <CloseManually/> <!-- If second tile is laid not via special property --> + <CloseManually/> <!-- Workaround, may be needed if one of the tiles is not laid via this special property --> </ClosingConditions> </Company> <Company name="PfB" longname="Pfalzbahnen" type="Private" basePrice="150" revenue="15"> @@ -70,7 +70,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> - <CloseManually/> <!-- If tile is laid not via special property--> + <CloseManually/> <!-- Workaround, may be needed if a tile or token is not laid via this special property --> </ClosingConditions> </Company> <Company name="LD" longname="Leipzig-Dresdner Bahn" type="Private" basePrice="190"> diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index 0224995..2252757 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -937,12 +937,53 @@ public class ORUIManager implements DialogOwner { */ protected void relayBaseTokens (LayTile action) { - MapHex hex = action.getChosenHex(); + final MapHex hex = action.getChosenHex(); TileI newTile = action.getLaidTile(); TileI oldTile = hex.getCurrentTile(); if (!action.isRelayBaseTokens() && !oldTile.relayBaseTokensOnUpgrade()) return; - for (Stop oldStop : hex.getStops()) { + + List<Stop> stopsToQuery = hex.getStops(); + + /* Check which tokens must be relaid, and in which sequence. + * Ideally, the game engine should instruct the UI what to do + * if there is more than one stop and more than one token. + * TODO LayTile does not yet allow that. + * + * For now, the only case that needs special handling is the 1835 BA home hex L6, + * where it it possible to have two tokens laid before even one tile. + * Let's generalise this case to: two stops, both tokened. + * We consider single-slot stops only. + * In fact, all we need to do is + * 1. Sort the stops so that the home company gets queried first, + * 2. Count down the number of free slots per new station, so that full stations are skipped, + * It's already taken care for, that a choice-between-one is handled automatically. + * [EV, jun2012] + */ + if (stopsToQuery.size() == 2) { + Collections.sort(stopsToQuery, new Comparator<Stop>() { + public int compare (Stop s1, Stop s2) { + // Home stops on this hex go first. + boolean home1 = ((BaseToken)s1.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); + boolean home2 = ((BaseToken)s2.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); + if (home1 && !home2) { + return -1; + } else if (home2 && !home1) { + return 1; + } else { + return 0; // Doesn't matter + } + } + }); + } + + // Array to enable counting down the free token slots per new station + int[] freeSlots = new int[1 + newTile.getStations().size()]; + for (Station newStation : newTile.getStations()) { + freeSlots[newStation.getNumber()] = newStation.getBaseSlots(); + } + + for (Stop oldStop : stopsToQuery) { if (oldStop.hasTokens()) { // Assume only 1 token (no exceptions known) PublicCompanyI company = ((BaseToken)oldStop.getTokens().get(0)).getCompany(); @@ -951,7 +992,7 @@ public class ORUIManager implements DialogOwner { Map<String, Integer> promptToCityMap = new HashMap<String, Integer>(); String prompt; for (Station newStation : newTile.getStations()) { - if (newStation.getBaseSlots() > 0) { + if (newStation.getBaseSlots() > 0 && freeSlots[newStation.getNumber()] > 0) { prompt = LocalText.getText("SelectStationForTokenOption", newStation.getNumber(), hex.getConnectionString( @@ -987,8 +1028,10 @@ public class ORUIManager implements DialogOwner { prompts.toArray(), prompts.get(0)); if (selected == null) return; action.addRelayBaseToken(company.getName(), promptToCityMap.get(selected)); + --freeSlots[promptToCityMap.get(selected)]; } else { - action.addRelayBaseToken(company.getName(), promptToCityMap.get(prompts.toArray() [0])); + action.addRelayBaseToken(company.getName(), promptToCityMap.get(prompts.toArray()[0])); + --freeSlots[promptToCityMap.get(prompts.toArray()[0])]; } } } |
From: Stefan F. <ste...@us...> - 2012-06-15 15:44:39
|
Tag 'v1.7.7' created by Stefan Frey <ste...@we...> at 2012-06-15 15:43 +0000 version 1.7.7 Changes since v1.7.6-7: --- 0 files changed --- |
From: Erik V. <ev...@us...> - 2012-06-15 13:43:24
|
rails/util/GameFileIO.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) New commits: commit ee3e580ae2efdb10c28bdfe0565566e39f17491a Author: Erik Vos <eri...@xs...> Date: Fri Jun 15 13:48:48 2012 +0200 Fixed failure on reloading a null action list. GameFileIO.replayGame() was not protected against that condition. [IMO the list should have been created empty, not null; EV] diff --git a/rails/util/GameFileIO.java b/rails/util/GameFileIO.java index ec682df..cfb6ef3 100644 --- a/rails/util/GameFileIO.java +++ b/rails/util/GameFileIO.java @@ -219,13 +219,15 @@ public class GameFileIO { gameManager.setReloading(true); int count = -1; - for (PossibleAction action : gameData.actions) { - count++; - if (!gameManager.processOnReload(action)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted", count)); - ReportBuffer.add(LocalText.getText("LoadInterrupted", count)); - break; + if (gameData != null && gameData.actions != null) { + for (PossibleAction action : gameData.actions) { + count++; + if (!gameManager.processOnReload(action)) { + log.error ("Load interrupted"); + DisplayBuffer.add(LocalText.getText("LoadInterrupted", count)); + ReportBuffer.add(LocalText.getText("LoadInterrupted", count)); + break; + } } } |
From: Stefan F. <ste...@us...> - 2012-06-14 15:57:06
|
rails/game/ReportBuffer.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) New commits: commit 1686fd33004bbef7c25eeabab96e649f8d1849f8 Author: Stefan Frey <ste...@we...> Date: Thu Jun 14 17:56:46 2012 +0200 fixed error if a comment is added at the start of the game. Reported by Are-Harald Brenne diff --git a/rails/game/ReportBuffer.java b/rails/game/ReportBuffer.java index fa3074e..e95eebf 100644 --- a/rails/game/ReportBuffer.java +++ b/rails/game/ReportBuffer.java @@ -326,7 +326,12 @@ public final class ReportBuffer { // comments first if (comment != null) { s.append("<span style='color:green;font-size:80%;font-style:italic;'>"); - s.append(item.player.getName() + " says: ' "); + // at gamestart no player is defined, this is a bug-fix + if (item.player == null) { + s.append("'"); + } else { + s.append(item.player.getName() + " says: '"); + } s.append(comment + "'" + NEWLINE_STRING); s.append("</span>"); } |
From: Erik V. <ev...@us...> - 2012-06-14 13:47:39
|
rails/ui/swing/ORUIManager.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) New commits: commit ce10cb981aa82985380177433571aed4789f75ae Author: Erik Vos <eri...@xs...> Date: Thu Jun 14 15:44:15 2012 +0200 Fix to 1835 (etc.) token relay fix (previous commit). It failed in a typical 1830 Erie case. diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index 2252757..f3b6049 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -963,12 +963,14 @@ public class ORUIManager implements DialogOwner { if (stopsToQuery.size() == 2) { Collections.sort(stopsToQuery, new Comparator<Stop>() { public int compare (Stop s1, Stop s2) { - // Home stops on this hex go first. - boolean home1 = ((BaseToken)s1.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); - boolean home2 = ((BaseToken)s2.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); - if (home1 && !home2) { + List<TokenI> tokens; + boolean stop1IsHome = !((tokens = s1.getTokens()).isEmpty()) + && ((BaseToken)tokens.get(0)).getCompany().getHomeHexes().contains(hex); + boolean stop2IsHome = !((tokens = s2.getTokens()).isEmpty()) + && ((BaseToken)tokens.get(0)).getCompany().getHomeHexes().contains(hex); + if (stop1IsHome && !stop2IsHome) { return -1; - } else if (home2 && !home1) { + } else if (stop2IsHome && !stop1IsHome) { return 1; } else { return 0; // Doesn't matter |
From: Erik V. <ev...@us...> - 2012-06-13 22:32:31
|
data/1835/CompanyManager.xml | 3 +- rails/ui/swing/ORUIManager.java | 51 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 5 deletions(-) New commits: commit f34c80df8dacc9f6381c2a0c615cec89aade704c Author: Erik Vos <eri...@xs...> Date: Wed Jun 13 17:36:00 2012 +0200 Fixes for 1835 Pfalzbahnen. Manual closure made possible for PfB. If two tokens are laid on L6 (BA home) before the first tile, only the BA president will get asked where to put the BA home token. diff --git a/data/1835/CompanyManager.xml b/data/1835/CompanyManager.xml index 4e05202..b7e893f 100644 --- a/data/1835/CompanyManager.xml +++ b/data/1835/CompanyManager.xml @@ -55,7 +55,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> - <CloseManually/> <!-- If second tile is laid not via special property --> + <CloseManually/> <!-- Workaround, may be needed if one of the tiles is not laid via this special property --> </ClosingConditions> </Company> <Company name="PfB" longname="Pfalzbahnen" type="Private" basePrice="150" revenue="15"> @@ -70,6 +70,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> + <CloseManually/> <!-- Workaround, may be needed if a tile or token is not laid via this special property --> </ClosingConditions> </Company> <Company name="LD" longname="Leipzig-Dresdner Bahn" type="Private" basePrice="190"> diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index 0224995..2252757 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -937,12 +937,53 @@ public class ORUIManager implements DialogOwner { */ protected void relayBaseTokens (LayTile action) { - MapHex hex = action.getChosenHex(); + final MapHex hex = action.getChosenHex(); TileI newTile = action.getLaidTile(); TileI oldTile = hex.getCurrentTile(); if (!action.isRelayBaseTokens() && !oldTile.relayBaseTokensOnUpgrade()) return; - for (Stop oldStop : hex.getStops()) { + + List<Stop> stopsToQuery = hex.getStops(); + + /* Check which tokens must be relaid, and in which sequence. + * Ideally, the game engine should instruct the UI what to do + * if there is more than one stop and more than one token. + * TODO LayTile does not yet allow that. + * + * For now, the only case that needs special handling is the 1835 BA home hex L6, + * where it it possible to have two tokens laid before even one tile. + * Let's generalise this case to: two stops, both tokened. + * We consider single-slot stops only. + * In fact, all we need to do is + * 1. Sort the stops so that the home company gets queried first, + * 2. Count down the number of free slots per new station, so that full stations are skipped, + * It's already taken care for, that a choice-between-one is handled automatically. + * [EV, jun2012] + */ + if (stopsToQuery.size() == 2) { + Collections.sort(stopsToQuery, new Comparator<Stop>() { + public int compare (Stop s1, Stop s2) { + // Home stops on this hex go first. + boolean home1 = ((BaseToken)s1.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); + boolean home2 = ((BaseToken)s2.getTokens().get(0)).getCompany().getHomeHexes().contains(hex); + if (home1 && !home2) { + return -1; + } else if (home2 && !home1) { + return 1; + } else { + return 0; // Doesn't matter + } + } + }); + } + + // Array to enable counting down the free token slots per new station + int[] freeSlots = new int[1 + newTile.getStations().size()]; + for (Station newStation : newTile.getStations()) { + freeSlots[newStation.getNumber()] = newStation.getBaseSlots(); + } + + for (Stop oldStop : stopsToQuery) { if (oldStop.hasTokens()) { // Assume only 1 token (no exceptions known) PublicCompanyI company = ((BaseToken)oldStop.getTokens().get(0)).getCompany(); @@ -951,7 +992,7 @@ public class ORUIManager implements DialogOwner { Map<String, Integer> promptToCityMap = new HashMap<String, Integer>(); String prompt; for (Station newStation : newTile.getStations()) { - if (newStation.getBaseSlots() > 0) { + if (newStation.getBaseSlots() > 0 && freeSlots[newStation.getNumber()] > 0) { prompt = LocalText.getText("SelectStationForTokenOption", newStation.getNumber(), hex.getConnectionString( @@ -987,8 +1028,10 @@ public class ORUIManager implements DialogOwner { prompts.toArray(), prompts.get(0)); if (selected == null) return; action.addRelayBaseToken(company.getName(), promptToCityMap.get(selected)); + --freeSlots[promptToCityMap.get(selected)]; } else { - action.addRelayBaseToken(company.getName(), promptToCityMap.get(prompts.toArray() [0])); + action.addRelayBaseToken(company.getName(), promptToCityMap.get(prompts.toArray()[0])); + --freeSlots[promptToCityMap.get(prompts.toArray()[0])]; } } } |
From: Stefan F. <ste...@us...> - 2012-06-13 17:52:44
|
src/rails/algorithms/RevenueBonusTemplate.java | 4 src/rails/algorithms/RevenueManager.java | 12 src/rails/common/parser/ComponentManager.java | 16 src/rails/common/parser/ConfigurableComponent.java | 37 src/rails/common/parser/ConfigurableComponentI.java | 37 src/rails/common/parser/GameFileParser.java | 8 src/rails/game/AbstractRound.java | 545 ----------- src/rails/game/Bank.java | 6 src/rails/game/BonusToken.java | 4 src/rails/game/Company.java | 4 src/rails/game/CompanyManager.java | 14 src/rails/game/CompanyManagerI.java | 70 - src/rails/game/CompanyType.java | 2 src/rails/game/EndOfGameRound.java | 2 src/rails/game/Game.java | 2 src/rails/game/GameManager.java | 10 src/rails/game/MapHex.java | 4 src/rails/game/MapManager.java | 4 src/rails/game/OperatingRound.java | 2 src/rails/game/Phase.java | 4 src/rails/game/PhaseManager.java | 4 src/rails/game/PlayerManager.java | 4 src/rails/game/PrivateCompany.java | 2 src/rails/game/Round.java | 543 ++++++++++ src/rails/game/StartItem.java | 4 src/rails/game/StartRound.java | 2 src/rails/game/StockMarket.java | 6 src/rails/game/StockRound.java | 2 src/rails/game/SwitchableUIRound.java | 2 src/rails/game/TileManager.java | 4 src/rails/game/TrainManager.java | 6 src/rails/game/TrainType.java | 2 src/rails/game/action/BuyCertificate.java | 2 src/rails/game/action/BuyTrain.java | 4 src/rails/game/action/MergeCompanies.java | 2 src/rails/game/action/PossibleAction.java | 2 src/rails/game/action/ReachDestinations.java | 4 src/rails/game/action/SellShares.java | 2 src/rails/game/specific/_1835/FoldIntoPrussian.java | 2 src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java | 4 src/rails/game/specific/_18AL/NamedTrainToken.java | 4 src/rails/game/specific/_18EU/StartCompany_18EU.java | 2 src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java | 4 src/rails/ui/swing/ORPanel.java | 6 src/test/GameTestServlet.java | 4 src/test/StockMarketTestServlet.java | 4 src/test/StockTest.java | 4 47 files changed, 660 insertions(+), 758 deletions(-) New commits: commit 7286b3efe40f2c6303b72c84a0740c12d6b57d6f Author: Stefan Frey <ste...@we...> Date: Wed Jun 13 19:51:16 2012 +0200 renamed ConfigurableCompenentI to ConfigurableComponent diff --git a/src/rails/algorithms/RevenueBonusTemplate.java b/src/rails/algorithms/RevenueBonusTemplate.java index c4ce053..69b535f 100644 --- a/src/rails/algorithms/RevenueBonusTemplate.java +++ b/src/rails/algorithms/RevenueBonusTemplate.java @@ -6,7 +6,7 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; @@ -21,7 +21,7 @@ import rails.game.TrainType; * will be converted to a true RevenueBonus object during each revenue calculation * @author freystef */ -public final class RevenueBonusTemplate implements ConfigurableComponentI { +public final class RevenueBonusTemplate implements ConfigurableComponent { 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 c367678..0c14e5d 100644 --- a/src/rails/algorithms/RevenueManager.java +++ b/src/rails/algorithms/RevenueManager.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; @@ -27,12 +27,12 @@ import rails.game.state.Item; * */ -public final class RevenueManager extends AbstractItem implements ConfigurableComponentI { +public final class RevenueManager extends AbstractItem implements ConfigurableComponent { protected static Logger log = LoggerFactory.getLogger(RevenueManager.class.getPackage().getName()); - private final HashSet<ConfigurableComponentI> configurableModifiers = new HashSet<ConfigurableComponentI>(); + private final HashSet<ConfigurableComponent> configurableModifiers = new HashSet<ConfigurableComponent>(); private final ArrayListState<NetworkGraphModifier> graphModifiers = ArrayListState.create(); private final ArrayListState<RevenueStaticModifier> staticModifiers = ArrayListState.create(); @@ -86,8 +86,8 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo throw new ConfigurationException(LocalText.getText( "ClassIsNotAModifier", className)); } - if (isModifier && modifier instanceof ConfigurableComponentI) { - configurableModifiers.add((ConfigurableComponentI)modifier); + if (isModifier && modifier instanceof ConfigurableComponent) { + configurableModifiers.add((ConfigurableComponent)modifier); } } } @@ -104,7 +104,7 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo public void finishConfiguration(GameManager parent) throws ConfigurationException { - for (ConfigurableComponentI modifier:configurableModifiers) { + for (ConfigurableComponent modifier:configurableModifiers) { modifier.finishConfiguration(parent); } } diff --git a/src/rails/common/parser/ComponentManager.java b/src/rails/common/parser/ComponentManager.java index ffb19ff..daa7f30 100644 --- a/src/rails/common/parser/ComponentManager.java +++ b/src/rails/common/parser/ComponentManager.java @@ -25,8 +25,8 @@ public class ComponentManager { protected Logger log = LoggerFactory.getLogger(ComponentManager.class.getPackage().getName()); protected List<String> directories = new ArrayList<String>(); - private Map<String, ConfigurableComponentI> mComponentMap = - new HashMap<String, ConfigurableComponentI>(); + private Map<String, ConfigurableComponent> mComponentMap = + new HashMap<String, ConfigurableComponent>(); public ComponentManager(Context context, String gameName, Tag tag, Map<String, String> gameOptions) throws ConfigurationException { @@ -64,13 +64,13 @@ public class ComponentManager { } // Now construct the component - ConfigurableComponentI component; + ConfigurableComponent component; try { - Class<? extends ConfigurableComponentI> compClass; + Class<? extends ConfigurableComponent> compClass; compClass = Class.forName(clazz).asSubclass( - ConfigurableComponentI.class); - Constructor<? extends ConfigurableComponentI> compCons = + ConfigurableComponent.class); + Constructor<? extends ConfigurableComponent> compCons = compClass.getConstructor(new Class[0]); component = compCons.newInstance(new Object[0]); } catch (Exception ex) { @@ -110,8 +110,8 @@ public class ComponentManager { * @param componentName the of the component sought. * @return the component sought, or null if it has not been configured. */ - public ConfigurableComponentI findComponent(String componentName) throws ConfigurationException { - ConfigurableComponentI comp = mComponentMap.get(componentName); + public ConfigurableComponent findComponent(String componentName) throws ConfigurationException { + ConfigurableComponent 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 new file mode 100644 index 0000000..02e67f1 --- /dev/null +++ b/src/rails/common/parser/ConfigurableComponent.java @@ -0,0 +1,37 @@ +/* $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/ConfigurableComponentI.java b/src/rails/common/parser/ConfigurableComponentI.java deleted file mode 100644 index c0741f2..0000000 --- a/src/rails/common/parser/ConfigurableComponentI.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 ConfigurableComponentI { - - /** - * 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/game/Bank.java b/src/rails/game/Bank.java index fac4fe1..392c62c 100644 --- a/src/rails/game/Bank.java +++ b/src/rails/game/Bank.java @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; import rails.common.parser.Config; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.model.CashMoneyModel; @@ -18,7 +18,7 @@ import rails.game.state.BooleanState; import rails.game.state.Item; import rails.util.*; -public class Bank extends AbstractItem implements CashOwner, ConfigurableComponentI { +public class Bank extends AbstractItem implements CashOwner, ConfigurableComponent { private static Bank instance = null; @@ -81,7 +81,7 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { diff --git a/src/rails/game/BonusToken.java b/src/rails/game/BonusToken.java index 9c8f871..acfcfe7 100644 --- a/src/rails/game/BonusToken.java +++ b/src/rails/game/BonusToken.java @@ -1,6 +1,6 @@ package rails.game; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.Item; @@ -15,7 +15,7 @@ import rails.util.Util; * @author Erik Vos */ -public final class BonusToken extends Token implements Closeable, ConfigurableComponentI { +public final class BonusToken extends Token implements Closeable, ConfigurableComponent { private int value; private String name; diff --git a/src/rails/game/Company.java b/src/rails/game/Company.java index 58bc80f..04f9658 100644 --- a/src/rails/game/Company.java +++ b/src/rails/game/Company.java @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.special.SpecialProperty; @@ -17,7 +17,7 @@ import rails.game.state.Item; import rails.game.state.PortfolioList; import rails.util.Util; -public abstract class Company extends AbstractItem implements ConfigurableComponentI, +public abstract class Company extends AbstractItem implements ConfigurableComponent, Cloneable, Comparable<Company> { /** The name of the XML tag used to configure a company. */ diff --git a/src/rails/game/CompanyManager.java b/src/rails/game/CompanyManager.java index 0adc9f1..399e514 100644 --- a/src/rails/game/CompanyManager.java +++ b/src/rails/game/CompanyManager.java @@ -9,12 +9,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; -public class CompanyManager extends AbstractItem implements ConfigurableComponentI { +public class CompanyManager extends AbstractItem implements ConfigurableComponent { /** * This is the name by which the CompanyManager should be registered with @@ -71,7 +71,7 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen public CompanyManager() { } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#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 dad9339..cae1e49 100644 --- a/src/rails/game/CompanyType.java +++ b/src/rails/game/CompanyType.java @@ -63,7 +63,7 @@ public class CompanyType extends AbstractItem { } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { //No longer needed. diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index 1b9bf81..2ba7b72 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -27,7 +27,7 @@ import rails.util.Util; * This class manages the playing rounds by supervising all implementations of * Round. Currently everything is hardcoded à la 1830. */ -public class GameManager extends AbstractItem implements ConfigurableComponentI { +public class GameManager extends AbstractItem implements ConfigurableComponent { /** Version ID of the Save file header, as written in save() */ private static final long saveFileHeaderVersionID = 3L; /** diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 71f758e..e338c10 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -59,7 +59,7 @@ import rails.util.*; */ // FIXME: MapHex was previous a model -public class MapHex extends AbstractItem implements PortfolioHolder, ConfigurableComponentI, +public class MapHex extends AbstractItem implements PortfolioHolder, ConfigurableComponent, StationHolder { private static final String[] ewOrNames = @@ -193,7 +193,7 @@ StationHolder { } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { Pattern namePattern = Pattern.compile("(\\D+?)(-?\\d+)"); diff --git a/src/rails/game/MapManager.java b/src/rails/game/MapManager.java index f8f6d19..de07282 100644 --- a/src/rails/game/MapManager.java +++ b/src/rails/game/MapManager.java @@ -17,7 +17,7 @@ import rails.util.Util; /** * MapManager configures the map layout from XML */ -public class MapManager extends AbstractItem implements ConfigurableComponentI { +public class MapManager extends AbstractItem implements ConfigurableComponent { private String mapUIClassName = null; @@ -68,7 +68,7 @@ public class MapManager extends AbstractItem implements ConfigurableComponentI { } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { String attr = tag.getAttributeAsString("tileOrientation"); diff --git a/src/rails/game/Phase.java b/src/rails/game/Phase.java index 1b20e8d..7857bf7 100644 --- a/src/rails/game/Phase.java +++ b/src/rails/game/Phase.java @@ -10,13 +10,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.Owner; import rails.util.Util; -public class Phase implements ConfigurableComponentI { +public class Phase implements ConfigurableComponent { protected int index; diff --git a/src/rails/game/PhaseManager.java b/src/rails/game/PhaseManager.java index 2b80119..0b2c1a0 100644 --- a/src/rails/game/PhaseManager.java +++ b/src/rails/game/PhaseManager.java @@ -5,7 +5,7 @@ import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; @@ -14,7 +14,7 @@ import rails.game.state.Item; import rails.game.state.Owner; import rails.game.state.State; -public class PhaseManager extends AbstractItem implements ConfigurableComponentI { +public class PhaseManager extends AbstractItem implements ConfigurableComponent { protected ArrayList<Phase> phaseList; protected HashMap<String, Phase> phaseMap; diff --git a/src/rails/game/PlayerManager.java b/src/rails/game/PlayerManager.java index ce1e653..a7329a2 100644 --- a/src/rails/game/PlayerManager.java +++ b/src/rails/game/PlayerManager.java @@ -3,13 +3,13 @@ package rails.game; import java.util.*; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.model.MoneyModel; import rails.game.state.AbstractItem; -public class PlayerManager extends AbstractItem implements ConfigurableComponentI { +public class PlayerManager extends AbstractItem implements ConfigurableComponent { private int numberOfPlayers; private List<Player> players; diff --git a/src/rails/game/PrivateCompany.java b/src/rails/game/PrivateCompany.java index 0d7aebe..87b47d6 100644 --- a/src/rails/game/PrivateCompany.java +++ b/src/rails/game/PrivateCompany.java @@ -93,7 +93,7 @@ public class PrivateCompany extends Company implements Ownable<PrivateCompany>, } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ @Override public void configureFromXML(Tag tag) throws ConfigurationException { diff --git a/src/rails/game/StockMarket.java b/src/rails/game/StockMarket.java index 72f09b3..d8a4c08 100644 --- a/src/rails/game/StockMarket.java +++ b/src/rails/game/StockMarket.java @@ -5,14 +5,14 @@ import java.util.HashMap; import java.util.List; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; import rails.game.state.BooleanState; import rails.game.state.Item; -public class StockMarket extends AbstractItem implements ConfigurableComponentI { +public class StockMarket extends AbstractItem implements ConfigurableComponent { /** * This is the name by which the CompanyManager should be registered with @@ -62,7 +62,7 @@ public class StockMarket extends AbstractItem implements ConfigurableComponentI /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { diff --git a/src/rails/game/TileManager.java b/src/rails/game/TileManager.java index 6c68fab..c8e9465 100644 --- a/src/rails/game/TileManager.java +++ b/src/rails/game/TileManager.java @@ -16,7 +16,7 @@ import rails.game.Stop.Type; import rails.game.state.AbstractItem; import rails.util.Util; -public class TileManager extends AbstractItem implements ConfigurableComponentI { +public class TileManager extends AbstractItem implements ConfigurableComponent { protected Map<Integer, Tile> tileMap = new HashMap<Integer, Tile>(); protected List<Integer> tileIds = new ArrayList<Integer>(); @@ -40,7 +40,7 @@ public class TileManager extends AbstractItem implements ConfigurableComponentI } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tileSetTop) throws ConfigurationException { /* diff --git a/src/rails/game/TrainManager.java b/src/rails/game/TrainManager.java index 3b5bfc2..3138b08 100644 --- a/src/rails/game/TrainManager.java +++ b/src/rails/game/TrainManager.java @@ -11,7 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.model.PortfolioModel; @@ -21,7 +21,7 @@ import rails.game.state.IntegerState; import rails.game.state.Item; import rails.game.state.Owner; -public class TrainManager extends AbstractItem implements ConfigurableComponentI { +public class TrainManager extends AbstractItem implements ConfigurableComponent { // Static attributes protected final List<TrainType> lTrainTypes = new ArrayList<TrainType>(); @@ -83,7 +83,7 @@ public class TrainManager extends AbstractItem implements ConfigurableComponentI public TrainManager() { } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { diff --git a/src/rails/game/TrainType.java b/src/rails/game/TrainType.java index a9932cc..eb4be47 100644 --- a/src/rails/game/TrainType.java +++ b/src/rails/game/TrainType.java @@ -54,7 +54,7 @@ public class TrainType implements Cloneable { } /** - * @see rails.common.parser.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element) + * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { diff --git a/src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java b/src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java index 9471a5e..6f6bd83 100644 --- a/src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java +++ b/src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java @@ -10,14 +10,14 @@ import rails.algorithms.RevenueBonus; import rails.algorithms.RevenueDynamicModifier; import rails.algorithms.RevenueStaticModifier; import rails.algorithms.RevenueTrainRun; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; import rails.game.MapHex; import rails.game.Train; -public class NamedTrainRevenueModifier implements RevenueStaticModifier, RevenueDynamicModifier, ConfigurableComponentI { +public class NamedTrainRevenueModifier implements RevenueStaticModifier, RevenueDynamicModifier, ConfigurableComponent { private boolean dynamic; private List<RevenueBonus> bonuses; diff --git a/src/rails/game/specific/_18AL/NamedTrainToken.java b/src/rails/game/specific/_18AL/NamedTrainToken.java index f91f343..84c8720 100644 --- a/src/rails/game/specific/_18AL/NamedTrainToken.java +++ b/src/rails/game/specific/_18AL/NamedTrainToken.java @@ -10,14 +10,14 @@ import org.slf4j.LoggerFactory; //import rails.algorithms.RevenueBonus; //import rails.algorithms.RevenueManager; //import rails.algorithms.RevenueStaticModifier; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.*; import rails.game.state.Item; import rails.util.Util; -public class NamedTrainToken extends Token implements ConfigurableComponentI /*, RevenueStaticModifier */ { +public class NamedTrainToken extends Token implements ConfigurableComponent /*, RevenueStaticModifier */ { protected static Logger log = LoggerFactory.getLogger(NamedTrainToken.class.getPackage().getName()); diff --git a/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java b/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java index 4258d37..e75463c 100644 --- a/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java +++ b/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java @@ -10,12 +10,12 @@ import rails.algorithms.NetworkVertex; import rails.algorithms.RevenueAdapter; import rails.algorithms.RevenueBonus; import rails.algorithms.RevenueStaticModifier; -import rails.common.parser.ConfigurableComponentI; +import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; -public class RuhrRevenueModifier implements RevenueStaticModifier, ConfigurableComponentI { +public class RuhrRevenueModifier implements RevenueStaticModifier, ConfigurableComponent { protected static Logger log = LoggerFactory.getLogger(RuhrRevenueModifier.class.getPackage().getName()); commit 5856b28b19d275b4255d1c090abfbcabeedd04d6 Author: Stefan Frey <ste...@we...> Date: Wed Jun 13 19:49:39 2012 +0200 removed CompanyManagerI interface diff --git a/src/rails/common/parser/GameFileParser.java b/src/rails/common/parser/GameFileParser.java index 0462a7a..528892e 100644 --- a/src/rails/common/parser/GameFileParser.java +++ b/src/rails/common/parser/GameFileParser.java @@ -7,7 +7,7 @@ import rails.common.DisplayBuffer; import rails.common.LocalText; import rails.common.parser.ComponentManager; import rails.game.Bank; -import rails.game.CompanyManagerI; +import rails.game.CompanyManager; import rails.game.GameManager; import rails.game.MapManager; import rails.game.PhaseManager; @@ -24,7 +24,7 @@ public class GameFileParser extends XMLParser { private ComponentManager componentManager; private GameManager gameManager; - private CompanyManagerI companyManager; + private CompanyManager companyManager; private PlayerManager playerManager; private PhaseManager phaseManager; private TrainManager trainManager; @@ -47,7 +47,7 @@ public class GameFileParser extends XMLParser { playerManager = (PlayerManager) componentManager.findComponent("PlayerManager"); bank = (Bank) componentManager.findComponent("Bank"); - companyManager = (CompanyManagerI) componentManager.findComponent(CompanyManagerI.COMPONENT_NAME); + companyManager = (CompanyManager) componentManager.findComponent(CompanyManager.COMPONENT_NAME); stockMarket = (StockMarket) componentManager.findComponent(StockMarket.COMPONENT_NAME); gameManager = (GameManager) componentManager.findComponent("GameManager"); phaseManager = (PhaseManager) componentManager.findComponent("PhaseManager"); @@ -82,7 +82,7 @@ public class GameFileParser extends XMLParser { /** * @return the companyManager */ - public CompanyManagerI getCompanyManager() { + public CompanyManager getCompanyManager() { return companyManager; } diff --git a/src/rails/game/CompanyManager.java b/src/rails/game/CompanyManager.java index f581c81..0adc9f1 100644 --- a/src/rails/game/CompanyManager.java +++ b/src/rails/game/CompanyManager.java @@ -14,7 +14,13 @@ import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; -public class CompanyManager extends AbstractItem implements CompanyManagerI, ConfigurableComponentI { +public class CompanyManager extends AbstractItem implements ConfigurableComponentI { + + /** + * This is the name by which the CompanyManager should be registered with + * the ComponentManager. + */ + public static final String COMPONENT_NAME = "CompanyManager"; /** A List with all private companies */ private List<PrivateCompany> lPrivateCompanies = @@ -223,7 +229,7 @@ public class CompanyManager extends AbstractItem implements CompanyManagerI, Con } } /** - * @see rails.game.CompanyManagerI#getCompany(java.lang.String) + * @see rails.game.CompanyManager#getCompany(java.lang.String) * */ public PrivateCompany getPrivateCompany(String name) { diff --git a/src/rails/game/CompanyManagerI.java b/src/rails/game/CompanyManagerI.java deleted file mode 100644 index e3c927b..0000000 --- a/src/rails/game/CompanyManagerI.java +++ /dev/null @@ -1,70 +0,0 @@ -package rails.game; - -import java.util.List; - -import rails.common.parser.ConfigurableComponentI; - -/** - * Interface for CompanyManager objects. A company manager is a factory which - * vends Company objects. - */ -public interface CompanyManagerI extends ConfigurableComponentI { - - /** - * This is the name by which the CompanyManager should be registered with - * the ComponentManager. - */ - static final String COMPONENT_NAME = "CompanyManager"; - - /** - * Returns the Private Company identified by the supplied name. - * - * @param name the name of the company sought - * @return the Private Company with the supplied name - */ - PrivateCompany getPrivateCompany(String name); - - /** - * Returns the Public Company identified by the supplied name. - * - * @param name the name of the company sought - * @return the Public Company with the supplied name - */ - PublicCompany getPublicCompany(String name); - - /** - * Gives a list of all the registered Private Companies. - * - * @return a list of all the registered Private Companies - */ - List<PrivateCompany> getAllPrivateCompanies(); - - /** - * Gives a list of all the registered Private Companies. - * - * @return a list of all the registered Private Companies - */ - List<PublicCompany> getAllPublicCompanies(); - - /** - * Find a company by type and name - * - * @param type The name of the CompanyType - * @param name The name of the Company - * @return The company object, or null if not found. - */ - public Company getCompany(String type, String name); - - public String checkAlias (String alias); - public String checkAliasInCertId (String certId); - - public List<CompanyType> getCompanyTypes(); - - public void closeAllPrivates(); - - public List<PrivateCompany> getPrivatesOwnedByPlayers(); - - public StartPacket getStartPacket (int index); - public StartPacket getStartPacket (String name); - -} diff --git a/src/rails/game/Game.java b/src/rails/game/Game.java index c04e148..961c7b2 100644 --- a/src/rails/game/Game.java +++ b/src/rails/game/Game.java @@ -19,7 +19,7 @@ public class Game { /** The component Manager */ protected GameManager gameManager; - protected CompanyManagerI companyManager; + protected CompanyManager companyManager; protected PlayerManager playerManager; protected PhaseManager phaseManager; protected TrainManager trainManager; diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index 8a4fec5..1b9bf81 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -51,7 +51,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponentI protected String orWindowClassName = GuiDef.getDefaultClassName(GuiDef.ClassName.OR_WINDOW); protected PlayerManager playerManager; - protected CompanyManagerI companyManager; + protected CompanyManager companyManager; protected PhaseManager phaseManager; protected TrainManager trainManager; protected StockMarket stockMarket; @@ -531,11 +531,11 @@ public class GameManager extends AbstractItem implements ConfigurableComponentI } /* (non-Javadoc) - * @see rails.game.GameManager#startGame(rails.game.PlayerManager, rails.game.CompanyManagerI, rails.game.PhaseManager) + * @see rails.game.GameManager#startGame(rails.game.PlayerManager, rails.game.CompanyManager, rails.game.PhaseManager) */ public void init(String gameName, PlayerManager playerManager, - CompanyManagerI companyManager, + CompanyManager companyManager, PhaseManager phaseManager, TrainManager trainManager, StockMarket stockMarket, @@ -637,7 +637,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponentI /* (non-Javadoc) * @see rails.game.GameManager#getCompanyManager() */ - public CompanyManagerI getCompanyManager() { + public CompanyManager getCompanyManager() { return companyManager; } diff --git a/src/rails/game/Round.java b/src/rails/game/Round.java index a6378ea..61cb531 100644 --- a/src/rails/game/Round.java +++ b/src/rails/game/Round.java @@ -33,7 +33,7 @@ public abstract class Round extends AbstractItem { LoggerFactory.getLogger(Round.class.getPackage().getName()); protected GameManager gameManager = null; - protected CompanyManagerI companyManager = null; + protected CompanyManager companyManager = null; protected PlayerManager playerManager = null; protected Bank bank = null; protected PortfolioModel ipo = null; diff --git a/src/rails/game/StartItem.java b/src/rails/game/StartItem.java index ed9a83d..65987cd 100644 --- a/src/rails/game/StartItem.java +++ b/src/rails/game/StartItem.java @@ -71,7 +71,7 @@ public class StartItem extends AbstractItem { // Static properties //protected static Portfolio ipo; //protected static Portfolio unavailable; - //protected static CompanyManagerI compMgr; + //protected static CompanyManager compMgr; //protected static int nextIndex = 0; protected static Map<String, StartItem> startItemMap; @@ -161,7 +161,7 @@ public class StartItem extends AbstractItem { PortfolioModel ipo = gameManager.getBank().getIpo(); PortfolioModel unavailable = gameManager.getBank().getUnavailable(); - CompanyManagerI compMgr = gameManager.getCompanyManager(); + CompanyManager compMgr = gameManager.getCompanyManager(); Company company = compMgr.getCompany(type, name); if (company instanceof PrivateCompany) { diff --git a/src/rails/game/action/BuyCertificate.java b/src/rails/game/action/BuyCertificate.java index a906b62..6ddd43d 100644 --- a/src/rails/game/action/BuyCertificate.java +++ b/src/rails/game/action/BuyCertificate.java @@ -149,7 +149,7 @@ public class BuyCertificate extends PossibleAction { GameManager gameManager = GameManager.getInstance(); /* Check for aliases (old company names) */ - CompanyManagerI companyManager = gameManager.getCompanyManager(); + CompanyManager companyManager = gameManager.getCompanyManager(); companyName = companyManager.checkAlias (companyName); if (certUniqueId != null) { diff --git a/src/rails/game/action/BuyTrain.java b/src/rails/game/action/BuyTrain.java index 905e375..f41090b 100644 --- a/src/rails/game/action/BuyTrain.java +++ b/src/rails/game/action/BuyTrain.java @@ -11,7 +11,7 @@ import java.util.ArrayList; import java.util.List; import rails.game.Bank; -import rails.game.CompanyManagerI; +import rails.game.CompanyManager; import rails.game.GameManager; import rails.game.Train; import rails.game.TrainManager; @@ -302,7 +302,7 @@ public class BuyTrain extends PossibleORAction { GameManager gameManager = GameManager.getInstance(); TrainManager trainManager = gameManager.getTrainManager(); - CompanyManagerI companyManager = gameManager.getCompanyManager(); + CompanyManager companyManager = gameManager.getCompanyManager(); fromName = companyManager.checkAlias (fromName); diff --git a/src/rails/game/action/MergeCompanies.java b/src/rails/game/action/MergeCompanies.java index e4600e3..fd30b6a 100644 --- a/src/rails/game/action/MergeCompanies.java +++ b/src/rails/game/action/MergeCompanies.java @@ -141,7 +141,7 @@ public class MergeCompanies extends PossibleAction { selectedTargetCompanyName = (String) fields.get("selectedTargetCompanyName", selectedTargetCompanyName); replaceToken = fields.get("replaceToken", replaceToken); - CompanyManagerI cmgr = getCompanyManager(); + CompanyManager cmgr = getCompanyManager(); mergingCompany = cmgr.getPublicCompany(mergingCompanyName); diff --git a/src/rails/game/action/PossibleAction.java b/src/rails/game/action/PossibleAction.java index 4673537..a1c0211 100644 --- a/src/rails/game/action/PossibleAction.java +++ b/src/rails/game/action/PossibleAction.java @@ -106,7 +106,7 @@ public abstract class PossibleAction implements Serializable { return GameManager.getInstance(); } - protected CompanyManagerI getCompanyManager () { + protected CompanyManager getCompanyManager () { return getGameManager().getCompanyManager(); } diff --git a/src/rails/game/action/ReachDestinations.java b/src/rails/game/action/ReachDestinations.java index 8f3c405..be45f55 100644 --- a/src/rails/game/action/ReachDestinations.java +++ b/src/rails/game/action/ReachDestinations.java @@ -5,7 +5,7 @@ import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.List; -import rails.game.CompanyManagerI; +import rails.game.CompanyManager; import rails.game.PublicCompany; import rails.util.Util; @@ -91,7 +91,7 @@ public class ReachDestinations extends PossibleORAction { in.defaultReadObject(); - CompanyManagerI cmgr = getCompanyManager(); + CompanyManager cmgr = getCompanyManager(); possibleCompanies = new ArrayList<PublicCompany>(); if (Util.hasValue(possibleCompanyNames)) { diff --git a/src/rails/game/action/SellShares.java b/src/rails/game/action/SellShares.java index 3ee4222..ceb8588 100644 --- a/src/rails/game/action/SellShares.java +++ b/src/rails/game/action/SellShares.java @@ -124,7 +124,7 @@ public class SellShares extends PossibleAction { in.defaultReadObject(); - CompanyManagerI companyManager = getCompanyManager(); + CompanyManager companyManager = getCompanyManager(); if (Util.hasValue(companyName)) companyName = companyManager.checkAlias(companyName); company = companyManager.getPublicCompany(companyName); diff --git a/src/rails/game/specific/_1835/FoldIntoPrussian.java b/src/rails/game/specific/_1835/FoldIntoPrussian.java index cf85408..6695678 100644 --- a/src/rails/game/specific/_1835/FoldIntoPrussian.java +++ b/src/rails/game/specific/_1835/FoldIntoPrussian.java @@ -91,7 +91,7 @@ public class FoldIntoPrussian extends PossibleAction { in.defaultReadObject(); - CompanyManagerI cmgr = getCompanyManager(); + CompanyManager cmgr = getCompanyManager(); if (foldableCompanyNames != null) { foldableCompanies = new ArrayList<Company>(); for (String name : foldableCompanyNames.split(",")) { diff --git a/src/rails/game/specific/_18EU/StartCompany_18EU.java b/src/rails/game/specific/_18EU/StartCompany_18EU.java index 6527454..1726d61 100644 --- a/src/rails/game/specific/_18EU/StartCompany_18EU.java +++ b/src/rails/game/specific/_18EU/StartCompany_18EU.java @@ -119,7 +119,7 @@ public class StartCompany_18EU extends StartCompany { in.defaultReadObject(); - CompanyManagerI cmgr = getCompanyManager(); + CompanyManager cmgr = getCompanyManager(); if (minorsToMergeNames != null) { minorsToMerge = new ArrayList<PublicCompany>(); for (String name : minorsToMergeNames.split(",")) { diff --git a/src/rails/ui/swing/ORPanel.java b/src/rails/ui/swing/ORPanel.java index 8edcdea..15d0484 100644 --- a/src/rails/ui/swing/ORPanel.java +++ b/src/rails/ui/swing/ORPanel.java @@ -509,7 +509,7 @@ implements ActionListener, KeyListener, RevenueListener { protected void addCompanynfo() { - CompanyManagerI cm = orUIManager.getGameUIManager().getGameManager().getCompanyManager(); + CompanyManager cm = orUIManager.getGameUIManager().getGameManager().getCompanyManager(); List<CompanyType> comps = cm.getCompanyTypes(); JMenu compMenu, menu, item; @@ -604,7 +604,7 @@ implements ActionListener, KeyListener, RevenueListener { } if (revenue_suggest) { - CompanyManagerI cm = orUIManager.getGameUIManager().getGameManager().getCompanyManager(); + CompanyManager cm = orUIManager.getGameUIManager().getGameManager().getCompanyManager(); for (PublicCompany comp : cm.getAllPublicCompanies()) { if (!comp.hasFloated() || comp.isClosed()) continue; JMenuItem item = new JMenuItem(comp.getId()); @@ -626,7 +626,7 @@ implements ActionListener, KeyListener, RevenueListener { mapGraph = NetworkGraphBuilder.optimizeGraph(mapGraph); NetworkGraphBuilder.visualize(mapGraph, "Optimized Map Network"); } else { - CompanyManagerI cm = gm.getCompanyManager(); + CompanyManager cm = gm.getCompanyManager(); PublicCompany company = cm.getPublicCompany(companyName); // // NetworkGraphBuilder nwGraph = NetworkGraphBuilder.create(gm); diff --git a/src/test/GameTestServlet.java b/src/test/GameTestServlet.java index 3c3deaf..764d051 100644 --- a/src/test/GameTestServlet.java +++ b/src/test/GameTestServlet.java @@ -51,7 +51,7 @@ * * private PlayerManager playerManager = null; * - * private CompanyManagerI companyManager = null; + * private CompanyManager companyManager = null; * * private Round currentRound = null; * @@ -505,7 +505,7 @@ * out.append("<table class=bordertable cellspacing=0 cellpadding=0>\n"); * out.append("<tr><th>Company</th><th>Par</th><th>Price</th><th>Cash</th><th>Revenue</th>") * .append("<th>Privates</th><th>IPO</th><th>Pool</th></tr>\n"); - * CompanyManagerI compMgr = Game.getCompanyManager(); iterator = + * CompanyManager compMgr = Game.getCompanyManager(); iterator = * compMgr.getAllPublicCompanies().iterator(); while (iterator.hasNext()) { * company = (PublicCompany) iterator.next(); companyName = company.getName(); * companyNumber = company.getCompanyNumber(); out.append("<tr><td>" + diff --git a/src/test/StockMarketTestServlet.java b/src/test/StockMarketTestServlet.java index f63fc2d..939defe 100644 --- a/src/test/StockMarketTestServlet.java +++ b/src/test/StockMarketTestServlet.java @@ -68,7 +68,7 @@ /* Process the action performed. Note: companies not mentioned yet. */ // iterator = game.getCompanyManager().getAllCompanies().iterator(); /* - * CompanyManagerI compMgr = Game.getCompanyManager(); iterator = + * CompanyManager compMgr = Game.getCompanyManager(); iterator = * compMgr.getAllPublicNames().iterator(); while (iterator.hasNext()) { * //company = (Company) iterator.next(); comp = (Company) * compMgr.getPublicCompany((String) iterator.next()); if (!(comp instanceof @@ -159,7 +159,7 @@ * action=\"http://localhost:8080/18xx/servlet/game.test.StockMarketTestServlet\">\n"); * out.append( "<form method=\"POST\" action=\"" + servletPrefix + * "game.test.StockMarketTestServlet\">\n"); out.append("<table - * cellspacing=\"0\" cellpadding=\"0\">\n"); CompanyManagerI compMgr = + * cellspacing=\"0\" cellpadding=\"0\">\n"); CompanyManager compMgr = * Game.getCompanyManager(); iterator = * compMgr.getAllPublicCompanies().iterator(); while (iterator.hasNext()) { * company = (PublicCompany) iterator.next(); companyName = company.getName(); diff --git a/src/test/StockTest.java b/src/test/StockTest.java index ace4aad..3d53620 100644 --- a/src/test/StockTest.java +++ b/src/test/StockTest.java @@ -43,8 +43,8 @@ * //ComponentManager.configureInstance(elem); * * ComponentManager componentMan = ComponentManager.getInstance(); - * CompanyManagerI companyManager = (CompanyManagerI) componentMan - * .findComponent(CompanyManagerI.COMPONENT_NAME); + * CompanyManager companyManager = (CompanyManager) componentMan + * .findComponent(CompanyManager.COMPONENT_NAME); * * List companies = companyManager.getAllCompanies(); * System.out.println(companies.size() + " companies are registered"); for (int commit 2cc6100e81921f30fba7aa5ecc08ea4d2fb65e30 Author: Stefan Frey <ste...@we...> Date: Wed Jun 13 19:46:52 2012 +0200 Removed Round Interface and renamed AbstractRound to Round diff --git a/src/rails/game/AbstractRound.java b/src/rails/game/AbstractRound.java deleted file mode 100644 index 03fe440..0000000 --- a/src/rails/game/AbstractRound.java +++ /dev/null @@ -1,545 +0,0 @@ -package rails.game; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -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 = - LoggerFactory.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 floa... [truncated message content] |