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-10-17 13:38:44
|
Tag 'v1.7.12' created by Stefan Frey <ste...@we...> at 2012-10-17 08:24 +0000 version 1.7.12 Changes since v1.7.11-2: --- 0 files changed --- |
From: Stefan F. <ste...@us...> - 2012-10-17 08:25:05
|
data/1835/Tiles.xml | 1 rails/game/specific/_1835/GameManager_1835.java | 1 rails/game/specific/_1835/OperatingRound_1835.java | 5 readme.txt | 19 test/data/bugs/1835_PROperates_After5Train.rails |binary test/data/bugs/1835_PROperates_After5Train.report | 1118 +++++++++++++++++++++ tiles/TileDictionary.18t | 4 tiles/TileDictionary.xml | 5 tiles/Tiles.xml | 1 version.number | 2 10 files changed, 1130 insertions(+), 26 deletions(-) New commits: commit 86026ff5f9cb5f35fdbbd8236f25a4c3ae7dcfa7 Author: Stefan Frey <ste...@we...> Date: Wed Oct 17 10:23:36 2012 +0200 prepared for 1.7.12 diff --git a/readme.txt b/readme.txt index 6eecc77..b18bc06 100644 --- a/readme.txt +++ b/readme.txt @@ -1,19 +1,12 @@ -Rails release 1.7.11: +Rails release 1.7.12: A new maintenance release for Rails 1.x series -This release fixes two bugs. +This release fixes a single bug. -Contributors: Erik Vos, Stefan Frey +Contributors: Erik Vos -Bugs reported by Volker Schnell +Bug reported by Volker Schnell -Lists of bugs fixed: -- When buying trains from other companies, include companies that have floated -but do not operate in the current round for any reason. -Example was the PR in 1835. -- 1889: the free tile lay of private C was not offered if the cash position was not exceeding -the (not-applicable) costs of building in the hex - -Further: -- Sorted 1835 game options to make the Options list looks prettier. +1835: after resuming an OR after a PR formation round, a check was missing if the (minor) operating company still exists. +Fix: finish the turn if the operating company is closed at that point. diff --git a/version.number b/version.number index d21edeb..84eade9 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.11 +version=1.7.12 # 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 456d62e5ec6e62652245d8c6de3671c812f0ac94 Author: Stefan Frey <ste...@we...> Date: Wed Oct 17 09:15:14 2012 +0200 added testcase for the previous 1835 bug diff --git a/test/data/bugs/1835_PROperates_After5Train.rails b/test/data/bugs/1835_PROperates_After5Train.rails new file mode 100644 index 0000000..1b7a979 Binary files /dev/null and b/test/data/bugs/1835_PROperates_After5Train.rails differ diff --git a/test/data/bugs/1835_PROperates_After5Train.report b/test/data/bugs/1835_PROperates_After5Train.report new file mode 100644 index 0000000..c4e4049 --- /dev/null +++ b/test/data/bugs/1835_PROperates_After5Train.report @@ -0,0 +1,1118 @@ +GameIs,1835 +PlayerIs,1,Klaus-Jürgen +PlayerIs,2,Jupp +PlayerIs,3,Volker S +PlayerIs,4,Sven K. +PlayerCash,475 +BankHas,10100 +StartOfPhase,2 +BankSizeIs,10100 +StartOfInitialRound +HasPriority,Klaus-Jürgen +BuysItemFor,Sven K.,M2,170 +FloatsWithCash,M2,170 +BuysItemFor,Volker S,M5,80 +FloatsWithCash,M5,80 +BuysItemFor,Jupp,M3,80 +FloatsWithCash,M3,80 +BuysItemFor,Klaus-Jürgen,M1,80 +FloatsWithCash,M1,80 +BuysItemFor,Klaus-Jürgen,M6,80 +FloatsWithCash,M6,80 +BuysItemFor,Jupp,LD,190 +ALSO_GETS,Jupp,PRES_CERT_NAME,SX,20 +BuysItemFor,Volker S,NF,100 +ALSO_GETS,Volker S,CERT_NAME,BY,10 +BuysItemFor,Sven K.,OBB,120 +ALSO_GETS,Sven K.,CERT_NAME,BY,10 +BuysItemFor,Klaus-Jürgen,BB,130 +BuysItemFor,Jupp,PRES_CERT_NAME,BY,20,184 +BuysItemFor,Volker S,PfB,150 +ALSO_GETS,Volker S,CERT_NAME,BY,10 +FloatsWithCash,BY,460 +BuysItemFor,Sven K.,HB,160 +BuysItemFor,Klaus-Jürgen,M4,160 +FloatsWithCash,M4,160 +Has,M1,80 +Has,M2,170 +Has,M3,80 +Has,M4,160 +Has,M5,80 +Has,M6,80 +Has,BY,460 +Has,Klaus-Jürgen,25 +Has,Jupp,21 +Has,Volker S,145 +Has,Sven K.,25 +StartStockRound,1 +HasPriority,Jupp +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BY,IPO,92 +PriceIsPaidTo,92,BY +IS_NOW_PRES_OF,Volker S,BY +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp +PASSES,Volker S + +END_SR,1 +Has,M1,80 +Has,M2,170 +Has,M3,80 +Has,M4,160 +Has,M5,80 +Has,M6,80 +Has,BY,552 +Has,Klaus-Jürgen,25 +Has,Jupp,21 +Has,Volker S,53 +Has,Sven K.,25 +START_OR,1.1 +ReceivesFor,Volker S,5,NF +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Jupp,20,LD +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,201,H2,SE +CompanyDoesNotPayDividend,M1 +BuysTrain,M1,2,IPO,80 +FirstTrainBought,2 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,8,E17,NW +CompanyDoesNotPayDividend,M2 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,6,F14,NW +CompanyDoesNotPayDividend,M3 +BuysTrain,M3,2,IPO,80 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,6,G5,NE +CompanyDoesNotPayDividend,M4 +BuysTrain,M4,2,IPO,80 +BuysTrain,M4,2,IPO,80 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,8,D18,NE +CompanyDoesNotPayDividend,M5 +BuysTrain,M5,2,IPO,80 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,9,B10,NW +CompanyDoesNotPayDividend,M6 +BuysTrain,M6,2,IPO,80 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,201,O15,NW +LaysTileAt,BY,8,O13,NW +CompanyDoesNotPayDividend,BY +PRICE_MOVES_LOG,BY,92,C3,86,B3 +BuysTrain,BY,2,IPO,80 +BuysTrain,BY,2,IPO,80 + +EndOfOperatingRound,1.1 +ORWorthIncrease,Klaus-Jürgen,1.1,25 +ORWorthIncrease,Jupp,1.1,8 +ORWorthIncrease,Volker S,1.1,2 +ORWorthIncrease,Sven K.,1.1,34 +Has,M1,0 +Has,M2,170 +Has,M3,0 +Has,M4,0 +Has,M5,0 +Has,M6,0 +Has,BY,392 +Has,Klaus-Jürgen,50 +Has,Jupp,41 +Has,Volker S,73 +Has,Sven K.,65 +StartStockRound,2 +HasPriority,Sven K. +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp +PASSES,Volker S + +END_SR,2 +Has,M1,0 +Has,M2,170 +Has,M3,0 +Has,M4,0 +Has,M5,0 +Has,M6,0 +Has,BY,392 +Has,Klaus-Jürgen,50 +Has,Jupp,41 +Has,Volker S,73 +Has,Sven K.,65 +START_OR,2.1 +ReceivesFor,Volker S,5,NF +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Jupp,20,LD +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,69,H4,SW +CompanyRevenue,M1,40 +CompanySplits,M1,40 +M1 receives 20 +Payout,Klaus-Jürgen,20,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,8,D16,SE +CompanyDoesNotPayDividend,M2 +BuysTrain,M2,2,IPO,80 +All 2-trains are sold out, 2+2-trains now available + +CompanyOperates,M3,Jupp +LaysTileAt,M3,4,G15,NW +CompanyRevenue,M3,40 +CompanySplits,M3,40 +M3 receives 20 +Payout,Jupp,20,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,3,F4,E +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,8,C19,E +CompanyRevenue,M5,50 +CompanySplits,M5,50 +M5 receives 25 +Payout,Volker S,25,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,6,A11,NW +CompanyRevenue,M6,60 +CompanySplits,M6,60 +M6 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,8,N14,SE +LaysTileAt,BY,5,N12,SW +LAYS_FREE_TOKEN_ON,BY,L14 +PrivateCloses,NF +CompanyRevenue,BY,100 +CompanyPaysOutFull,BY,100 +Payout,Jupp,20,2,10 +Payout,Volker S,30,3,10 +Payout,Sven K.,10,1,10 +PRICE_MOVES_LOG,BY,86,B3,92,C3 +BuysTrain,BY,2+2,IPO,120 +FirstTrainBought,2+2 + +EndOfOperatingRound,2.1 +ORWorthIncrease,Klaus-Jürgen,2.1,105 +ORWorthIncrease,Jupp,2.1,72 +ORWorthIncrease,Volker S,2.1,-7 +ORWorthIncrease,Sven K.,2.1,56 +Has,M1,20 +Has,M2,90 +Has,M3,20 +Has,M4,30 +Has,M5,25 +Has,M6,30 +Has,BY,272 +Has,Klaus-Jürgen,155 +Has,Jupp,101 +Has,Volker S,148 +Has,Sven K.,115 +StartStockRound,3 +HasPriority,Sven K. +BUY_SHARE_LOG,Sven K.,10,BY,IPO,92 +PriceIsPaidTo,92,BY +BUY_SHARE_LOG,Klaus-Jürgen,10,BY,IPO,92 +PriceIsPaidTo,92,BY +BUY_SHARE_LOG,Jupp,10,BY,IPO,92 +PriceIsPaidTo,92,BY +BUY_SHARE_LOG,Volker S,10,BY,IPO,92 +PriceIsPaidTo,92,BY +PASSES,Sven K. +Autopasses,Klaus-Jürgen +SELL_SHARE_LOG,Jupp,10,BY,92 +PRICE_MOVES_LOG,BY,92,C3,88,C4 +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +Autopasses,Volker S +Autopasses,Sven K. +Autopasses,Klaus-Jürgen +SELL_SHARE_LOG,Jupp,10,BY,88 +PRICE_MOVES_LOG,BY,88,C4,86,C5 +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +Autopasses,Volker S +Autopasses,Sven K. +Autopasses,Klaus-Jürgen +SELL_SHARE_LOG,Jupp,10,BY,86 +PRICE_MOVES_LOG,BY,86,C5,82,C6 +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +FloatsWithCash,SX,440 +Autopasses,Volker S +Autopasses,Sven K. +Autopasses,Klaus-Jürgen +PASSES,Jupp + +END_SR,3 +Has,M1,20 +Has,M2,90 +Has,M3,20 +Has,M4,30 +Has,M5,25 +Has,M6,30 +Has,BY,640 +Has,SX,440 +Has,Klaus-Jürgen,63 +Has,Jupp,11 +Has,Volker S,56 +Has,Sven K.,23 +START_OR,3.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Jupp,20,LD +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,8,I5,SW +CompanyRevenue,M1,40 +CompanySplits,M1,40 +M1 receives 20 +Payout,Klaus-Jürgen,20,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAtFor,M2,8,D14,NW,50 +CompanyRevenue,M2,70 +CompanySplits,M2,70 +M2 receives 35 +Payout,Sven K.,35,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,57,H16,NW +CompanyRevenue,M3,40 +CompanySplits,M3,40 +M3 receives 20 +Payout,Jupp,20,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,4,F6,W +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,M5,Volker S +CompanyRevenue,M5,50 +CompanySplits,M5,50 +M5 receives 25 +Payout,Volker S,25,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,58,B12,NW +CompanyRevenue,M6,60 +CompanySplits,M6,60 +M6 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,56,I17,NE +LaysTileAt,SX,202,H20,W +LAYS_TOKEN_ON,SX,H20,40 +CompanyDoesNotPayDividend,SX +PRICE_MOVES_LOG,SX,88,C4,84,B4 +BuysTrain,SX,2+2,IPO,120 +PrivateCloses,LD +BuysTrain,SX,2+2,IPO,120 +BuysTrain,SX,2+2,IPO,120 +All 2+2-trains are sold out, 3-trains now available + +CompanyOperates,BY,Volker S +LaysTileAt,BY,8,K13,SE +LaysTileAt,BY,58,K11,NW +CompanyRevenue,BY,140 +CompanyPaysOutFull,BY,140 +Payout,Volker S,56,4,10 +Payout,Sven K.,28,2,10 +Payout,Klaus-Jürgen,14,1,10 +Payout,BY,42,3,10 +PRICE_MOVES_LOG,BY,82,C6,88,D6 +BuysTrain,BY,3,IPO,180 +FirstTrainBought,3 +StartOfPhase,3 + +EndOfOperatingRound,3.1 +ORWorthIncrease,Klaus-Jürgen,3.1,125 +ORWorthIncrease,Jupp,3.1,-170 +ORWorthIncrease,Volker S,3.1,120 +ORWorthIncrease,Sven K.,3.1,115 +Has,M1,40 +Has,M2,75 +Has,M3,40 +Has,M4,60 +Has,M5,50 +Has,M6,60 +Has,BY,502 +Has,SX,40 +Has,Klaus-Jürgen,182 +Has,Jupp,51 +Has,Volker S,152 +Has,Sven K.,126 +StartStockRound,4 +HasPriority,Volker S +BUY_SHARE_LOG,Volker S,10,BY,Pool,88 +BUY_SHARE_LOG,Sven K.,10,BY,Pool,88 +BUY_SHARE_LOG,Klaus-Jürgen,10,BY,Pool,88 +Autopasses,Jupp +Autopasses,Volker S +Autopasses,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,SX,IPO,88 +PriceIsPaidTo,88,SX +Autopasses,Jupp +Autopasses,Volker S +Autopasses,Sven K. +PASSES,Klaus-Jürgen + +END_SR,4 +PRICE_MOVES_LOG,BY,88,D6,90,D5 +SoldOut,BY,88,D6,90,D5 +Has,M1,40 +Has,M2,75 +Has,M3,40 +Has,M4,60 +Has,M5,50 +Has,M6,60 +Has,BY,502 +Has,SX,128 +Has,Klaus-Jürgen,6 +Has,Jupp,51 +Has,Volker S,64 +Has,Sven K.,38 +START_OR,4.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,207,H2,E +CompanyRevenue,M1,50 +CompanySplits,M1,50 +M1 receives 25 +Payout,Klaus-Jürgen,25,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,209,E19,NE +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,206,H16,SW +CompanyRevenue,M3,40 +CompanySplits,M3,40 +M3 receives 20 +Payout,Jupp,20,1,100 +BuysTrain,M3,2+2,SX,60 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,12,G5,NW +CompanyRevenue,M4,80 +CompanySplits,M4,80 +M4 receives 40 +Payout,Klaus-Jürgen,40,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,9,F20,NW +CompanyRevenue,M5,80 +CompanySplits,M5,80 +M5 receives 40 +Payout,Volker S,40,1,100 +BuysTrain,M5,2,BY,90 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,12,A11,W +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M6,2,M4,95 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,8,J10,SE +LAYS_TOKEN_ON,BY,J8,120 +CompanyRevenue,BY,180 +CompanyPaysOutFull,BY,180 +Payout,Volker S,90,5,10 +Payout,Sven K.,54,3,10 +Payout,Klaus-Jürgen,36,2,10 +PRICE_MOVES_LOG,BY,90,D5,96,E5 +BuysTrain,BY,3,IPO,180 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,208,H20,W +CompanyRevenue,SX,180 +CompanyPaysOutFull,SX,180 +Payout,Klaus-Jürgen,18,1,10 +Payout,Jupp,90,5,10 +PRICE_MOVES_LOG,SX,84,B4,88,C4 +BuysTrain,SX,3,IPO,180 + +EndOfOperatingRound,4.1 +ORWorthIncrease,Klaus-Jürgen,4.1,195 +ORWorthIncrease,Jupp,4.1,130 +ORWorthIncrease,Volker S,4.1,175 +ORWorthIncrease,Sven K.,4.1,152 +Has,M1,65 +Has,M2,115 +Has,M3,0 +Has,M4,195 +Has,M5,0 +Has,M6,0 +Has,BY,292 +Has,SX,8 +Has,Klaus-Jürgen,185 +Has,Jupp,161 +Has,Volker S,209 +Has,Sven K.,172 +START_OR,4.2 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAtFor,M1,201,I3,NE,50 +CompanyRevenue,M1,70 +CompanySplits,M1,70 +M1 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M1,2,M6,5 + +CompanyOperates,M2,Sven K. +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,205,F14,SE +CompanyRevenue,M3,120 +CompanySplits,M3,120 +M3 receives 60 +Payout,Jupp,60,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAtFor,M4,215,G3,W,50 +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 +BuysTrain,M4,2,M1,175 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,8,H18,E +CompanyRevenue,M5,160 +CompanySplits,M5,160 +M5 receives 80 +Payout,Volker S,80,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,204,B12,SE +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 + +CompanyOperates,BY,Volker S +LaysTileAtFor,BY,213,J6,SE,50 +CompanyRevenue,BY,250 +CompanyPaysOutFull,BY,250 +Payout,Volker S,125,5,10 +Payout,Sven K.,75,3,10 +Payout,Klaus-Jürgen,50,2,10 +PRICE_MOVES_LOG,BY,96,E5,104,F5 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,8,F18,W +CompanyRevenue,SX,290 +CompanyPaysOutFull,SX,290 +Payout,Klaus-Jürgen,29,1,10 +Payout,Jupp,145,5,10 +PRICE_MOVES_LOG,SX,88,C4,94,D4 + +EndOfOperatingRound,4.2 +ORWorthIncrease,Klaus-Jürgen,4.2,226 +ORWorthIncrease,Jupp,4.2,235 +ORWorthIncrease,Volker S,4.2,260 +ORWorthIncrease,Sven K.,4.2,179 +Has,M1,220 +Has,M2,155 +Has,M3,60 +Has,M4,0 +Has,M5,80 +Has,M6,40 +Has,BY,242 +Has,SX,8 +Has,Klaus-Jürgen,389 +Has,Jupp,366 +Has,Volker S,429 +Has,Sven K.,327 +StartStockRound,5 +HasPriority,Jupp +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +PriceIsPaidTo,88,SX +BUY_SHARE_LOG,Volker S,10,SX,IPO,88 +PriceIsPaidTo,88,SX +BUY_SHARE_LOG,Sven K.,10,SX,IPO,88 +PriceIsPaidTo,88,SX +BUY_SHARE_LOG,Klaus-Jürgen,10,SX,IPO,88 +PriceIsPaidTo,88,SX +SharesReleased,All,BA +PASSES,Jupp +SELL_SHARE_LOG,Volker S,10,SX,94 +PRICE_MOVES_LOG,SX,94,D4,90,D5 +START_COMPANY_LOG,Volker S,BA,84,168,2,20,BANK +SharesReleased,4 10%,PR +BUY_SHARE_LOG,Sven K.,10,SX,Pool,90 +PASSES,Klaus-Jürgen +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +PASSES,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,PR,IPO,154 +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +FloatsWithCash,BA,420 +SharesReleased,All,WT +BUY_SHARE_LOG,Sven K.,10,BA,IPO,84 +PriceIsPaidTo,84,BA +SELL_SHARES_LOG,Klaus-Jürgen,2,10,20,BY,208 +PRICE_MOVES_LOG,BY,104,F5,98,F6 +START_COMPANY_LOG,Klaus-Jürgen,WT,84,168,2,20,BANK +BUY_SHARE_LOG,Jupp,10,BY,Pool,98 +Autopasses,Volker S +PASSES,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PASSES,Jupp +Autopasses,Volker S +PASSES,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PASSES,Jupp +Autopasses,Volker S +PASSES,Sven K. +SELL_SHARE_LOG,Klaus-Jürgen,10,SX,90 +PRICE_MOVES_LOG,SX,90,D5,88,D6 +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +FloatsWithCash,WT,420 +SharesReleased,All,HE +BUY_SHARE_LOG,Jupp,10,SX,Pool,88 +Autopasses,Volker S +PASSES,Sven K. +PASSES,Klaus-Jürgen +BUY_SHARE_LOG,Jupp,10,BA,IPO,84 +PriceIsPaidTo,84,BA +Autopasses,Volker S +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp + +END_SR,5 +PRICE_MOVES_LOG,SX,88,D6,90,D5 +SoldOut,SX,88,D6,90,D5 +Has,M1,220 +Has,M2,155 +Has,M3,60 +Has,M4,0 +Has,M5,80 +Has,M6,40 +Has,BY,242 +Has,SX,360 +Has,BA,588 +Has,WT,420 +Has,Klaus-Jürgen,25 +Has,Jupp,8 +Has,Volker S,15 +Has,Sven K.,65 +START_OR,5.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,8,K5,NW +CompanyRevenue,M1,70 +CompanySplits,M1,70 +M1 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M1,3,IPO,180 +All 3-trains are sold out, 3+3-trains now available + +CompanyOperates,M2,Sven K. +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,9,F16,W +CompanyRevenue,M3,140 +CompanySplits,M3,140 +M3 receives 70 +Payout,Jupp,70,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,207,I3,NE +CompanyRevenue,M4,100 +CompanySplits,M4,100 +M4 receives 50 +Payout,Klaus-Jürgen,50,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,58,I15,E +CompanyRevenue,M5,160 +CompanySplits,M5,160 +M5 receives 80 +Payout,Volker S,80,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,4,B14,W +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 + +CompanyOperates,BY,Volker S +LaysTileAtFor,BY,9,K7,SW,50 +LaysTileAt,BY,210,L6,E +CompanyRevenue,BY,320 +CompanyPaysOutFull,BY,320 +Payout,Volker S,160,5,10 +Payout,Sven K.,96,3,10 +Payout,Jupp,32,1,10 +Payout,BY,32,1,10 +PRICE_MOVES_LOG,BY,98,F6,106,G6 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,16,H18,E +LAYS_TOKEN_ON,SX,E19,60 +CompanyRevenue,SX,300 +CompanyPaysOutFull,SX,300 +Payout,Sven K.,60,2,10 +Payout,Klaus-Jürgen,30,1,10 +Payout,Jupp,210,7,10 +PRICE_MOVES_LOG,SX,90,D5,96,E5 +BuysTrain,SX,2,M3,1 + +CompanyOperates,BA,Volker S +LaysTileAt,BA,24,K5,NW +LAYS_TOKEN_ON,BA,H2,80 +CompanyDoesNotPayDividend,BA +PRICE_MOVES_LOG,BA,84,B4,78,A4 +BuysTrain,BA,3+3,IPO,270 +FirstTrainBought,3+3 +BuysTrain,BA,2,M5,1 +BuysTrain,BA,2+2,BY,110 + +CompanyOperates,WT,Klaus-Jürgen +LaysTileAt,WT,5,M9,NE +CompanyDoesNotPayDividend,WT +PRICE_MOVES_LOG,WT,84,B4,78,A4 +BuysTrain,WT,3+3,IPO,270 + +EndOfOperatingRound,5.1 +ORWorthIncrease,Klaus-Jürgen,5.1,151 +ORWorthIncrease,Jupp,5.1,356 +ORWorthIncrease,Volker S,5.1,265 +ORWorthIncrease,Sven K.,5.1,266 +Has,M1,75 +Has,M2,195 +Has,M3,131 +Has,M4,50 +Has,M5,161 +Has,M6,75 +Has,BY,334 +Has,SX,299 +Has,BA,127 +Has,WT,150 +Has,Klaus-Jürgen,200 +Has,Jupp,320 +Has,Volker S,270 +Has,Sven K.,301 +START_OR,5.2 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,19,K7,NE +CompanyRevenue,M1,180 +CompanySplits,M1,180 +M1 receives 90 +Payout,Klaus-Jürgen,90,1,100 + +CompanyOperates,M2,Sven K. +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,23,F18,SW +CompanyRevenue,M3,80 +CompanySplits,M3,80 +M3 receives 40 +Payout,Jupp,40,1,100 +BuysTrain,M3,2+2,SX,171 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,55,L8,SW +CompanyRevenue,M4,100 +CompanySplits,M4,100 +M4 receives 50 +Payout,Klaus-Jürgen,50,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,23,D14,W +CompanyRevenue,M5,80 +CompanySplits,M5,80 +M5 receives 40 +Payout,Volker S,40,1,100 +BuysTrain,M5,2,BA,201 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,58,B16,SE +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,16,I5,SE +CompanyRevenue,BY,280 +CompanyPaysOutFull,BY,280 +Payout,Volker S,140,5,10 +Payout,Sven K.,84,3,10 +Payout,Jupp,28,1,10 +Payout,BY,28,1,10 +PRICE_MOVES_LOG,BY,106,G6,114,G5 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,23,D18,NW +CompanyRevenue,SX,280 +CompanyPaysOutFull,SX,280 +Payout,Sven K.,56,2,10 +Payout,Jupp,196,7,10 +Payout,Klaus-Jürgen,28,1,10 +PRICE_MOVES_LOG,SX,96,E5,104,F5 + +CompanyOperates,BA,Volker S +LaysTileAt,BA,204,H4,E +CompanyRevenue,BA,230 +CompanyPaysOutFull,BA,230 +Payout,Volker S,115,5,10 +Payout,Jupp,23,1,10 +Payout,Sven K.,23,1,10 +PRICE_MOVES_LOG,BA,78,A4,84,B4 + +CompanyOperates,WT,Klaus-Jürgen +LaysTileAt,WT,69,M7,SE +LAYS_TOKEN_ON,WT,I3,100 +CompanyRevenue,WT,140 +CompanyPaysOutFull,WT,140 +Payout,Klaus-Jürgen,70,5,10 +PRICE_MOVES_LOG,WT,78,A4,84,B4 +BuysTrain,WT,2,M4,1 + +EndOfOperatingRound,5.2 +ORWorthIncrease,Klaus-Jürgen,5.2,336 +ORWorthIncrease,Jupp,5.2,357 +ORWorthIncrease,Volker S,5.2,380 +ORWorthIncrease,Sven K.,5.2,289 +Has,M1,165 +Has,M2,235 +Has,M3,0 +Has,M4,101 +Has,M5,0 +Has,M6,110 +Has,BY,362 +Has,SX,470 +Has,BA,328 +Has,WT,49 +Has,Klaus-Jürgen,498 +Has,Jupp,607 +Has,Volker S,580 +Has,Sven K.,544 +StartStockRound,6 +HasPriority,Volker S +BUY_SHARE_LOG,Volker S,10,BY,Pool,114 +START_COMPANY_LOG,Sven K.,HE,84,168,2,20,BANK +BUY_SHARE_LOG,Klaus-Jürgen,10,PR,IPO,154 +BUY_SHARE_LOG,Jupp,10,PR,IPO,154 +BUY_SHARE_LOG,Volker S,10,PR,IPO,154 +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PriceIsPaidTo,84,WT +BUY_SHARE_LOG,Jupp,10,WT,IPO,84 +PriceIsPaidTo,84,WT +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +PriceIsPaidTo,84,BA +BUY_SHARE_LOG,Sven K.,20,BA,IPO,168 +PriceIsPaidTo,168,BA +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PriceIsPaidTo,84,WT +BUY_SHARE_LOG,Jupp,20,WT,IPO,168 +PriceIsPaidTo,168,WT +BUY_SHARE_LOG,Volker S,10,BY,Sven K.,171 +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +PASSES,Klaus-Jürgen +PASSES,Jupp +Autopasses,Volker S +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +FloatsWithCash,HE,420 +CorrectionModeActivate,Klaus-Jürgen,CORRECT_CASH +CorrectCashAddMoney,M1,5 +CorrectCashAddMoney,Klaus-Jürgen,5 +CorrectionModeDeactivate,Klaus-Jürgen,CORRECT_CASH +PASSES,Klaus-Jürgen +PASSES,Jupp +Autopasses,Volker S +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +PriceIsPaidTo,84,HE +PASSES,Klaus-Jürgen +BUY_SHARE_LOG,Jupp,10,HE,IPO,84 +PriceIsPaidTo,84,HE +Autopasses,Volker S +SELL_SHARE_LOG,Sven K.,10,BA,84 +PRICE_MOVES_LOG,BA,84,B4,80,B5 +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +PriceIsPaidTo,84,HE +BUY_SHARE_LOG,Klaus-Jürgen,10,BA,Pool,80 +PASSES,Jupp +Autopasses,Volker S +PASSES,Sven K. +PASSES,Klaus-Jürgen + +END_SR,6 +PRICE_MOVES_LOG,BY,114,G5,124,G4 +SoldOut,BY,114,G5,124,G4 +PRICE_MOVES_LOG,SX,104,F5,112,F4 +SoldOut,SX,104,F5,112,F4 +PRICE_MOVES_LOG,WT,84,B4,86,B3 +SoldOut,WT,84,B4,86,B3 +PRICE_MOVES_LOG,BA,80,B5,84,B4 +SoldOut,BA,80,B5,84,B4 +Has,M1,170 +Has,M2,235 +Has,M3,0 +Has,M4,101 +Has,M5,0 +Has,M6,110 +Has,BY,362 +Has,SX,470 +Has,BA,580 +Has,WT,469 +Has,HE,672 +Has,Klaus-Jürgen,101 +Has,Jupp,117 +Has,Volker S,57 +Has,Sven K.,43 +START_OR,6.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,15,M9,W +CompanyRevenue,M1,180 +CompanySplits,M1,180 +M1 receives 90 +Payout,Klaus-Jürgen,90,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,9,C17,NW +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 +BuysTrain,M2,3+3,IPO,270 +All 3+3-trains are sold out, 4-trains now available + +CompanyOperates,M3,Jupp +CompanyRevenue,M3,140 +CompanySplits,M3,140 +M3 receives 70 +Payout,Jupp,70,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,8,F8,W +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 +BuysTrain,M4,3,M1,131 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,9,D12,W +CompanyRevenue,M5,160 +CompanySplits,M5,160 +M5 receives 80 +Payout,Volker S,80,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,25,E17,NW +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M6,2,M1,145 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,15,N12,NW +CompanyRevenue,BY,290 +CompanyPaysOutFull,BY,290 +Payout,Volker S,203,7,10 +Payout,Jupp,29,1,10 +Payout,Sven K.,58,2,10 +PRICE_MOVES_LOG,BY,124,G4,138,H4 +BuysTrain,BY,4,IPO,360 +FirstTrainBought,4 +StartOfPhase,4 +TrainsRusted,2 +CompanyDiscardsTrain,M3,2+2 +StartFormationRound,PR +StartingPlayer,Sven K. +START_MERGED_COMPANY,PR,154,154 +FloatsWithCash,PR,616 +MERGE_MINOR_LOG,Sven K.,M2,PR,5,1 +GetShareForMinor,Sven K.,10,PR,IPO,M2 +ExchangesBaseToken,PR,M2,E19/1 +MERGE_MINOR_LOG,Klaus-Jürgen,M6,PR,0,0 +GetShareForMinor,Klaus-Jürgen,5,PR,IPO,M6 +ExchangesBaseToken,PR,M6,C11/1 + +EndOfFormationRound,PR,OperatingRound 6.1 +IS_NOW_PRES_OF,Klaus-Jürgen,PR + +CompanyOperates,SX,Jupp +LaysTileAt,SX,9,G17,SW +CompanyRevenue,SX,210 +CompanyPaysOutFull,SX,210 +Payout,Sven K.,42,2,10 +Payout,Jupp,147,7,10 +Payout,Klaus-Jürgen,21,1,10 +PRICE_MOVES_LOG,SX,112,F4,124,G4 +BuysTrain,SX,4,IPO,360 + +CompanyOperates,WT,Klaus-Jürgen +LaysTileAt,WT,8,M11,SE +CompanyRevenue,WT,150 +CompanyPaysOutFull,WT,150 +Payout,Jupp,45,3,10 +Payout,Klaus-Jürgen,105,7,10 +PRICE_MOVES_LOG,WT,86,B3,92,C3 +BuysTrain,WT,4,IPO,360 +All 4-trains are sold out, 4+4-trains now available +BuysTrain,WT,3+3,PR,108 + +CompanyOperates,HE,Sven K. +LaysTileAt,HE,25,K13,W +CompanyDoesNotPayDividend,HE +PRICE_MOVES_LOG,HE,84,B4,78,A4 +BuysTrain,HE,3+3,WT,1 +BuysTrain,HE,4+4,IPO,440 +All 4+4-trains are sold out, 5-trains now available +FirstTrainBought,4+4 +StartOfPhase,4+4 +TrainsRusted,2+2 + +CompanyOperates,BA,Volker S +LaysTileAt,BA,9,L10,SW +CompanyRevenue,BA,140 +CompanyPaysOutFull,BA,140 +Payout,Volker S,84,6,10 +Payout,Jupp,14,1,10 +Payout,Sven K.,28,2,10 +Payout,Klaus-Jürgen,14,1,10 +PRICE_MOVES_LOG,BA,84,B4,88,C4 +BuysTrain,BA,3,BY,49 + +EndOfOperatingRound,6.1 +ORWorthIncrease,Klaus-Jürgen,6.1,455 +ORWorthIncrease,Jupp,6.1,419 +ORWorthIncrease,Volker S,6.1,504 +ORWorthIncrease,Sven K.,6.1,380 +Has,M1,536 +Has,M3,70 +Has,M4,0 +Has,M5,80 +Has,BY,51 +Has,SX,110 +Has,BA,531 +Has,WT,2 +Has,HE,231 +Has,PR,729 +Has,Klaus-Jürgen,421 +Has,Jupp,422 +Has,Volker S,439 +Has,Sven K.,251 +StartFormationRound,PR +MERGE_MINOR_LOG,Sven K.,HB,PR,no,no +GetShareForMinor,Sven K.,10,PR,IPO,HB +PrivateCloses,HB +MERGE_MINOR_LOG,Klaus-Jürgen,BB,PR,no,no +GetShareForMinor,Klaus-Jürgen,10,PR,IPO,BB +PrivateCloses,BB +MERGE_MINOR_LOG,Klaus-Jürgen,M4,PR,0,1 +GetShareForMinor,Klaus-Jürgen,10,PR,IPO,M4 +ExchangesBaseToken,PR,M4,G5/1 + +EndOfFormationRoundNoInterrupt,PR +START_OR,6.2 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,203,K11,W +CompanyDoesNotPayDividend,M1 +BuysTrain,M1,5,IPO,500 +FirstTrainBought,5 +StartOfPhase,5 +PhaseClosesAllPrivates, +PrivateCloses,OBB +PrivateCloses,PfB +StartFormationRound,PR +MERGE_MINOR_LOG,Klaus-Jürgen,M1,PR,36,1 +GetShareForMinor,Klaus-Jürgen,5,PR,IPO,M1 +ExchangesBaseToken,PR,M1,H2/1 +MERGE_MINOR_LOG,Jupp,M3,PR,70,0 +GetShareForMinor,Jupp,5,PR,IPO,M3 +ExchangesBaseToken,PR,M3,F14/1 +MERGE_MINOR_LOG,Volker S,M5,PR,80,0 +GetShareForMinor,Volker S,5,PR,IPO,M5 + +EndOfFormationRound,PR,OperatingRound 6.2 + +CompanyOperates,PR,Klaus-Jürgen +CompanyRevenue,PR,300 +CompanyPaysOutFull,PR,300 +NoIncomeForPreviousOperation,Klaus-Jürgen,5,PR +Payout,Volker S,45,3,5 +Payout,Jupp,45,3,5 +Payout,Klaus-Jürgen,135,9,5 +Payout,Sven K.,60,4,5 +PRICE_MOVES_LOG,PR,154,I4,172,J4 commit 9da89be961377d2b13ca5720346c35023a54a207 Author: Erik Vos <eri...@xs...> Date: Fri Oct 12 22:09:41 2012 +0200 1835: after resuming an OR after a PR formation round, a check was missing if the (minor) operating company still exists. Fix: finish the turn if the operating company is closed at that point. This has happened on buying the first 5-train by a minor company. Reported by Volker Schnell. Also fixed: a redundant (and harmless) null track in tile -114 (Braunschweig).(cherry picked from commit 436879f40b9571dfcb27ef5340232a1ec8410aff) Conflicts: tiles/TileDictionary.xml tiles/Tiles.xml diff --git a/data/1835/Tiles.xml b/data/1835/Tiles.xml index f2e99d8..9d048be 100644 --- a/data/1835/Tiles.xml +++ b/data/1835/Tiles.xml @@ -42,7 +42,6 @@ <Track from="city1" gauge="normal" to="side4"/> <Track from="city1" gauge="normal" to="side3"/> <Track from="city1" gauge="normal" to="side1"/> - <Track from="side2" gauge="normal" to="side2"/> </Tile> <Tile colour="fixed" id="-143" name="-143"> <Station id="city1" position="0" type="Town" value="10"/> diff --git a/rails/game/specific/_1835/GameManager_1835.java b/rails/game/specific/_1835/GameManager_1835.java index 8a44dca..28593b6 100644 --- a/rails/game/specific/_1835/GameManager_1835.java +++ b/rails/game/specific/_1835/GameManager_1835.java @@ -9,6 +9,7 @@ public class GameManager_1835 extends GameManager { private RoundI previousRound = null; private Player prFormStartingPlayer = null; + public static String M1_ID = "M1"; public static String M2_ID = "M2"; public static String PR_ID = "PR"; public static String OL_ID = "OL"; diff --git a/rails/game/specific/_1835/OperatingRound_1835.java b/rails/game/specific/_1835/OperatingRound_1835.java index 4513f32..3546ffd 100644 --- a/rails/game/specific/_1835/OperatingRound_1835.java +++ b/rails/game/specific/_1835/OperatingRound_1835.java @@ -147,7 +147,7 @@ public class OperatingRound_1835 extends OperatingRound { // PR has just started. Check if it can operate this round // That's only the case if M1 has just bought // the first 4-train or 4+4-train - && operatingCompany.get() == companyManager.getPublicCompany("M1")) { + && operatingCompany.getName().equalsIgnoreCase(GameManager_1835.M1_ID)) { log.debug("M2 has not operated: PR can operate"); // Insert the Prussian before the first major company @@ -179,6 +179,9 @@ public class OperatingRound_1835 extends OperatingRound { } + // Check if the operating company still exists + if (operatingCompany.get().isClosed()) finishTurn(); + guiHints.setCurrentRoundType(getClass()); super.resume(); } diff --git a/tiles/TileDictionary.18t b/tiles/TileDictionary.18t index 9038379..26de5d4 100644 --- a/tiles/TileDictionary.18t +++ b/tiles/TileDictionary.18t @@ -12970,10 +12970,6 @@ object TTilesWrapper item Position1 = tp1SideF Position2 = tp4SideB - end - item - Position1 = tp4SideC - Position2 = tp4SideC end> Junctions = < item diff --git a/tiles/TileDictionary.xml b/tiles/TileDictionary.xml index 03ec5de..457c3c8 100644 --- a/tiles/TileDictionary.xml +++ b/tiles/TileDictionary.xml @@ -17779,11 +17779,6 @@ <position1>tp1SideF</position1> <position2>tp4SideB</position2> </connection> - <connection> - <conType>ctNormal</conType> - <position1>tp4SideC</position1> - <position2>tp4SideC</position2> - </connection> </connections> </tile> <tile> diff --git a/tiles/Tiles.xml b/tiles/Tiles.xml index d7741b5..7343614 100644 --- a/tiles/Tiles.xml +++ b/tiles/Tiles.xml @@ -3126,7 +3126,6 @@ <Track from="city1" gauge="normal" to="side4"/> <Track from="city1" gauge="normal" to="side3"/> <Track from="city1" gauge="normal" to="side1"/> - <Track from="side2" gauge="normal" to="side2"/> </Tile> <Tile colour="yellow" id="-807" name="XX"> <Station id="city1" position="102" slots="1" type="City"/> |
From: Erik V. <ev...@us...> - 2012-10-12 21:01:25
|
data/1835/Tiles.xml | 1 - rails/game/specific/_1835/GameManager_1835.java | 1 + rails/game/specific/_1835/OperatingRound_1835.java | 5 ++++- tiles/TileDictionary.18t | 4 ---- tiles/TileDictionary.xml | 5 ----- tiles/Tiles.xml | 1 - 6 files changed, 5 insertions(+), 12 deletions(-) New commits: commit 436879f40b9571dfcb27ef5340232a1ec8410aff Author: Erik Vos <eri...@xs...> Date: Fri Oct 12 22:09:41 2012 +0200 1835: after resuming an OR after a PR formation round, a check was missing if the (minor) operating company still exists. Fix: finish the turn if the operating company is closed at that point. This has happened on buying the first 5-train by a minor company. Reported by Volker Schnell. Also fixed: a redundant (and harmless) null track in tile -114 (Braunschweig). diff --git a/data/1835/Tiles.xml b/data/1835/Tiles.xml index f2e99d8..9d048be 100644 --- a/data/1835/Tiles.xml +++ b/data/1835/Tiles.xml @@ -42,7 +42,6 @@ <Track from="city1" gauge="normal" to="side4"/> <Track from="city1" gauge="normal" to="side3"/> <Track from="city1" gauge="normal" to="side1"/> - <Track from="side2" gauge="normal" to="side2"/> </Tile> <Tile colour="fixed" id="-143" name="-143"> <Station id="city1" position="0" type="Town" value="10"/> diff --git a/rails/game/specific/_1835/GameManager_1835.java b/rails/game/specific/_1835/GameManager_1835.java index 8a44dca..28593b6 100644 --- a/rails/game/specific/_1835/GameManager_1835.java +++ b/rails/game/specific/_1835/GameManager_1835.java @@ -9,6 +9,7 @@ public class GameManager_1835 extends GameManager { private RoundI previousRound = null; private Player prFormStartingPlayer = null; + public static String M1_ID = "M1"; public static String M2_ID = "M2"; public static String PR_ID = "PR"; public static String OL_ID = "OL"; diff --git a/rails/game/specific/_1835/OperatingRound_1835.java b/rails/game/specific/_1835/OperatingRound_1835.java index 4513f32..3546ffd 100644 --- a/rails/game/specific/_1835/OperatingRound_1835.java +++ b/rails/game/specific/_1835/OperatingRound_1835.java @@ -147,7 +147,7 @@ public class OperatingRound_1835 extends OperatingRound { // PR has just started. Check if it can operate this round // That's only the case if M1 has just bought // the first 4-train or 4+4-train - && operatingCompany.get() == companyManager.getPublicCompany("M1")) { + && operatingCompany.getName().equalsIgnoreCase(GameManager_1835.M1_ID)) { log.debug("M2 has not operated: PR can operate"); // Insert the Prussian before the first major company @@ -179,6 +179,9 @@ public class OperatingRound_1835 extends OperatingRound { } + // Check if the operating company still exists + if (operatingCompany.get().isClosed()) finishTurn(); + guiHints.setCurrentRoundType(getClass()); super.resume(); } diff --git a/tiles/TileDictionary.18t b/tiles/TileDictionary.18t index e42ad39..366d1dc 100644 --- a/tiles/TileDictionary.18t +++ b/tiles/TileDictionary.18t @@ -12970,10 +12970,6 @@ object TTilesWrapper item Position1 = tp1SideF Position2 = tp4SideB - end - item - Position1 = tp4SideC - Position2 = tp4SideC end> Junctions = < item diff --git a/tiles/TileDictionary.xml b/tiles/TileDictionary.xml index 56a6e39..a1bbe64 100644 --- a/tiles/TileDictionary.xml +++ b/tiles/TileDictionary.xml @@ -17779,11 +17779,6 @@ <position1>tp1SideF</position1> <position2>tp4SideB</position2> </connection> - <connection> - <conType>ctNormal</conType> - <position1>tp4SideC</position1> - <position2>tp4SideC</position2> - </connection> </connections> </tile> <tile> diff --git a/tiles/Tiles.xml b/tiles/Tiles.xml index 9e879bc..49d95d6 100644 --- a/tiles/Tiles.xml +++ b/tiles/Tiles.xml @@ -3126,7 +3126,6 @@ <Track from="city1" gauge="normal" to="side4"/> <Track from="city1" gauge="normal" to="side3"/> <Track from="city1" gauge="normal" to="side1"/> - <Track from="side2" gauge="normal" to="side2"/> </Tile> <Tile colour="yellow" id="-807" name="XX"> <Station id="city1" position="102" slots="1" type="City"/> |
From: Stefan F. <ste...@us...> - 2012-10-11 06:36:12
|
Tag 'v1.7.11' created by Stefan Frey <ste...@we...> at 2012-10-11 06:35 +0000 version 1.7.11 Changes since v1.7.10-4: --- 0 files changed --- |
From: Stefan F. <ste...@us...> - 2012-10-11 06:36:09
|
data/GamesList.xml | 2 rails/game/OperatingRound.java | 4 readme.txt | 16 test/data/bugs/1835_buyTrainAfterMergerPR.rails |binary test/data/bugs/1835_buyTrainAfterMergerPR.report | 1030 +++++++++++++++++++++++ version.number | 2 6 files changed, 1046 insertions(+), 8 deletions(-) New commits: commit 4e22c653c78a352e9644fe7a78d5e283b60c3f58 Author: Stefan Frey <ste...@we...> Date: Thu Oct 11 08:14:04 2012 +0200 prepared for rails 1.7.11 diff --git a/readme.txt b/readme.txt index 5ef8bbc..6eecc77 100644 --- a/readme.txt +++ b/readme.txt @@ -1,13 +1,19 @@ -Rails release 1.7.10: +Rails release 1.7.11: A new maintenance release for Rails 1.x series This release fixes two bugs. -Contributors: Stefan Frey +Contributors: Erik Vos, Stefan Frey -Bugs reported by theos and Russel J. Alphey +Bugs reported by Volker Schnell Lists of bugs fixed: -- fixed bug in starting a company in 18EU if only one start price is possible -- fixed bug that the ReportWindow does not scroll down at game start \ No newline at end of file +- When buying trains from other companies, include companies that have floated +but do not operate in the current round for any reason. +Example was the PR in 1835. +- 1889: the free tile lay of private C was not offered if the cash position was not exceeding +the (not-applicable) costs of building in the hex + +Further: +- Sorted 1835 game options to make the Options list looks prettier. diff --git a/version.number b/version.number index 2ab2e9d..d21edeb 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.10 +version=1.7.11 # 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 21e14d110e1ecad632f3f9007a37729df9c62161 Author: Stefan Frey <ste...@we...> Date: Thu Oct 11 01:17:43 2012 +0200 added testCase for 1835 bug of merged PR: It was impossible to buy a train from the not operating PR diff --git a/test/data/bugs/1835_buyTrainAfterMergerPR.rails b/test/data/bugs/1835_buyTrainAfterMergerPR.rails new file mode 100644 index 0000000..bbd1558 Binary files /dev/null and b/test/data/bugs/1835_buyTrainAfterMergerPR.rails differ diff --git a/test/data/bugs/1835_buyTrainAfterMergerPR.report b/test/data/bugs/1835_buyTrainAfterMergerPR.report new file mode 100644 index 0000000..b80b414 --- /dev/null +++ b/test/data/bugs/1835_buyTrainAfterMergerPR.report @@ -0,0 +1,1030 @@ +GameIs,1835 +PlayerIs,1,Klaus-Jürgen +PlayerIs,2,Jupp +PlayerIs,3,Volker S +PlayerIs,4,Sven K. +PlayerCash,475 +BankHas,10100 +StartOfPhase,2 +BankSizeIs,10100 +StartOfInitialRound +HasPriority,Klaus-Jürgen +BuysItemFor,Sven K.,M2,170 +FloatsWithCash,M2,170 +BuysItemFor,Volker S,M5,80 +FloatsWithCash,M5,80 +BuysItemFor,Jupp,M3,80 +FloatsWithCash,M3,80 +BuysItemFor,Klaus-Jürgen,M1,80 +FloatsWithCash,M1,80 +BuysItemFor,Klaus-Jürgen,M6,80 +FloatsWithCash,M6,80 +BuysItemFor,Jupp,LD,190 +ALSO_GETS,Jupp,PRES_CERT_NAME,SX,20 +BuysItemFor,Volker S,NF,100 +ALSO_GETS,Volker S,CERT_NAME,BY,10 +BuysItemFor,Sven K.,OBB,120 +ALSO_GETS,Sven K.,CERT_NAME,BY,10 +BuysItemFor,Klaus-Jürgen,BB,130 +BuysItemFor,Jupp,PRES_CERT_NAME,BY,20,184 +BuysItemFor,Volker S,PfB,150 +ALSO_GETS,Volker S,CERT_NAME,BY,10 +FloatsWithCash,BY,460 +BuysItemFor,Sven K.,HB,160 +BuysItemFor,Klaus-Jürgen,M4,160 +FloatsWithCash,M4,160 +Has,M1,80 +Has,M2,170 +Has,M3,80 +Has,M4,160 +Has,M5,80 +Has,M6,80 +Has,BY,460 +Has,Klaus-Jürgen,25 +Has,Jupp,21 +Has,Volker S,145 +Has,Sven K.,25 +StartStockRound,1 +HasPriority,Jupp +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BY,IPO,92 +PriceIsPaidTo,92,BY +IS_NOW_PRES_OF,Volker S,BY +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp +PASSES,Volker S + +END_SR,1 +Has,M1,80 +Has,M2,170 +Has,M3,80 +Has,M4,160 +Has,M5,80 +Has,M6,80 +Has,BY,552 +Has,Klaus-Jürgen,25 +Has,Jupp,21 +Has,Volker S,53 +Has,Sven K.,25 +START_OR,1.1 +ReceivesFor,Volker S,5,NF +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Jupp,20,LD +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,201,H2,SE +CompanyDoesNotPayDividend,M1 +BuysTrain,M1,2,IPO,80 +FirstTrainBought,2 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,8,E17,NW +CompanyDoesNotPayDividend,M2 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,6,F14,NW +CompanyDoesNotPayDividend,M3 +BuysTrain,M3,2,IPO,80 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,6,G5,NE +CompanyDoesNotPayDividend,M4 +BuysTrain,M4,2,IPO,80 +BuysTrain,M4,2,IPO,80 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,8,D18,NE +CompanyDoesNotPayDividend,M5 +BuysTrain,M5,2,IPO,80 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,9,B10,NW +CompanyDoesNotPayDividend,M6 +BuysTrain,M6,2,IPO,80 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,201,O15,NW +LaysTileAt,BY,8,O13,NW +CompanyDoesNotPayDividend,BY +PRICE_MOVES_LOG,BY,92,C3,86,B3 +BuysTrain,BY,2,IPO,80 +BuysTrain,BY,2,IPO,80 + +EndOfOperatingRound,1.1 +ORWorthIncrease,Klaus-Jürgen,1.1,25 +ORWorthIncrease,Jupp,1.1,8 +ORWorthIncrease,Volker S,1.1,2 +ORWorthIncrease,Sven K.,1.1,34 +Has,M1,0 +Has,M2,170 +Has,M3,0 +Has,M4,0 +Has,M5,0 +Has,M6,0 +Has,BY,392 +Has,Klaus-Jürgen,50 +Has,Jupp,41 +Has,Volker S,73 +Has,Sven K.,65 +StartStockRound,2 +HasPriority,Sven K. +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp +PASSES,Volker S + +END_SR,2 +Has,M1,0 +Has,M2,170 +Has,M3,0 +Has,M4,0 +Has,M5,0 +Has,M6,0 +Has,BY,392 +Has,Klaus-Jürgen,50 +Has,Jupp,41 +Has,Volker S,73 +Has,Sven K.,65 +START_OR,2.1 +ReceivesFor,Volker S,5,NF +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Jupp,20,LD +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,69,H4,SW +CompanyRevenue,M1,40 +CompanySplits,M1,40 +M1 receives 20 +Payout,Klaus-Jürgen,20,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,8,D16,SE +CompanyDoesNotPayDividend,M2 +BuysTrain,M2,2,IPO,80 +All 2-trains are sold out, 2+2-trains now available + +CompanyOperates,M3,Jupp +LaysTileAt,M3,4,G15,NW +CompanyRevenue,M3,40 +CompanySplits,M3,40 +M3 receives 20 +Payout,Jupp,20,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,3,F4,E +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,8,C19,E +CompanyRevenue,M5,50 +CompanySplits,M5,50 +M5 receives 25 +Payout,Volker S,25,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,6,A11,NW +CompanyRevenue,M6,60 +CompanySplits,M6,60 +M6 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,8,N14,SE +LaysTileAt,BY,5,N12,SW +LAYS_FREE_TOKEN_ON,BY,L14 +PrivateCloses,NF +CompanyRevenue,BY,100 +CompanyPaysOutFull,BY,100 +Payout,Jupp,20,2,10 +Payout,Volker S,30,3,10 +Payout,Sven K.,10,1,10 +PRICE_MOVES_LOG,BY,86,B3,92,C3 +BuysTrain,BY,2+2,IPO,120 +FirstTrainBought,2+2 + +EndOfOperatingRound,2.1 +ORWorthIncrease,Klaus-Jürgen,2.1,105 +ORWorthIncrease,Jupp,2.1,72 +ORWorthIncrease,Volker S,2.1,-7 +ORWorthIncrease,Sven K.,2.1,56 +Has,M1,20 +Has,M2,90 +Has,M3,20 +Has,M4,30 +Has,M5,25 +Has,M6,30 +Has,BY,272 +Has,Klaus-Jürgen,155 +Has,Jupp,101 +Has,Volker S,148 +Has,Sven K.,115 +StartStockRound,3 +HasPriority,Sven K. +BUY_SHARE_LOG,Sven K.,10,BY,IPO,92 +PriceIsPaidTo,92,BY +BUY_SHARE_LOG,Klaus-Jürgen,10,BY,IPO,92 +PriceIsPaidTo,92,BY +BUY_SHARE_LOG,Jupp,10,BY,IPO,92 +PriceIsPaidTo,92,BY +BUY_SHARE_LOG,Volker S,10,BY,IPO,92 +PriceIsPaidTo,92,BY +PASSES,Sven K. +Autopasses,Klaus-Jürgen +SELL_SHARE_LOG,Jupp,10,BY,92 +PRICE_MOVES_LOG,BY,92,C3,88,C4 +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +Autopasses,Volker S +Autopasses,Sven K. +Autopasses,Klaus-Jürgen +SELL_SHARE_LOG,Jupp,10,BY,88 +PRICE_MOVES_LOG,BY,88,C4,86,C5 +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +Autopasses,Volker S +Autopasses,Sven K. +Autopasses,Klaus-Jürgen +SELL_SHARE_LOG,Jupp,10,BY,86 +PRICE_MOVES_LOG,BY,86,C5,82,C6 +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +FloatsWithCash,SX,440 +Autopasses,Volker S +Autopasses,Sven K. +Autopasses,Klaus-Jürgen +PASSES,Jupp + +END_SR,3 +Has,M1,20 +Has,M2,90 +Has,M3,20 +Has,M4,30 +Has,M5,25 +Has,M6,30 +Has,BY,640 +Has,SX,440 +Has,Klaus-Jürgen,63 +Has,Jupp,11 +Has,Volker S,56 +Has,Sven K.,23 +START_OR,3.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Jupp,20,LD +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,8,I5,SW +CompanyRevenue,M1,40 +CompanySplits,M1,40 +M1 receives 20 +Payout,Klaus-Jürgen,20,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAtFor,M2,8,D14,NW,50 +CompanyRevenue,M2,70 +CompanySplits,M2,70 +M2 receives 35 +Payout,Sven K.,35,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,57,H16,NW +CompanyRevenue,M3,40 +CompanySplits,M3,40 +M3 receives 20 +Payout,Jupp,20,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,4,F6,W +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,M5,Volker S +CompanyRevenue,M5,50 +CompanySplits,M5,50 +M5 receives 25 +Payout,Volker S,25,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,58,B12,NW +CompanyRevenue,M6,60 +CompanySplits,M6,60 +M6 receives 30 +Payout,Klaus-Jürgen,30,1,100 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,56,I17,NE +LaysTileAt,SX,202,H20,W +LAYS_TOKEN_ON,SX,H20,40 +CompanyDoesNotPayDividend,SX +PRICE_MOVES_LOG,SX,88,C4,84,B4 +BuysTrain,SX,2+2,IPO,120 +PrivateCloses,LD +BuysTrain,SX,2+2,IPO,120 +BuysTrain,SX,2+2,IPO,120 +All 2+2-trains are sold out, 3-trains now available + +CompanyOperates,BY,Volker S +LaysTileAt,BY,8,K13,SE +LaysTileAt,BY,58,K11,NW +CompanyRevenue,BY,140 +CompanyPaysOutFull,BY,140 +Payout,Volker S,56,4,10 +Payout,Sven K.,28,2,10 +Payout,Klaus-Jürgen,14,1,10 +Payout,BY,42,3,10 +PRICE_MOVES_LOG,BY,82,C6,88,D6 +BuysTrain,BY,3,IPO,180 +FirstTrainBought,3 +StartOfPhase,3 + +EndOfOperatingRound,3.1 +ORWorthIncrease,Klaus-Jürgen,3.1,125 +ORWorthIncrease,Jupp,3.1,-170 +ORWorthIncrease,Volker S,3.1,120 +ORWorthIncrease,Sven K.,3.1,115 +Has,M1,40 +Has,M2,75 +Has,M3,40 +Has,M4,60 +Has,M5,50 +Has,M6,60 +Has,BY,502 +Has,SX,40 +Has,Klaus-Jürgen,182 +Has,Jupp,51 +Has,Volker S,152 +Has,Sven K.,126 +StartStockRound,4 +HasPriority,Volker S +BUY_SHARE_LOG,Volker S,10,BY,Pool,88 +BUY_SHARE_LOG,Sven K.,10,BY,Pool,88 +BUY_SHARE_LOG,Klaus-Jürgen,10,BY,Pool,88 +Autopasses,Jupp +Autopasses,Volker S +Autopasses,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,SX,IPO,88 +PriceIsPaidTo,88,SX +Autopasses,Jupp +Autopasses,Volker S +Autopasses,Sven K. +PASSES,Klaus-Jürgen + +END_SR,4 +PRICE_MOVES_LOG,BY,88,D6,90,D5 +SoldOut,BY,88,D6,90,D5 +Has,M1,40 +Has,M2,75 +Has,M3,40 +Has,M4,60 +Has,M5,50 +Has,M6,60 +Has,BY,502 +Has,SX,128 +Has,Klaus-Jürgen,6 +Has,Jupp,51 +Has,Volker S,64 +Has,Sven K.,38 +START_OR,4.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,207,H2,E +CompanyRevenue,M1,50 +CompanySplits,M1,50 +M1 receives 25 +Payout,Klaus-Jürgen,25,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,209,E19,NE +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,206,H16,SW +CompanyRevenue,M3,40 +CompanySplits,M3,40 +M3 receives 20 +Payout,Jupp,20,1,100 +BuysTrain,M3,2+2,SX,60 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,12,G5,NW +CompanyRevenue,M4,80 +CompanySplits,M4,80 +M4 receives 40 +Payout,Klaus-Jürgen,40,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,9,F20,NW +CompanyRevenue,M5,80 +CompanySplits,M5,80 +M5 receives 40 +Payout,Volker S,40,1,100 +BuysTrain,M5,2,BY,90 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,12,A11,W +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M6,2,M4,95 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,8,J10,SE +LAYS_TOKEN_ON,BY,J8,120 +CompanyRevenue,BY,180 +CompanyPaysOutFull,BY,180 +Payout,Volker S,90,5,10 +Payout,Sven K.,54,3,10 +Payout,Klaus-Jürgen,36,2,10 +PRICE_MOVES_LOG,BY,90,D5,96,E5 +BuysTrain,BY,3,IPO,180 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,208,H20,W +CompanyRevenue,SX,180 +CompanyPaysOutFull,SX,180 +Payout,Klaus-Jürgen,18,1,10 +Payout,Jupp,90,5,10 +PRICE_MOVES_LOG,SX,84,B4,88,C4 +BuysTrain,SX,3,IPO,180 + +EndOfOperatingRound,4.1 +ORWorthIncrease,Klaus-Jürgen,4.1,195 +ORWorthIncrease,Jupp,4.1,130 +ORWorthIncrease,Volker S,4.1,175 +ORWorthIncrease,Sven K.,4.1,152 +Has,M1,65 +Has,M2,115 +Has,M3,0 +Has,M4,195 +Has,M5,0 +Has,M6,0 +Has,BY,292 +Has,SX,8 +Has,Klaus-Jürgen,185 +Has,Jupp,161 +Has,Volker S,209 +Has,Sven K.,172 +START_OR,4.2 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAtFor,M1,201,I3,NE,50 +CompanyRevenue,M1,70 +CompanySplits,M1,70 +M1 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M1,2,M6,5 + +CompanyOperates,M2,Sven K. +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,205,F14,SE +CompanyRevenue,M3,120 +CompanySplits,M3,120 +M3 receives 60 +Payout,Jupp,60,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAtFor,M4,215,G3,W,50 +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 +BuysTrain,M4,2,M1,175 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,8,H18,E +CompanyRevenue,M5,160 +CompanySplits,M5,160 +M5 receives 80 +Payout,Volker S,80,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,204,B12,SE +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 + +CompanyOperates,BY,Volker S +LaysTileAtFor,BY,213,J6,SE,50 +CompanyRevenue,BY,250 +CompanyPaysOutFull,BY,250 +Payout,Volker S,125,5,10 +Payout,Sven K.,75,3,10 +Payout,Klaus-Jürgen,50,2,10 +PRICE_MOVES_LOG,BY,96,E5,104,F5 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,8,F18,W +CompanyRevenue,SX,290 +CompanyPaysOutFull,SX,290 +Payout,Klaus-Jürgen,29,1,10 +Payout,Jupp,145,5,10 +PRICE_MOVES_LOG,SX,88,C4,94,D4 + +EndOfOperatingRound,4.2 +ORWorthIncrease,Klaus-Jürgen,4.2,226 +ORWorthIncrease,Jupp,4.2,235 +ORWorthIncrease,Volker S,4.2,260 +ORWorthIncrease,Sven K.,4.2,179 +Has,M1,220 +Has,M2,155 +Has,M3,60 +Has,M4,0 +Has,M5,80 +Has,M6,40 +Has,BY,242 +Has,SX,8 +Has,Klaus-Jürgen,389 +Has,Jupp,366 +Has,Volker S,429 +Has,Sven K.,327 +StartStockRound,5 +HasPriority,Jupp +BUY_SHARE_LOG,Jupp,10,SX,IPO,88 +PriceIsPaidTo,88,SX +BUY_SHARE_LOG,Volker S,10,SX,IPO,88 +PriceIsPaidTo,88,SX +BUY_SHARE_LOG,Sven K.,10,SX,IPO,88 +PriceIsPaidTo,88,SX +BUY_SHARE_LOG,Klaus-Jürgen,10,SX,IPO,88 +PriceIsPaidTo,88,SX +SharesReleased,All,BA +PASSES,Jupp +SELL_SHARE_LOG,Volker S,10,SX,94 +PRICE_MOVES_LOG,SX,94,D4,90,D5 +START_COMPANY_LOG,Volker S,BA,84,168,2,20,BANK +SharesReleased,4 10%,PR +BUY_SHARE_LOG,Sven K.,10,SX,Pool,90 +PASSES,Klaus-Jürgen +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +PASSES,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,PR,IPO,154 +PASSES,Jupp +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +FloatsWithCash,BA,420 +SharesReleased,All,WT +BUY_SHARE_LOG,Sven K.,10,BA,IPO,84 +PriceIsPaidTo,84,BA +SELL_SHARES_LOG,Klaus-Jürgen,2,10,20,BY,208 +PRICE_MOVES_LOG,BY,104,F5,98,F6 +START_COMPANY_LOG,Klaus-Jürgen,WT,84,168,2,20,BANK +BUY_SHARE_LOG,Jupp,10,BY,Pool,98 +Autopasses,Volker S +PASSES,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PASSES,Jupp +Autopasses,Volker S +PASSES,Sven K. +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PASSES,Jupp +Autopasses,Volker S +PASSES,Sven K. +SELL_SHARE_LOG,Klaus-Jürgen,10,SX,90 +PRICE_MOVES_LOG,SX,90,D5,88,D6 +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +FloatsWithCash,WT,420 +SharesReleased,All,HE +BUY_SHARE_LOG,Jupp,10,SX,Pool,88 +Autopasses,Volker S +PASSES,Sven K. +PASSES,Klaus-Jürgen +BUY_SHARE_LOG,Jupp,10,BA,IPO,84 +PriceIsPaidTo,84,BA +Autopasses,Volker S +PASSES,Sven K. +PASSES,Klaus-Jürgen +PASSES,Jupp + +END_SR,5 +PRICE_MOVES_LOG,SX,88,D6,90,D5 +SoldOut,SX,88,D6,90,D5 +Has,M1,220 +Has,M2,155 +Has,M3,60 +Has,M4,0 +Has,M5,80 +Has,M6,40 +Has,BY,242 +Has,SX,360 +Has,BA,588 +Has,WT,420 +Has,Klaus-Jürgen,25 +Has,Jupp,8 +Has,Volker S,15 +Has,Sven K.,65 +START_OR,5.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,8,K5,NW +CompanyRevenue,M1,70 +CompanySplits,M1,70 +M1 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M1,3,IPO,180 +All 3-trains are sold out, 3+3-trains now available + +CompanyOperates,M2,Sven K. +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,9,F16,W +CompanyRevenue,M3,140 +CompanySplits,M3,140 +M3 receives 70 +Payout,Jupp,70,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,207,I3,NE +CompanyRevenue,M4,100 +CompanySplits,M4,100 +M4 receives 50 +Payout,Klaus-Jürgen,50,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,58,I15,E +CompanyRevenue,M5,160 +CompanySplits,M5,160 +M5 receives 80 +Payout,Volker S,80,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,4,B14,W +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 + +CompanyOperates,BY,Volker S +LaysTileAtFor,BY,9,K7,SW,50 +LaysTileAt,BY,210,L6,E +CompanyRevenue,BY,320 +CompanyPaysOutFull,BY,320 +Payout,Volker S,160,5,10 +Payout,Sven K.,96,3,10 +Payout,Jupp,32,1,10 +Payout,BY,32,1,10 +PRICE_MOVES_LOG,BY,98,F6,106,G6 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,16,H18,E +LAYS_TOKEN_ON,SX,E19,60 +CompanyRevenue,SX,300 +CompanyPaysOutFull,SX,300 +Payout,Sven K.,60,2,10 +Payout,Klaus-Jürgen,30,1,10 +Payout,Jupp,210,7,10 +PRICE_MOVES_LOG,SX,90,D5,96,E5 +BuysTrain,SX,2,M3,1 + +CompanyOperates,BA,Volker S +LaysTileAt,BA,24,K5,NW +LAYS_TOKEN_ON,BA,H2,80 +CompanyDoesNotPayDividend,BA +PRICE_MOVES_LOG,BA,84,B4,78,A4 +BuysTrain,BA,3+3,IPO,270 +FirstTrainBought,3+3 +BuysTrain,BA,2,M5,1 +BuysTrain,BA,2+2,BY,110 + +CompanyOperates,WT,Klaus-Jürgen +LaysTileAt,WT,5,M9,NE +CompanyDoesNotPayDividend,WT +PRICE_MOVES_LOG,WT,84,B4,78,A4 +BuysTrain,WT,3+3,IPO,270 + +EndOfOperatingRound,5.1 +ORWorthIncrease,Klaus-Jürgen,5.1,151 +ORWorthIncrease,Jupp,5.1,356 +ORWorthIncrease,Volker S,5.1,265 +ORWorthIncrease,Sven K.,5.1,266 +Has,M1,75 +Has,M2,195 +Has,M3,131 +Has,M4,50 +Has,M5,161 +Has,M6,75 +Has,BY,334 +Has,SX,299 +Has,BA,127 +Has,WT,150 +Has,Klaus-Jürgen,200 +Has,Jupp,320 +Has,Volker S,270 +Has,Sven K.,301 +START_OR,5.2 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,19,K7,NE +CompanyRevenue,M1,180 +CompanySplits,M1,180 +M1 receives 90 +Payout,Klaus-Jürgen,90,1,100 + +CompanyOperates,M2,Sven K. +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 + +CompanyOperates,M3,Jupp +LaysTileAt,M3,23,F18,SW +CompanyRevenue,M3,80 +CompanySplits,M3,80 +M3 receives 40 +Payout,Jupp,40,1,100 +BuysTrain,M3,2+2,SX,171 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,55,L8,SW +CompanyRevenue,M4,100 +CompanySplits,M4,100 +M4 receives 50 +Payout,Klaus-Jürgen,50,1,100 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,23,D14,W +CompanyRevenue,M5,80 +CompanySplits,M5,80 +M5 receives 40 +Payout,Volker S,40,1,100 +BuysTrain,M5,2,BA,201 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,58,B16,SE +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,16,I5,SE +CompanyRevenue,BY,280 +CompanyPaysOutFull,BY,280 +Payout,Volker S,140,5,10 +Payout,Sven K.,84,3,10 +Payout,Jupp,28,1,10 +Payout,BY,28,1,10 +PRICE_MOVES_LOG,BY,106,G6,114,G5 + +CompanyOperates,SX,Jupp +LaysTileAt,SX,23,D18,NW +CompanyRevenue,SX,280 +CompanyPaysOutFull,SX,280 +Payout,Sven K.,56,2,10 +Payout,Jupp,196,7,10 +Payout,Klaus-Jürgen,28,1,10 +PRICE_MOVES_LOG,SX,96,E5,104,F5 + +CompanyOperates,BA,Volker S +LaysTileAt,BA,204,H4,E +CompanyRevenue,BA,230 +CompanyPaysOutFull,BA,230 +Payout,Volker S,115,5,10 +Payout,Jupp,23,1,10 +Payout,Sven K.,23,1,10 +PRICE_MOVES_LOG,BA,78,A4,84,B4 + +CompanyOperates,WT,Klaus-Jürgen +LaysTileAt,WT,69,M7,SE +LAYS_TOKEN_ON,WT,I3,100 +CompanyRevenue,WT,140 +CompanyPaysOutFull,WT,140 +Payout,Klaus-Jürgen,70,5,10 +PRICE_MOVES_LOG,WT,78,A4,84,B4 +BuysTrain,WT,2,M4,1 + +EndOfOperatingRound,5.2 +ORWorthIncrease,Klaus-Jürgen,5.2,336 +ORWorthIncrease,Jupp,5.2,357 +ORWorthIncrease,Volker S,5.2,380 +ORWorthIncrease,Sven K.,5.2,289 +Has,M1,165 +Has,M2,235 +Has,M3,0 +Has,M4,101 +Has,M5,0 +Has,M6,110 +Has,BY,362 +Has,SX,470 +Has,BA,328 +Has,WT,49 +Has,Klaus-Jürgen,498 +Has,Jupp,607 +Has,Volker S,580 +Has,Sven K.,544 +StartStockRound,6 +HasPriority,Volker S +BUY_SHARE_LOG,Volker S,10,BY,Pool,114 +START_COMPANY_LOG,Sven K.,HE,84,168,2,20,BANK +BUY_SHARE_LOG,Klaus-Jürgen,10,PR,IPO,154 +BUY_SHARE_LOG,Jupp,10,PR,IPO,154 +BUY_SHARE_LOG,Volker S,10,PR,IPO,154 +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PriceIsPaidTo,84,WT +BUY_SHARE_LOG,Jupp,10,WT,IPO,84 +PriceIsPaidTo,84,WT +BUY_SHARE_LOG,Volker S,10,BA,IPO,84 +PriceIsPaidTo,84,BA +BUY_SHARE_LOG,Sven K.,20,BA,IPO,168 +PriceIsPaidTo,168,BA +BUY_SHARE_LOG,Klaus-Jürgen,10,WT,IPO,84 +PriceIsPaidTo,84,WT +BUY_SHARE_LOG,Jupp,20,WT,IPO,168 +PriceIsPaidTo,168,WT +BUY_SHARE_LOG,Volker S,10,BY,Sven K.,171 +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +PASSES,Klaus-Jürgen +PASSES,Jupp +Autopasses,Volker S +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +FloatsWithCash,HE,420 +CorrectionModeActivate,Klaus-Jürgen,CORRECT_CASH +CorrectCashAddMoney,M1,5 +CorrectCashAddMoney,Klaus-Jürgen,5 +CorrectionModeDeactivate,Klaus-Jürgen,CORRECT_CASH +PASSES,Klaus-Jürgen +PASSES,Jupp +Autopasses,Volker S +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +PriceIsPaidTo,84,HE +PASSES,Klaus-Jürgen +BUY_SHARE_LOG,Jupp,10,HE,IPO,84 +PriceIsPaidTo,84,HE +Autopasses,Volker S +SELL_SHARE_LOG,Sven K.,10,BA,84 +PRICE_MOVES_LOG,BA,84,B4,80,B5 +BUY_SHARE_LOG,Sven K.,10,HE,IPO,84 +PriceIsPaidTo,84,HE +BUY_SHARE_LOG,Klaus-Jürgen,10,BA,Pool,80 +PASSES,Jupp +Autopasses,Volker S +PASSES,Sven K. +PASSES,Klaus-Jürgen + +END_SR,6 +PRICE_MOVES_LOG,BY,114,G5,124,G4 +SoldOut,BY,114,G5,124,G4 +PRICE_MOVES_LOG,SX,104,F5,112,F4 +SoldOut,SX,104,F5,112,F4 +PRICE_MOVES_LOG,WT,84,B4,86,B3 +SoldOut,WT,84,B4,86,B3 +PRICE_MOVES_LOG,BA,80,B5,84,B4 +SoldOut,BA,80,B5,84,B4 +Has,M1,170 +Has,M2,235 +Has,M3,0 +Has,M4,101 +Has,M5,0 +Has,M6,110 +Has,BY,362 +Has,SX,470 +Has,BA,580 +Has,WT,469 +Has,HE,672 +Has,Klaus-Jürgen,101 +Has,Jupp,117 +Has,Volker S,57 +Has,Sven K.,43 +START_OR,6.1 +ReceivesFor,Sven K.,10,OBB +ReceivesFor,Volker S,15,PfB +ReceivesFor,Klaus-Jürgen,25,BB +ReceivesFor,Sven K.,30,HB + +CompanyOperates,M1,Klaus-Jürgen +LaysTileAt,M1,15,M9,W +CompanyRevenue,M1,180 +CompanySplits,M1,180 +M1 receives 90 +Payout,Klaus-Jürgen,90,1,100 + +CompanyOperates,M2,Sven K. +LaysTileAt,M2,9,C17,NW +CompanyRevenue,M2,80 +CompanySplits,M2,80 +M2 receives 40 +Payout,Sven K.,40,1,100 +BuysTrain,M2,3+3,IPO,270 +All 3+3-trains are sold out, 4-trains now available + +CompanyOperates,M3,Jupp +CompanyRevenue,M3,140 +CompanySplits,M3,140 +M3 receives 70 +Payout,Jupp,70,1,100 + +CompanyOperates,M4,Klaus-Jürgen +LaysTileAt,M4,8,F8,W +CompanyRevenue,M4,60 +CompanySplits,M4,60 +M4 receives 30 +Payout,Klaus-Jürgen,30,1,100 +BuysTrain,M4,3,M1,131 + +CompanyOperates,M5,Volker S +LaysTileAt,M5,9,D12,W +CompanyRevenue,M5,160 +CompanySplits,M5,160 +M5 receives 80 +Payout,Volker S,80,1,100 + +CompanyOperates,M6,Klaus-Jürgen +LaysTileAt,M6,25,E17,NW +CompanyRevenue,M6,70 +CompanySplits,M6,70 +M6 receives 35 +Payout,Klaus-Jürgen,35,1,100 +BuysTrain,M6,2,M1,145 + +CompanyOperates,BY,Volker S +LaysTileAt,BY,15,N12,NW +CompanyRevenue,BY,290 +CompanyPaysOutFull,BY,290 +Payout,Volker S,203,7,10 +Payout,Jupp,29,1,10 +Payout,Sven K.,58,2,10 +PRICE_MOVES_LOG,BY,124,G4,138,H4 +BuysTrain,BY,4,IPO,360 +FirstTrainBought,4 +StartOfPhase,4 +TrainsRusted,2 +CompanyDiscardsTrain,M3,2+2 +StartFormationRound,PR +StartingPlayer,Sven K. +START_MERGED_COMPANY,PR,154,154 +FloatsWithCash,PR,616 +MERGE_MINOR_LOG,Sven K.,M2,PR,5,1 +GetShareForMinor,Sven K.,10,PR,IPO,M2 +ExchangesBaseToken,PR,M2,E19/1 +MERGE_MINOR_LOG,Klaus-Jürgen,M6,PR,0,0 +GetShareForMinor,Klaus-Jürgen,5,PR,IPO,M6 +ExchangesBaseToken,PR,M6,C11/1 + +EndOfFormationRound,PR,OperatingRound 6.1 +IS_NOW_PRES_OF,Klaus-Jürgen,PR + +CompanyOperates,SX,Jupp +LaysTileAt,SX,9,G17,SW +CompanyRevenue,SX,210 +CompanyPaysOutFull,SX,210 +Payout,Sven K.,42,2,10 +Payout,Jupp,147,7,10 +Payout,Klaus-Jürgen,21,1,10 +PRICE_MOVES_LOG,SX,112,F4,124,G4 +BuysTrain,SX,4,IPO,360 + +CompanyOperates,WT,Klaus-Jürgen +LaysTileAt,WT,8,M11,SE +CompanyRevenue,WT,150 +CompanyPaysOutFull,WT,150 +Payout,Jupp,45,3,10 +Payout,Klaus-Jürgen,105,7,10 +PRICE_MOVES_LOG,WT,86,B3,92,C3 +BuysTrain,WT,4,IPO,360 +All 4-trains are sold out, 4+4-trains now available +BuysTrain,WT,3+3,PR,108 commit 120e014d5fb84b6b044f8389409e6f6f44a6c15e Author: Erik Vos <eri...@xs...> Date: Tue Oct 9 21:24:48 2012 +0200 When buying trains from other companies, include companies that have floated but do not operate in the current round for any reason. This fixes a bug reported by Volker Schnell where no train could be bought from the PR in the OR where the PR was formed.(cherry picked from commit fa8142a7eec7a0ba5d2e5f795d0063908650db59) diff --git a/rails/game/OperatingRound.java b/rails/game/OperatingRound.java index af6df5e..94f0c9d 100644 --- a/rails/game/OperatingRound.java +++ b/rails/game/OperatingRound.java @@ -3062,7 +3062,9 @@ public class OperatingRound extends Round implements Observer { companiesPerPlayer.add(new ArrayList<PublicCompanyI>(4)); List<PublicCompanyI> companies; // Sort out which players preside over which companies. - for (PublicCompanyI c : getOperatingCompanies()) { + //for (PublicCompanyI c : getOperatingCompanies()) { + for (PublicCompanyI c : companyManager.getAllPublicCompanies()) { + if (!c.hasFloated()) continue; if (c.isClosed() || c == operatingCompany.get()) continue; p = c.getPresident(); index = p.getIndex(); commit ad23347fa10dcc15aad83823eaef87669685e7a5 Author: Erik Vos <eri...@xs...> Date: Thu Aug 30 13:11:36 2012 +0200 Sorted 1835 game options to make the Options list looks prettier.(cherry picked from commit f86acdf3e526052f22213c594e3e4e75efb3d107) diff --git a/data/GamesList.xml b/data/GamesList.xml index 06fe440..a3877f8 100644 --- a/data/GamesList.xml +++ b/data/GamesList.xml @@ -56,10 +56,10 @@ Known limitations: <Option name="RouteAwareness" values="Highlight,Deactivate" default="Highlight" /> <Option name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest" /> <Option name="UnlimitedTiles" values="No,Yellow Plain,Yes" default="No"/> - <Option name="NoMapMode" type="toggle" default="no" /> <Option name="BYFloatsAt" values="50%,20%" default="50%"/> <Option name="LDIncome" values="20M,30M" default="20M"/> <Option name="MinorsRequireFloatedBY" type="toggle" default="no"/> + <Option name="NoMapMode" type="toggle" default="no" /> <Players minimum="3" maximum="7"/> </Game> |
From: Erik V. <ev...@us...> - 2012-10-09 19:25:34
|
rails/game/OperatingRound.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) New commits: commit fa8142a7eec7a0ba5d2e5f795d0063908650db59 Author: Erik Vos <eri...@xs...> Date: Tue Oct 9 21:24:48 2012 +0200 When buying trains from other companies, include companies that have floated but do not operate in the current round for any reason. This fixes a bug reported by Volker Schnell where no train could be bought from the PR in the OR where the PR was formed. diff --git a/rails/game/OperatingRound.java b/rails/game/OperatingRound.java index d799ad9..4d77326 100644 --- a/rails/game/OperatingRound.java +++ b/rails/game/OperatingRound.java @@ -3062,7 +3062,9 @@ public class OperatingRound extends Round implements Observer { companiesPerPlayer.add(new ArrayList<PublicCompanyI>(4)); List<PublicCompanyI> companies; // Sort out which players preside over which companies. - for (PublicCompanyI c : getOperatingCompanies()) { + //for (PublicCompanyI c : getOperatingCompanies()) { + for (PublicCompanyI c : companyManager.getAllPublicCompanies()) { + if (!c.hasFloated()) continue; if (c.isClosed() || c == operatingCompany.get()) continue; p = c.getPresident(); index = p.getIndex(); |
From: Stefan F. <ste...@us...> - 2012-10-02 09:54:11
|
.classpath | 4 .settings/org.eclipse.core.resources.prefs | 3 .settings/org.eclipse.core.runtime.prefs | 3 dev/null |binary make_rails_pkg.sh | 16 src/LocalisedText.properties | 126 src/build.xml | 350 src/buildRails.xml | 171 src/data/1825/CompanyManager.xml | 4 src/data/1825/Game.xml | 5 src/data/1825/Map.xml | 523 src/data/1825/TileSet.xml | 5 src/data/1825/Tiles.xml | 7 src/data/1826/Game.xml | 2 src/data/1830/CompanyManager.xml | 2 src/data/1830/Game.xml | 6 src/data/1830/Map.xml | 12 src/data/1830/TileSet.xml | 1 src/data/1830/Tiles.xml | 55 src/data/1835/CompanyManager.xml | 13 src/data/1835/Game.xml | 13 src/data/1835/Tiles.xml | 36 src/data/1851/CompanyManager.xml | 4 src/data/1851/Game.xml | 6 src/data/1856/CompanyManager.xml | 73 src/data/1856/Game.xml | 39 src/data/1856/Map.xml | 203 src/data/1856/MapImage.svg | 6072 ++ src/data/1856/TileSet.xml | 15 src/data/1856/Tiles.xml | 6 src/data/1870/Game.xml | 2 src/data/1870/TileSet.xml | 2 src/data/1880/CompanyManager.xml | 4 src/data/1880/Game.xml | 6 src/data/1889/CompanyManager.xml | 2 src/data/1889/Game.xml | 1 src/data/1889/Map.xml | 53 src/data/1889/MapImage.svg | 4259 + src/data/18AL/18AL_Map_gamekit.svg | 1435 src/data/18AL/Game.xml | 15 src/data/18AL/Map.xml | 1 src/data/18AL/TileSet.xml | 2 src/data/18EU/CompanyManager.xml | 8 src/data/18EU/Game.xml | 9 src/data/18EU/Map.xml | 4 src/data/18EU/TileSet.xml | 1 src/data/18EU/Tiles.xml | 6 src/data/18GA/Game.xml | 2 src/data/18GA/Map.xml | 274 src/data/18GA/MapImage.svg |18617 ++++++++ src/data/18GA/MapImage_CottonPort.svg |21576 ++++++++++ src/data/18GA/StockMarket.xml | 2 src/data/18JR/CompanyManager.xml | 101 src/data/18JR/Game.xml | 168 src/data/18JR/Map.xml | 65 src/data/18JR/StockMarket.xml | 111 src/data/18JR/TileSet.xml | 128 src/data/18JR/Tiles.xml | 291 src/data/18Kaas/Game.xml | 8 src/data/18Kaas/TileSet.xml | 2 src/data/18Lummer/CompanyManager.xml | 43 src/data/18Lummer/Game.xml | 102 src/data/18Lummer/Map.xml | 17 src/data/18Lummer/StockMarket.xml | 149 src/data/18Lummer/TileSet.xml | 145 src/data/18Lummer/Tiles.xml | 460 src/data/18TN/CompanyManager.xml | 4 src/data/18TN/Game.xml | 11 src/data/18TN/TileSet.xml | 2 src/data/GamesList.xml | 189 src/data/Properties.xml | 58 src/data/profiles/LIST_OF_PROFILES | 7 src/data/profiles/ORDocking.predefined | 7 src/data/profiles/default.profile | 41 src/data/profiles/default.profiles | 2 src/data/profiles/hotseat.predefined | 4 src/data/profiles/pbem.predefined | 4 src/data/profiles/prettyUI.predefined | 13 src/data/profiles/root | 60 src/data/profiles/test | 15 src/data/profiles/test.profile | 125 src/images/icon/green_station.png |binary src/images/icon/green_track.png |binary src/images/icon/grey_station.png |binary src/images/icon/grey_track.png |binary src/images/icon/notile_2towns.png |binary src/images/icon/notile_station.png |binary src/images/icon/russet_station.png |binary src/images/icon/russet_track.png |binary src/images/icon/yellow_station.png |binary src/images/icon/yellow_track.png |binary src/lib/JLayer1.0.1/jl1.0.1jar |binary src/lib/commons-io-2.1/commons-io-2.1.jar |binary src/lib/df_1.1.0/dockingFramesCommon.jar |binary src/lib/df_1.1.0/dockingFramesCore.jar |binary src/manifest | 4 src/rails.bat | 2 src/rails.sh | 2 src/rails/algorithms/RevenueAdapter.java | 3 src/rails/common/Config.java | 55 src/rails/common/ConfigItem.java | 181 src/rails/common/ConfigManager.java | 313 src/rails/common/ConfigProfile.java | 396 src/rails/common/GuiDef.java | 7 src/rails/common/LocalText.java | 1 src/rails/common/MoneyFormatter.java | 1 src/rails/common/parser/Config.java | 608 src/rails/common/parser/ConfigItem.java | 145 src/rails/game/Bank.java | 2 src/rails/game/CompanyManager.java | 19 src/rails/game/GameManager.java | 81 src/rails/game/MapHex.java | 23 src/rails/game/MapManager.java | 52 src/rails/game/OperatingRound.java | 184 src/rails/game/Phase.java | 112 src/rails/game/PublicCompany.java | 212 src/rails/game/RailsRoot.java | 33 src/rails/game/ReportBuffer.java | 9 src/rails/game/ShareSellingRound.java | 43 src/rails/game/StartRound.java | 20 src/rails/game/StartRound_1835.java | 271 src/rails/game/StockMarket.java | 33 src/rails/game/StockRound.java | 268 src/rails/game/StockSpace.java | 13 src/rails/game/Stop.java | 6 src/rails/game/Tile.java | 20 src/rails/game/TrainManager.java | 43 src/rails/game/TreasuryShareRound.java | 53 src/rails/game/action/BuyTrain.java | 7 src/rails/game/action/LayBaseToken.java | 47 src/rails/game/action/LayTile.java | 38 src/rails/game/action/PossibleActions.java | 6 src/rails/game/action/SellShares.java | 75 src/rails/game/correct/ClosePrivate.java | 2 src/rails/game/model/CertificatesModel.java | 51 src/rails/game/model/PortfolioModel.java | 46 src/rails/game/model/ShareDetailsModel.java | 49 src/rails/game/model/ViewUpdate.java | 1 src/rails/game/special/SpecialRight.java | 4 src/rails/game/special/SpecialTileLay.java | 56 src/rails/game/specific/_1825/StockRound_1825.java | 2 src/rails/game/specific/_1835/ElsasModifier.java | 44 src/rails/game/specific/_1835/GameManager_1835.java | 41 src/rails/game/specific/_1835/OperatingRound_1835.java | 59 src/rails/game/specific/_1835/PrussianFormationRound.java | 65 src/rails/game/specific/_1835/StartRound_1835.java | 273 src/rails/game/specific/_1835/StockRound_1835.java | 103 src/rails/game/specific/_1856/CGRFormationRound.java | 56 src/rails/game/specific/_1889/OperatingRound_1889.java | 66 src/rails/game/specific/_18EU/FinalMinorExchangeRound.java | 4 src/rails/game/specific/_18EU/OffBoardRevenueModifier.java | 2 src/rails/game/specific/_18EU/StartCompany_18EU.java | 20 src/rails/game/specific/_18EU/StockRound_18EU.java | 8 src/rails/game/state/Observer.java | 4 src/rails/sound/SoundConfig.java | 104 src/rails/sound/SoundContext.java | 129 src/rails/sound/SoundEventInterpreter.java | 301 src/rails/sound/SoundManager.java | 68 src/rails/sound/SoundPlayer.java | 273 src/rails/ui/images/accept.png |binary src/rails/ui/images/add.png |binary src/rails/ui/images/arrow_redo.png |binary src/rails/ui/images/arrow_undo.png |binary src/rails/ui/images/auction_hammer_gavel.png |binary src/rails/ui/images/bricks.png |binary src/rails/ui/images/button.png |binary src/rails/ui/images/cancel.png |binary src/rails/ui/images/cash_stack.png |binary src/rails/ui/images/clock_add.png |binary src/rails/ui/images/clock_delete.png |binary src/rails/ui/images/coins_in_hand.png |binary src/rails/ui/images/control_fastforward_blue.png |binary src/rails/ui/images/control_play_blue.png |binary src/rails/ui/images/globe_model.png |binary src/rails/ui/images/hand_property.png |binary src/rails/ui/images/information.png |binary src/rails/ui/images/money_add.png |binary src/rails/ui/images/money_bag.png |binary src/rails/ui/images/participation_rate.png |binary src/rails/ui/images/rails32.png |binary src/rails/ui/images/script.png |binary src/rails/ui/images/traffic_lights_green.png |binary src/rails/ui/images/traffic_lights_red.png |binary src/rails/ui/images/traffic_lights_yellow.png |binary src/rails/ui/images/train.png |binary src/rails/ui/swing/AbstractReportWindow.java | 11 src/rails/ui/swing/ConfigWindow.java | 398 src/rails/ui/swing/GUIToken.java | 78 src/rails/ui/swing/GameSetupWindow.java | 167 src/rails/ui/swing/GameStatus.java | 192 src/rails/ui/swing/GameUIManager.java | 382 src/rails/ui/swing/GridPanel.java | 262 src/rails/ui/swing/ImageLoader.java | 27 src/rails/ui/swing/MapPanel.java | 184 src/rails/ui/swing/MessagePanel.java | 103 src/rails/ui/swing/ORPanel.java | 626 src/rails/ui/swing/ORUIManager.java | 476 src/rails/ui/swing/ORWindow.java | 145 src/rails/ui/swing/RemainingTilesWindow.java | 80 src/rails/ui/swing/ReportWindow.java | 2 src/rails/ui/swing/ReportWindowDynamic.java | 66 src/rails/ui/swing/Scale.java | 2 src/rails/ui/swing/SplashWindow.java | 357 src/rails/ui/swing/StartRoundWindow.java | 291 src/rails/ui/swing/StatusWindow.java | 141 src/rails/ui/swing/StockChart.java | 10 src/rails/ui/swing/TokenIcon.java | 15 src/rails/ui/swing/UpgradesPanel.java | 232 src/rails/ui/swing/WindowSettings.java | 7 src/rails/ui/swing/elements/ActionButton.java | 8 src/rails/ui/swing/elements/Caption.java | 10 src/rails/ui/swing/elements/CheckBoxDialog.java | 111 src/rails/ui/swing/elements/ConfirmationDialog.java | 112 src/rails/ui/swing/elements/DockingFrame.java | 409 src/rails/ui/swing/elements/Field.java | 108 src/rails/ui/swing/elements/GUIStockSpace.java | 21 src/rails/ui/swing/elements/MessageDialog.java | 83 src/rails/ui/swing/elements/NonModalDialog.java | 132 src/rails/ui/swing/elements/RadioButtonDialog.java | 113 src/rails/ui/swing/elements/RailsIcon.java | 127 src/rails/ui/swing/elements/RailsIconButton.java | 139 src/rails/ui/swing/gamespecific/_1835/GameUIManager_1835.java | 46 src/rails/ui/swing/gamespecific/_1835/StatusWindow_1835.java | 33 src/rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java | 27 src/rails/ui/swing/gamespecific/_1880 | 7 src/rails/ui/swing/gamespecific/_18EU/GameStatus_18EU.java | 8 src/rails/ui/swing/gamespecific/_18EU/GameUIManager_18EU.java | 182 src/rails/ui/swing/hexmap/GUIHex.java | 261 src/rails/ui/swing/hexmap/GUITile.java | 137 src/rails/ui/swing/hexmap/HexHighlightMouseListener.java | 243 src/rails/ui/swing/hexmap/HexMap.java | 721 src/rails/ui/swing/hexmap/HexMapImage.java | 160 src/rails/util/GameFileIO.java | 230 src/rails/util/RunGame.java | 23 src/rails/util/SystemOS.java | 117 src/rails/util/Util.java | 47 src/readme.txt | 13 src/test/SVGApplication.java | 105 src/test/SVGOffscreenLoader.java | 192 src/test/TestGame.java | 2 src/test/TestGameBuilder.java | 8 src/test/data/bugs/1830CF_obsoleteTrains.rails |binary src/test/data/bugs/1830CF_obsoleteTrains.report | 432 src/test/data/bugs/1830_sellPresidency.rails |binary src/test/data/bugs/1830_sellPresidency.report | 408 src/test/data/bugs/1835_changePresidentAtStart.rails |binary src/test/data/bugs/1835_changePresidentAtStart.report | 54 src/test/data/bugs/1856_tokens.rails |binary src/test/data/bugs/1856_tokens.report | 1034 src/test/data/bugs/1889_presidentContribution.rails |binary src/test/data/bugs/1889_presidentContribution.report | 1048 src/test/data/real/1830_A.report | 3 src/test/data/real/1856_A.report | 3 src/test/data/real/1889_A.report | 2 src/test/data/real/1889_B.report | 3 src/test/data/real/1889_C.report | 3 src/test/data/real/18AL_A.report | 1 src/test/data/real/18EU_A.report | 2099 src/test/data/real/18TN_A.rails |binary src/test/data/real/18TN_A.report | 616 src/test/data/test/1830_5forDtrainExchange.report | 3 src/test/data/test/1830_SellFullPresCert.rails |binary src/test/data/test/1830_SellFullPresCert.report | 268 src/test/data/test/1830_SellHalfPresCert.rails |binary src/test/data/test/1830_SellHalfPresCert.report | 268 src/test/data/test/1835_NatDoubleShare.rails |binary src/test/data/test/1835_NatDoubleShare.report | 884 src/test/data/test/1835_NatSingleShare.rails |binary src/test/data/test/1835_NatSingleShare.report | 348 src/test/data/test/1835_PR_3rdTrain.report | 1060 src/test/data/test/1835_SellDoubleShare.rails |binary src/test/data/test/1835_SellDoubleShare.report | 1643 src/test/data/test/1835_SwapPresForDoubleShare.rails |binary src/test/data/test/1835_SwapPresForDoubleShare.report | 348 src/test/data/test/1851_Late.report | 2 src/test/data/test/1856_2nd6T+PrezCash2.report | 3 src/tiles/HandmadeTiles.xml | 5 src/tiles/TileDictionary.18t | 2 src/tiles/TileDictionary.xml | 2 src/tiles/Tiles.xml | 212 src/tiles/svg/tile-25017.svg | 6 src/tiles/svg/tile-25018.svg | 6 src/tiles/svg/tile-4000.svg | 6 src/tiles/svg/tile-4004.svg | 6 src/tiles/svg/tile-4005.svg | 6 src/tools/ConvertTilesXML.java | 98 src/tools/ListAndFixSavedFiles.java | 268 src/tools/formatxml.pl | 23 src/version.number | 5 289 files changed, 71474 insertions(+), 9500 deletions(-) New commits: commit bc91566270779d8a245d05219b01392563cab91b Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 12:20:16 2012 +0200 prepared for release 1.7.10 (cherry picked from commit ef4e13ac6c9dba970ff8e7720098eaf7d0d9a552) diff --git a/src/readme.txt b/src/readme.txt index ba355d5..5ef8bbc 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -1,4 +1,4 @@ -Rails release 1.7.9: +Rails release 1.7.10: A new maintenance release for Rails 1.x series @@ -6,8 +6,8 @@ This release fixes two bugs. Contributors: Stefan Frey -Bugs reported by Arne Ãsterlund +Bugs reported by theos and Russel J. Alphey Lists of bugs fixed: -- List of recent files does not work with few entries -- 1830 Coalfields (and others): Obsolete Trains in Pool should rust (previously the stayed forever) +- fixed bug in starting a company in 18EU if only one start price is possible +- fixed bug that the ReportWindow does not scroll down at game start \ No newline at end of file diff --git a/src/version.number b/src/version.number index 385bed2..2ab2e9d 100644 --- a/src/version.number +++ b/src/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.9 +version=1.7.10 # 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 9198df6e602f5195f1f38e65c412f668aabae76e Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 10:45:27 2012 +0200 fixed bug that the ReportWindow does not scrolldown at gameStart, added invokeLater to scrollDown to run in EDT, reported by Russel J. Alphey (cherry picked from commit 31879bbddbab1a44403379a4ab34004c3c903d53) diff --git a/src/rails/ui/swing/ReportWindowDynamic.java b/src/rails/ui/swing/ReportWindowDynamic.java index bed9f8e..2752af9 100644 --- a/src/rails/ui/swing/ReportWindowDynamic.java +++ b/src/rails/ui/swing/ReportWindowDynamic.java @@ -181,21 +181,25 @@ public class ReportWindowDynamic extends AbstractReportWindow implements Action @Override public void scrollDown() { // only set caret if visible - if (!this.isVisible()) return; + //if (!this.isVisible()) return; // find the active message in the parsed html code (not identical to the position in the html string) // thus the message indicator is used - int caretPosition; - try{ - String docText = editorPane.getDocument().getText(0, editorPane.getDocument().getLength()); - caretPosition = docText.indexOf(ReportBuffer.ACTIVE_MESSAGE_INDICATOR); - } catch (BadLocationException e){ - caretPosition = -1; - }; - final int caretPositionStore = caretPosition; - if (caretPosition != -1) { - editorPane.setCaretPosition(caretPositionStore); - } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + int caretPosition; + try{ + String docText = editorPane.getDocument().getText(0, editorPane.getDocument().getLength()); + caretPosition = docText.indexOf(ReportBuffer.ACTIVE_MESSAGE_INDICATOR); + } catch (BadLocationException e){ + caretPosition = -1; + }; + final int caretPositionStore = caretPosition; + if (caretPosition != -1) { + editorPane.setCaretPosition(caretPositionStore); + } + } + }); } public void actionPerformed(ActionEvent e) { commit afd21447aa9d4ae35f7e00f77c7a6be2b8690816 Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 10:35:49 2012 +0200 fixed bug in starting a company in 18EU if only one start price is possible, bug reported by theos (cherry picked from commit 4c1d24f937619baccda7e76d141a621319282d3d) Conflicts: src/rails/ui/swing/GameStatus.java diff --git a/src/rails/ui/swing/GameStatus.java b/src/rails/ui/swing/GameStatus.java index 9a5e758..0450dfd 100644 --- a/src/rails/ui/swing/GameStatus.java +++ b/src/rails/ui/swing/GameStatus.java @@ -18,6 +18,7 @@ import rails.game.*; import rails.game.action.*; import rails.game.correct.CashCorrectionAction; import rails.game.model.PortfolioModel; +import rails.game.specific._18EU.StartCompany_18EU; import rails.sound.SoundManager; import rails.ui.swing.elements.*; import rails.ui.swing.hexmap.HexHighlightMouseListener; @@ -769,7 +770,8 @@ public class GameStatus extends GridPanel implements ActionListener { } } int index = 0; - if (options.size() > 1) { + // check for instanceof StartCompany_18EU allows to continue with selecting the minor + if (options.size() > 1 || actions.get(0) instanceof StartCompany_18EU) { if (startCompany) { RadioButtonDialog dialog = new RadioButtonDialog ( GameUIManager.COMPANY_START_PRICE_DIALOG, commit 81f16a283eadc74d8aea660409b63a82eeb490ba Author: Stefan Frey <ste...@we...> Date: Mon Sep 17 20:18:41 2012 +0200 prepared for 1.7.9 release (cherry picked from commit 2a12d199876712dd7e83f5ed491e05365e644b5a) diff --git a/src/readme.txt b/src/readme.txt index 111a7c4..ba355d5 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -1,13 +1,13 @@ -Rails release 1.7.8: +Rails release 1.7.9: A new maintenance release for Rails 1.x series -This release fixes several bugs. +This release fixes two bugs. -Contributors: Erik Vos, Stefan Frey +Contributors: Stefan Frey -Bugs reported by Martin Brumm, John David Galt +Bugs reported by Arne Ãsterlund Lists of bugs fixed: -- All Games: Update "PD" label in GameStatus lower player names panel -- 1835 (and others with NoMapMode): Cannot save game file with ClosePrivate action +- List of recent files does not work with few entries +- 1830 Coalfields (and others): Obsolete Trains in Pool should rust (previously the stayed forever) diff --git a/src/version.number b/src/version.number index f74a335..385bed2 100644 --- a/src/version.number +++ b/src/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.8 +version=1.7.9 # 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 2dd67fc4bc701adad9b5e9998d33f0b13b7ef01b Author: Stefan Frey <ste...@we...> Date: Mon Sep 17 18:47:13 2012 +0200 fixed problem of obsoleting trains in the pool, as reported by arne oestlund (cherry picked from commit 1cb73edf9ec9657eaac3665cf7db57908556e88f) Conflicts: rails/game/TrainManager.java diff --git a/src/rails/game/TrainManager.java b/src/rails/game/TrainManager.java index 289491d..02b3d0e 100644 --- a/src/rails/game/TrainManager.java +++ b/src/rails/game/TrainManager.java @@ -328,6 +328,8 @@ public class TrainManager extends RailsManager implements Configurable { private boolean isTrainObsolete(Train train, Owner lastBuyingCompany) { // check fist if train can obsolete at all if (!train.getCertType().isObsoleting()) return false; + // and if it is in the pool (always rust) + if (train.getOwner() == pool.getParent()) return false; // then check if obsolete type if (obsoleteTrainFor == ObsoleteTrainForType.ALL) { commit 68d5723375b9b4a73adf03ea7af7f7b31738d27c Author: Stefan Frey <ste...@we...> Date: Mon Sep 10 15:29:29 2012 +0200 fixed recent file list bug (cherry picked from commit 0eeb12fa8e0383287abe41d85a8dfc311a0e6126) Commit was already included, kept for reference. commit 78c45672597422a92362e0f1c424782c2cbc74d7 Author: Stefan Frey <ste...@we...> Date: Mon Jul 23 17:01:38 2012 +0200 prepared for 1.7.8 release (cherry picked from commit 18c0f865fc235df7a4d370114d3d26cb3eff4f76) diff --git a/src/readme.txt b/src/readme.txt index 33de310..111a7c4 100644 --- a/src/readme.txt +++ b/src/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/src/version.number b/src/version.number index 60520e3..f74a335 100644 --- a/src/version.number +++ b/src/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 d0c93922e840fca16e8c628e654e53e411b3b6d7 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) (cherry picked from commit 59d48a43689c5128a9487290d0682e0961201c6e) Conflicts: src/rails/ui/swing/GameStatus.java diff --git a/src/rails/ui/swing/GameStatus.java b/src/rails/ui/swing/GameStatus.java index 9e22716..9a5e758 100644 --- a/src/rails/ui/swing/GameStatus.java +++ b/src/rails/ui/swing/GameStatus.java @@ -977,8 +977,9 @@ public class GameStatus extends GridPanel implements ActionListener { public void setPriorityPlayer(int index) { for (int j = 0; j < np; j++) { - upperPlayerCaption[j].setText(players[j].getId() - + (j == index ? " PD" : "")); + String playerNameAndPriority = players[j].getId() + (j == index ? " PD" : ""); + upperPlayerCaption[j].setText(playerNameAndPriority); + lowerPlayerCaption[j].setText(playerNameAndPriority); } } commit 5d1855c07242cdad121ee11c6a210c3a55cd946c 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 (cherry picked from commit b564e00983be9033464fd3e0658d61143ab5bf5f) Conflicts: src/rails/game/correct/ClosePrivate.java diff --git a/src/rails/game/correct/ClosePrivate.java b/src/rails/game/correct/ClosePrivate.java index 0ffea43..7a10c3e 100644 --- a/src/rails/game/correct/ClosePrivate.java +++ b/src/rails/game/correct/ClosePrivate.java @@ -18,7 +18,7 @@ public class ClosePrivate extends PossibleAction { /* Preconditions */ /** private company to close */ - private PrivateCompany privateCompany; + transient private PrivateCompany privateCompany; /** converted to name */ private String privateCompanyName; commit c910d16695395424919bc5312cfebf04b95d18d3 Author: Stefan Frey <ste...@we...> Date: Fri Jun 15 17:35:37 2012 +0200 prepared for release 1.7.7 (cherry picked from commit 90ba59260b14c2a7d5f14a37c730d7d0cc5e0baf) diff --git a/src/readme.txt b/src/readme.txt index a1180ee..33de310 100644 --- a/src/readme.txt +++ b/src/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/src/version.number b/src/version.number index cde0424..60520e3 100644 --- a/src/version.number +++ b/src/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 65107299650c9c09229f3f88bf03f952eb494115 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) (cherry picked from commit bf16424ac310389b5b48fabfc11a86a6f2a93a29) Conflicts: src/rails/util/GameFileIO.java diff --git a/src/rails/util/GameFileIO.java b/src/rails/util/GameFileIO.java index 7e97190..f4feece 100644 --- a/src/rails/util/GameFileIO.java +++ b/src/rails/util/GameFileIO.java @@ -227,16 +227,17 @@ public class GameFileIO { gameManager.setReloading(true); int count = -1; - // set possible actions for first action - gameManager.getCurrentRound().setPossibleActions(); - - 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) { + // set possible actions for first action + gameManager.getCurrentRound().setPossibleActions(); + 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 58a2f91d034602a80a8b25970bacb3137d3bfc0f 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) (cherry picked from commit 3892c7f2d7d9685cc3a1e5b69e4be900fe7bc4e7) Includes change of method signature of Stop.getBaseTokens() to ImmutableSet Conflicts: src/rails/ui/swing/ORUIManager.java diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 206496f..c533027 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -971,7 +971,7 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable { if (mStops == null || mStops.isEmpty()) return null; ImmutableSet.Builder<BaseToken> tokens = ImmutableSet.builder(); for (Stop city : mStops) { - tokens.addAll(city.getBaseTokens().items()); + tokens.addAll(city.getBaseTokens()); } return tokens.build(); } @@ -1019,7 +1019,7 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable { public ImmutableSet<BaseToken> getTokens(int cityNumber) { // TODO: Is the test for null still required if (mStops.size() > 0 && mStops.get(cityNumber) != null) { - return (mStops.get(cityNumber)).getBaseTokens().items(); + return (mStops.get(cityNumber)).getBaseTokens(); } else { return ImmutableSet.of(); // empty set } diff --git a/src/rails/game/Stop.java b/src/rails/game/Stop.java index 9a2f398..df104d3 100644 --- a/src/rails/game/Stop.java +++ b/src/rails/game/Stop.java @@ -3,6 +3,8 @@ package rails.game; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableSet; + import rails.game.state.GenericState; import rails.game.state.Owner; import rails.game.state.PortfolioSet; @@ -213,8 +215,8 @@ public class Stop extends RailsAbstractItem implements Owner { initStopProperties(); } - public PortfolioSet<BaseToken> getBaseTokens() { - return tokens; + public ImmutableSet<BaseToken> getBaseTokens() { + return tokens.items(); } public boolean hasTokens() { diff --git a/src/rails/ui/swing/ORUIManager.java b/src/rails/ui/swing/ORUIManager.java index e07708d..4cd507c 100644 --- a/src/rails/ui/swing/ORUIManager.java +++ b/src/rails/ui/swing/ORUIManager.java @@ -963,16 +963,20 @@ public class ORUIManager implements DialogOwner { * 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] + * + * TODO: (Rails2.0) Check if this still works */ 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 = Iterables.get(s1.getBaseTokens(), 0).getParent().getHomeHexes().contains(hex); - boolean home2 = Iterables.get(s2.getBaseTokens(), 0).getParent().getHomeHexes().contains(hex); - if (home1 && !home2) { + Set<BaseToken> tokens; + boolean stop1IsHome = !((tokens = s1.getBaseTokens()).isEmpty()) + && Iterables.get(tokens, 0).getParent().getHomeHexes().contains(hex); + boolean stop2IsHome = !((tokens = s2.getBaseTokens()).isEmpty()) + && Iterables.get(tokens, 0).getParent().getHomeHexes().contains(hex); + if (stop1IsHome && !stop2IsHome) { return -1; - } else if (home2 && !home1) { + } else if (stop2IsHome && !stop1IsHome) { return 1; } else { return 0; // Doesn't matter @@ -991,7 +995,7 @@ public class ORUIManager implements DialogOwner { if (oldStop.hasTokens()) { // Assume only 1 token (no exceptions known) // TODO: Rewrite this to make this code nicer - PublicCompany company = (Iterables.get(oldStop.getBaseTokens().items(), 0)).getParent(); + PublicCompany company = (Iterables.get(oldStop.getBaseTokens(), 0)).getParent(); List<String> prompts = new ArrayList<String>(); Map<String, Integer> promptToCityMap = new HashMap<String, Integer>(); commit d91e830cc4130ed708e769b4e9ad521127e7b4ff 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 (cherry picked from commit 18b22dec3aeaa01d27250baf5b7dc0256c777d64) Conflicts: src/rails/ui/swing/ORUIManager.java diff --git a/src/data/1835/CompanyManager.xml b/src/data/1835/CompanyManager.xml index 9f28099..bfdbb7f 100644 --- a/src/data/1835/CompanyManager.xml +++ b/src/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/src/rails/ui/swing/ORUIManager.java b/src/rails/ui/swing/ORUIManager.java index 35ca9b0..e07708d 100644 --- a/src/rails/ui/swing/ORUIManager.java +++ b/src/rails/ui/swing/ORUIManager.java @@ -941,12 +941,53 @@ public class ORUIManager implements DialogOwner { */ protected void relayBaseTokens (LayTile action) { - MapHex hex = action.getChosenHex(); + final MapHex hex = action.getChosenHex(); Tile newTile = action.getLaidTile(); Tile 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 = Iterables.get(s1.getBaseTokens(), 0).getParent().getHomeHexes().contains(hex); + boolean home2 = Iterables.get(s2.getBaseTokens(), 0).getParent().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) // TODO: Rewrite this to make this code nicer @@ -956,7 +997,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( @@ -992,8 +1033,10 @@ public class ORUIManager implements DialogOwner { prompts.toArray(), prompts.get(0)); if (selected == null) return; action.addRelayBaseToken(company.getId(), promptToCityMap.get(selected)); + --freeSlots[promptToCityMap.get(selected)]; } else { action.addRelayBaseToken(company.getId(), promptToCityMap.get(prompts.toArray() [0])); + --freeSlots[promptToCityMap.get(prompts.toArray()[0])]; } } } commit 41575ef06b40d98705a3dfe6ff36f27fe12e37be 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 (cherry picked from commit 1686fd33004bbef7c25eeabab96e649f8d1849f8) Conflicts: src/rails/game/ReportBuffer.java diff --git a/src/rails/game/ReportBuffer.java b/src/rails/game/ReportBuffer.java index 8e9751b..53e9767 100644 --- a/src/rails/game/ReportBuffer.java +++ b/src/rails/game/ReportBuffer.java @@ -333,7 +333,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.getId() + " says: ' "); + // at gamestart no player is defined, this is a bug-fix + if (item.player == null) { + s.append("'"); + } else { + s.append(item.player.getId() + " says: '"); + } s.append(comment + "'" + NEWLINE_STRING); s.append("</span>"); } commit 309e95ba38a50e10a77f93081fb100141bf95ac2 Author: Stefan Frey <ste...@we...> Date: Wed Jun 13 19:42:52 2012 +0200 removed the limitation text for the 1830 coalfield variant (cherry picked from commit ae10a615c47ca248f0f7d9a5c2c5c38946ced196) diff --git a/src/data/GamesList.xml b/src/data/GamesList.xml index 3674b65..06fe440 100644 --- a/src/data/GamesList.xml +++ b/src/data/GamesList.xml @@ -12,11 +12,6 @@ Coalfields variant by Alan R. Moon Limitations: - The M&H/NYC share swap can only be executed in the SR, in the owning player's turn. - Privates cannot be traded between players. -- The Coalfields variant is playable with the following workarounds: - - Coalfield certificates cannot yet be bought. Execute a Cash Correction to mimic this action. - - Route and revenue calculation will always include the Coalfields, if reachable. - If you have not bought a Coalfields certificate, you'll have to calculate the correct revenue - yourself, and enter it manually. </Description> <!-- GAME OPTIONS must have: - a name, which must also exist as an entry in LocalText.properties, commit 44d3ab262ef9cc7b61afee69a260b803de7a75b1 Author: Stefan Frey <ste...@we...> Date: Tue Jun 12 08:37:03 2012 +0200 1835: Allow manual close of Pfalzbahn (supports play after rules interpretation by John David Galt) (cherry picked from commit b8b5db220ec42180d2799567e6f9343e1207a6c8) diff --git a/src/data/1835/CompanyManager.xml b/src/data/1835/CompanyManager.xml index baa4fd8..9f28099 100644 --- a/src/data/1835/CompanyManager.xml +++ b/src/data/1835/CompanyManager.xml @@ -70,6 +70,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> + <CloseManually/> <!-- If tile is laid not via special property--> </ClosingConditions> </Company> <Company name="LD" longname="Leipzig-Dresdner Bahn" type="Private" basePrice="190"> commit fa2dc21691fa5a95753714b1b30f8bd2929e8b09 Author: Stefan Frey <ste...@we...> Date: Wed Jun 6 18:06:51 2012 +0200 added little fun variant 18Lummer (cherry picked from commit 29aeea878329201b84d6238f7b5fd78f0c7d084f) diff --git a/src/data/18Lummer/CompanyManager.xml b/src/data/18Lummer/CompanyManager.xml new file mode 100644 index 0000000..6d3339d --- /dev/null +++ b/src/data/18Lummer/CompanyManager.xml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<CompanyManager> + <CompanyType name="Private" class="rails.game.PrivateCompany"> + <ClosingConditions> + <Phase>5</Phase> + </ClosingConditions> + <Tradeable toCompany="yes" lowerPriceFactor="0.5" upperPriceFactor="2.0"/> + <Tradeable toPlayer="yes"/> + </CompanyType> + <CompanyType name="Public" class="rails.game.PublicCompany"> + <CanBuyPrivates/> + <PoolPaysOut/> + <Float percentage="60"/> + <ShareUnit percentage="10"/> + <BaseTokens> + <!-- HomeBase lay options: "whenStarted", "whenFloated", "firstOR" (default) --> + <HomeBase lay="firstOR"/> + <!-- LayCost methods: only "sequence" (1830 style) implemented so far (default) --> + <LayCost method="sequence" cost="0,40"/> + </BaseTokens> + <Certificate type="President" shares="2"/> + <Certificate shares="1" number="8"/> + <Trains limit="4,3,2"/> + <CanUseSpecialProperties/> + </CompanyType> + <Company name="Post" type="Private" basePrice="20" revenue="5" + longname="Postschiff" /> + <Company name="JK" type="Public" tokens="2" fgColour="255,255,255" bgColour="0,0,255" + longname="Jim Knopf"> + <Home hex="C4"/> + </Company> + <Company name="LL" type="Public" tokens="2" fgColour="FFFFFF" bgColour="FF0000" + longname="Lukas Lokomotivfuehrer"> + <Home hex="C8"/> + </Company> + <StartPacket roundClass="rails.game.StartRound_1830"> + <Bidding initial="5" minimum="5" increment="1"/> + <Item name="Post" type="Private" basePrice="20"/> + </StartPacket> +</CompanyManager> + + + \ No newline at end of file diff --git a/src/data/18Lummer/Game.xml b/src/data/18Lummer/Game.xml new file mode 100644 index 0000000..79fc4ac --- /dev/null +++ b/src/data/18Lummer/Game.xml @@ -0,0 +1,102 @@ +<?xml version="1.0"?> +<ComponentManager> + <Component name="GameManager" class="rails.game.GameManager"> + <Game name="18Lummer"/> + <GameOption name="RouteAwareness" values="Highlight,Deactivate" default="Highlight" /> + <GameOption name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest" /> + + <GameParameters> + <PlayerShareLimit percentage="60"> + <!-- Option "NumberOfPlayers" is automatically set + by the game engine --> + <IfOption name="NumberOfPlayers" value="2"> + <IfOption name="TwoPlayersCertLimit70Percent" value="yes"> + <Attributes percentage="70"/> + </IfOption> + </IfOption> + </PlayerShareLimit> + <BankPoolLimit percentage="50"/> + <StockRound> + <NoSaleInFirstSR/> + </StockRound> + <OperatingRound> + <EmergencyTrainBuying mustBuyCheapestTrain="no" mayBuyFromCompany="yes"/> + </OperatingRound> + </GameParameters> + <EndOfGame> + <Bankruptcy/> + <BankBreaks limit="0" finish="setOfORs"/> + <!-- "Runs out"; when "broken", -1 is the limit --> + </EndOfGame> + </Component> + <Component name="PlayerManager" class="rails.game.PlayerManager"> + <Players number="2" cash="600" certLimit="28"/> + <Players number="3" cash="400" certLimit="20"/> + <Players number="4" cash="300" certLimit="16"/> + </Component> + <Component name="Bank" class="rails.game.Bank"> + <Bank amount="2000"/> + <Money format="$@"/> + </Component> + <Component name="TileManager" class="rails.game.TileManager" + file="TileSet.xml"/> + <Component name="Map" class="rails.game.MapManager" file="Map.xml"/> + <Component name="CompanyManager" class="rails.game.CompanyManager" + file="CompanyManager.xml"/> + <Component name="StockMarket" class="rails.game.StockMarket" + file="StockMarket.xml"/> + <Component name="TrainManager" class="rails.game.TrainManager"> + <Defaults> + <Reach base="stops" countTowns="yes"/> + <Score towns="yes"/> + </Defaults> + <TrainType name="2" majorStops="2" cost="80" quantity="2"/> + <TrainType name="3" majorStops="3" cost="180" quantity="1"> + <NewPhase phaseName="3"/> + </TrainType> + <TrainType name="4" majorStops="4" cost="300" quantity="1"> + <NewPhase phaseName="4"/> + </TrainType> + <TrainType name="5" majorStops="5" cost="450" quantity="1"> + <NewPhase phaseName="5"/> + </TrainType> + <TrainType name="6" majorStops="6" cost="630" quantity="1"> + <NewPhase phaseName="6"/> + </TrainType> + <TrainType name="D" majorStops="99" cost="1100" quantity="1"> + <NewPhase phaseName="D"/> + <Exchange cost="800"/> + </TrainType> + </Component> + <Component name="PhaseManager" class="rails.game.PhaseManager"> + <Phase name="2" > + <Tiles colour="yellow"/> + <Privates sellingAllowed="no"/> + <OperatingRounds number="1"/> + <Trains onePerTurn="yes" tradingAllowed="yes"/> + </Phase> + <Phase name="3"> + <Tiles colour="yellow,green"/> + <Privates sellingAllowed="yes"/> + <OperatingRounds number="2"/> + </Phase> + <Phase name="4"> + <Trains rusted="2" limitStep="2"/> + </Phase> + <Phase name="5"> + <Tiles colour="yellow,green,brown"/> + <Trains limitStep="3"/> + <!--Privates close="yes"/--> + <OperatingRounds number="3"/> + <OffBoardRevenue step="2"/> + </Phase> + <Phase name="6"> + <Trains rusted="3"> + <Attributes released="D"/> + </Trains> + </Phase> + <Phase name="D"> + <Trains rusted="4"/> + </Phase> + </Component> +</ComponentManager> diff --git a/src/data/18Lummer/Map.xml b/src/data/18Lummer/Map.xml new file mode 100644 index 0000000..4c7ecb8 --- /dev/null +++ b/src/data/18Lummer/Map.xml @@ -0,0 +1,17 @@ +<Map tileOrientation="EW" letterOrientation="vertical" even="A"> + <Defaults> + <Access type="city" runTo="yes" runThrough="yes" loop="yes" score="major"/> + <Access type="town" runTo="yes" runThrough="yes" loop="yes" score="minor"/> + </Defaults> + <!-- The above defaults are redundant, these settings are the system defaults anyway --> + <Hex name="B3" tile="-7" orientation="0"/> + <Hex name="B5" tile="-1" /> + <Hex name="B7" tile="0" /> + <Hex name="B9" tile="-7" orientation="2"/> + <Hex name="C4" tile="-10" /> + <Hex name="C6" tile="-20" cost="120" /> + <Hex name="C8" tile="-10" /> + <Hex name="D5" tile="0" /> + <Hex name="D7" tile="-1" /> + <Hex name="E6" tile="-7" orientation="4"/> +</Map> \ No newline at end of file diff --git a/src/data/18Lummer/StockMarket.xml b/src/data/18Lummer/StockMarket.xml new file mode 100755 index 0000000..770d885 --- /dev/null +++ b/src/data/18Lummer/StockMarket.xml @@ -0,0 +1,149 @@ +<StockMarket type="rectangular"> + <!-- Note two supported colour specification formats: + RGB decimal with commas and RGB hexadecimal without commas --> + <StockSpaceType name="yellow" colour="255,255,0"> + <NoCertLimit/> + </StockSpaceType> + <StockSpaceType name="orange" colour="FF8000"> + <NoCertLimit/> + <NoHoldLimit/> + </StockSpaceType> + <StockSpaceType name="brown" colour="884000"> + <NoCertLimit/> + <NoHoldLimit/> + <NoBuyLimit/> + </StockSpaceType> + + <StockSpace name="A1" price="60" type="yellow"/> + <StockSpace name="A2" price="53" type="yellow"/> + <StockSpace name="A3" price="46" type="yellow"/> + <StockSpace name="A4" price="39" type="orange"/> + <StockSpace name="A5" price="32" type="orange"/> + <StockSpace name="A6" price="25" type="brown"/> + <StockSpace name="A7" price="18" type="brown"/> + <StockSpace name="A8" price="10" type="brown"/> + <StockSpace name="B1" price="67" /> + <StockSpace name="B2" price="60" type="yellow"/> + <StockSpace name="B3" price="55" type="yellow"/> + <StockSpace name="B4" price="48" type="yellow"/> + <StockSpace name="B5" price="41" type="orange"/> + <StockSpace name="B6" price="34" type="orange"/> + <StockSpace name="B7" price="27" type="brown"/> + <StockSpace name="B8" price="20" type="brown"/> + <StockSpace name="B9" price="10" type="brown"/> + <StockSpace name="C1" price="71" /> + <StockSpace name="C2" price="66" /> + <StockSpace name="C3" price="60" type="yellow"/> + <StockSpace name="C4" price="54" type="yellow"/> + <StockSpace name="C5" price="48" type="yellow"/> + <StockSpace name="C6" price="42" type="orange"/> + <StockSpace name="C7" price="36" type="orange"/> + <StockSpace name="C8" price="30" type="brown"/> + <StockSpace name="C9" price="20" type="brown"/> + <StockSpace name="C10" price="10" type="brown"/> + <StockSpace name="D1" price="76" /> + <StockSpace name="D2" price="70" /> + <StockSpace name="D3" price="65" /> + <StockSpace name="D4" price="60" type="yellow"/> + <StockSpace name="D5" price="55" type="yellow"/> + <StockSpace name="D6" price="50" type="yellow"/> + <StockSpace name="D7" price="45" type="orange"/> + <StockSpace name="D8" price="40" type="orange"/> + <StockSpace name="D9" price="30" type="brown"/> + <StockSpace name="D10" price="20" type="brown"/> + <StockSpace name="D11" price="10" type="brown"/> + <StockSpace name="E1" price="82" /> + <StockSpace name="E2" price="76" /> + <StockSpace name="E3" price="70" /> + <StockSpace name="E4" price="66" /> + <StockSpace name="E5" price="62" /> + <StockSpace name="E6" price="58" type="yellow"/> + <StockSpace name="E7" price="54" type="yellow"/> + <StockSpace name="E8" price="50" type="yellow"/> + <StockSpace name="E9" price="40" type="orange"/> + <StockSpace name="E10" price="30" type="brown"/> + <StockSpace name="E11" price="20" type="brown"/> + <StockSpace name="F1" price="90" /> + <StockSpace name="F2" price="82" /> + <StockSpace name="F3" price="76" /> + <StockSpace name="F4" price="71" /> + <StockSpace name="F5" price="67" /> + <StockSpace name="F6" price="65" /> + <StockSpace name="F7" price="63" /> + <StockSpace name="F8" price="60" type="yellow"/> + <StockSpace name="F9" price="50" type="yellow"/> + <StockSpace name="F10" price="40" type="orange"/> + <StockSpace name="F11" price="30" type="brown"/> + <StockSpace name="G1" price="100" > + <StartSpace/> + </StockSpace> + <StockSpace name="G2" price="90" > + <StartSpace/> + </StockSpace> + <StockSpace name="G3" price="82" > + <StartSpace/> + </StockSpace> + <StockSpace name="G4" price="76" > + <StartSpace/> + </StockSpace> + <StockSpace name="G5" price="71" > + <StartSpace/> + </StockSpace> + <StockSpace name="G6" price="67" > + <StartSpace/> + </StockSpace> + <StockSpace name="G7" price="67" /> + <StockSpace name="G8" price="67" /> + <StockSpace name="G9" price="60" type="yellow"/> + <StockSpace name="G10" price="50" type="yellow"/> + <StockSpace name="G11" price="40" type="orange"/> + <StockSpace name="H1" price="112" /> + <StockSpace name="H2" price="100" /> + <StockSpace name="H3" price="90" /> + <StockSpace name="H4" price="82" /> + <StockSpace name="H5" price="76" /> + <StockSpace name="H6" price="71" /> + <StockSpace name="H7" price="69" /> + <StockSpace name="H8" price="68" /> + <StockSpace name="I1" price="126" /> + <StockSpace name="I2" price="112" /> + <StockSpace name="I3" price="100" /> + <StockSpace name="I4" price="90" /> + <StockSpace name="I5" price="82" /> + <StockSpace name="I6" price="75" /> + <StockSpace nam... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-10-02 09:48:20
|
.classpath | 4 dev/null |binary rails.bat | 2 rails.sh | 3 rails/ui/swing/gamespecific/_1880/StartRoundWindow_1880.java | 7 src/LocalisedText.properties | 115 src/build.xml | 350 src/buildRails.xml | 171 src/data/1830/CompanyManager.xml | 2 src/data/1830/Game.xml | 4 src/data/1830/Map.xml | 12 src/data/1830/TileSet.xml | 1 src/data/1830/Tiles.xml | 5 src/data/1835/CompanyManager.xml | 12 src/data/1835/Game.xml | 3 src/data/1856/CompanyManager.xml | 73 src/data/1856/Game.xml | 37 src/data/1856/Map.xml | 203 src/data/1856/MapImage.svg | 6072 ++ src/data/1856/TileSet.xml | 15 src/data/1856/Tiles.xml | 6 src/data/1889/CompanyManager.xml | 2 src/data/1889/Map.xml | 53 src/data/1889/MapImage.svg | 4259 + src/data/18AL/Game.xml | 13 src/data/18AL/Map.xml | 2 src/data/18EU/Map.xml | 2 src/data/18EU/TileSet.xml | 1 src/data/18EU/Tiles.xml | 6 src/data/18GA/Map.xml | 280 src/data/18GA/MapImage_CottonPort.svg |21576 ++++++++++ src/data/18Kaas/Game.xml | 6 src/data/18Lummer/CompanyManager.xml | 43 src/data/18Lummer/Game.xml | 102 src/data/18Lummer/Map.xml | 17 src/data/18Lummer/StockMarket.xml | 149 src/data/18Lummer/TileSet.xml | 145 src/data/18Lummer/Tiles.xml | 460 src/data/18TN/Game.xml | 4 src/data/GamesList.xml | 91 src/data/Properties.xml | 58 src/data/profiles/LIST_OF_PROFILES | 7 src/data/profiles/ORDocking.predefined | 7 src/data/profiles/default.profile | 41 src/data/profiles/default.profiles | 2 src/data/profiles/hotseat.predefined | 4 src/data/profiles/pbem.predefined | 4 src/data/profiles/prettyUI.predefined | 13 src/data/profiles/root | 60 src/data/profiles/test | 15 src/data/profiles/test.profile | 125 src/images/icon/green_station.png |binary src/images/icon/green_track.png |binary src/images/icon/grey_station.png |binary src/images/icon/grey_track.png |binary src/images/icon/notile_2towns.png |binary src/images/icon/notile_station.png |binary src/images/icon/russet_station.png |binary src/images/icon/russet_track.png |binary src/images/icon/yellow_station.png |binary src/images/icon/yellow_track.png |binary src/lib/JLayer1.0.1/jl1.0.1jar |binary src/lib/commons-io-2.1/commons-io-2.1.jar |binary src/lib/df_1.1.0/dockingFramesCommon.jar |binary src/lib/df_1.1.0/dockingFramesCore.jar |binary src/manifest | 4 src/rails.bat | 2 src/rails.sh | 2 src/rails/algorithms/RevenueAdapter.java | 3 src/rails/common/Config.java | 55 src/rails/common/ConfigItem.java | 181 src/rails/common/ConfigManager.java | 313 src/rails/common/ConfigProfile.java | 396 src/rails/common/LocalText.java | 1 src/rails/common/MoneyFormatter.java | 1 src/rails/common/parser/Config.java | 608 src/rails/common/parser/ConfigItem.java | 145 src/rails/game/Bank.java | 2 src/rails/game/GameManager.java | 57 src/rails/game/MapHex.java | 21 src/rails/game/MapManager.java | 42 src/rails/game/OperatingRound.java | 110 src/rails/game/Phase.java | 7 src/rails/game/PublicCompany.java | 34 src/rails/game/RailsRoot.java | 33 src/rails/game/ReportBuffer.java | 9 src/rails/game/StartRound.java | 20 src/rails/game/StockMarket.java | 33 src/rails/game/StockRound.java | 126 src/rails/game/StockSpace.java | 13 src/rails/game/Stop.java | 6 src/rails/game/Tile.java | 15 src/rails/game/TrainManager.java | 43 src/rails/game/action/BuyTrain.java | 7 src/rails/game/action/LayTile.java | 38 src/rails/game/correct/ClosePrivate.java | 2 src/rails/game/special/SpecialRight.java | 4 src/rails/game/special/SpecialTileLay.java | 56 src/rails/game/specific/_1835/ElsasModifier.java | 44 src/rails/game/specific/_1835/OperatingRound_1835.java | 39 src/rails/game/specific/_1835/StartRound_1835.java | 14 src/rails/game/specific/_1856/CGRFormationRound.java | 3 src/rails/game/specific/_1889/OperatingRound_1889.java | 66 src/rails/game/specific/_18EU/FinalMinorExchangeRound.java | 4 src/rails/game/specific/_18EU/OffBoardRevenueModifier.java | 2 src/rails/game/specific/_18EU/StartCompany_18EU.java | 20 src/rails/game/specific/_18EU/StockRound_18EU.java | 8 src/rails/sound/SoundConfig.java | 104 src/rails/sound/SoundContext.java | 129 src/rails/sound/SoundEventInterpreter.java | 301 src/rails/sound/SoundManager.java | 68 src/rails/sound/SoundPlayer.java | 273 src/rails/ui/images/accept.png |binary src/rails/ui/images/add.png |binary src/rails/ui/images/arrow_redo.png |binary src/rails/ui/images/arrow_undo.png |binary src/rails/ui/images/auction_hammer_gavel.png |binary src/rails/ui/images/bricks.png |binary src/rails/ui/images/button.png |binary src/rails/ui/images/cancel.png |binary src/rails/ui/images/cash_stack.png |binary src/rails/ui/images/clock_add.png |binary src/rails/ui/images/clock_delete.png |binary src/rails/ui/images/coins_in_hand.png |binary src/rails/ui/images/control_fastforward_blue.png |binary src/rails/ui/images/control_play_blue.png |binary src/rails/ui/images/globe_model.png |binary src/rails/ui/images/hand_property.png |binary src/rails/ui/images/information.png |binary src/rails/ui/images/money_add.png |binary src/rails/ui/images/money_bag.png |binary src/rails/ui/images/participation_rate.png |binary src/rails/ui/images/rails32.png |binary src/rails/ui/images/script.png |binary src/rails/ui/images/traffic_lights_green.png |binary src/rails/ui/images/traffic_lights_red.png |binary src/rails/ui/images/traffic_lights_yellow.png |binary src/rails/ui/images/train.png |binary src/rails/ui/swing/AbstractReportWindow.java | 11 src/rails/ui/swing/ConfigWindow.java | 398 src/rails/ui/swing/GUIToken.java | 78 src/rails/ui/swing/GameSetupWindow.java | 167 src/rails/ui/swing/GameStatus.java | 125 src/rails/ui/swing/GameUIManager.java | 234 src/rails/ui/swing/GridPanel.java | 230 src/rails/ui/swing/ImageLoader.java | 27 src/rails/ui/swing/MapPanel.java | 182 src/rails/ui/swing/MessagePanel.java | 103 src/rails/ui/swing/ORPanel.java | 597 src/rails/ui/swing/ORUIManager.java | 476 src/rails/ui/swing/ORWindow.java | 145 src/rails/ui/swing/RemainingTilesWindow.java | 80 src/rails/ui/swing/ReportWindow.java | 2 src/rails/ui/swing/ReportWindowDynamic.java | 66 src/rails/ui/swing/Scale.java | 2 src/rails/ui/swing/SplashWindow.java | 357 src/rails/ui/swing/StartRoundWindow.java | 139 src/rails/ui/swing/StatusWindow.java | 141 src/rails/ui/swing/StockChart.java | 10 src/rails/ui/swing/TokenIcon.java | 15 src/rails/ui/swing/UpgradesPanel.java | 230 src/rails/ui/swing/WindowSettings.java | 7 src/rails/ui/swing/elements/ActionButton.java | 8 src/rails/ui/swing/elements/CheckBoxDialog.java | 111 src/rails/ui/swing/elements/ConfirmationDialog.java | 112 src/rails/ui/swing/elements/DockingFrame.java | 409 src/rails/ui/swing/elements/MessageDialog.java | 83 src/rails/ui/swing/elements/NonModalDialog.java | 132 src/rails/ui/swing/elements/RadioButtonDialog.java | 113 src/rails/ui/swing/elements/RailsIcon.java | 127 src/rails/ui/swing/elements/RailsIconButton.java | 139 src/rails/ui/swing/gamespecific/_1835/GameUIManager_1835.java | 46 src/rails/ui/swing/gamespecific/_1835/StatusWindow_1835.java | 33 src/rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java | 27 src/rails/ui/swing/gamespecific/_1880 | 7 src/rails/ui/swing/gamespecific/_18EU/GameStatus_18EU.java | 8 src/rails/ui/swing/gamespecific/_18EU/GameUIManager_18EU.java | 182 src/rails/ui/swing/hexmap/GUIHex.java | 249 src/rails/ui/swing/hexmap/GUITile.java | 137 src/rails/ui/swing/hexmap/HexHighlightMouseListener.java | 243 src/rails/ui/swing/hexmap/HexMap.java | 713 src/rails/ui/swing/hexmap/HexMapImage.java | 83 src/rails/util/GameFileIO.java | 230 src/rails/util/RunGame.java | 23 src/rails/util/SystemOS.java | 117 src/rails/util/Util.java | 47 src/readme.txt | 13 src/test/SVGApplication.java | 105 src/test/SVGOffscreenLoader.java | 192 src/test/TestGame.java | 2 src/test/TestGameBuilder.java | 8 src/test/data/bugs/1830CF_obsoleteTrains.rails |binary src/test/data/bugs/1830CF_obsoleteTrains.report | 432 src/test/data/bugs/1830_sellPresidency.rails |binary src/test/data/bugs/1830_sellPresidency.report | 408 src/test/data/bugs/1835_changePresidentAtStart.rails |binary src/test/data/bugs/1835_changePresidentAtStart.report | 54 src/test/data/bugs/1856_tokens.report | 1 src/test/data/bugs/1889_presidentContribution.report | 3 src/test/data/real/1830_A.report | 3 src/test/data/real/1856_A.report | 3 src/test/data/real/1889_A.report | 2 src/test/data/real/1889_B.report | 3 src/test/data/real/1889_C.report | 3 src/test/data/real/18AL_A.report | 1 src/test/data/real/18EU_A.report | 2099 src/test/data/real/18GA_A.report | 415 src/test/data/real/18TN_A.rails |binary src/test/data/real/18TN_A.report | 616 src/test/data/test/1830_5forDtrainExchange.report | 3 src/test/data/test/1830_SellFullPresCert.report | 535 src/test/data/test/1830_SellHalfPresCert.report | 535 src/test/data/test/1835_NatDoubleShare.rails |binary src/test/data/test/1835_NatDoubleShare.report | 884 src/test/data/test/1835_NatSingleShare.rails |binary src/test/data/test/1835_NatSingleShare.report | 348 src/test/data/test/1835_PR_3rdTrain.report | 1060 src/test/data/test/1835_SellDoubleShare.rails |binary src/test/data/test/1835_SellDoubleShare.report | 1643 src/test/data/test/1835_SwapPresForDoubleShare.rails |binary src/test/data/test/1835_SwapPresForDoubleShare.report | 424 src/test/data/test/1851_Late.report | 2 src/test/data/test/1856_2nd6T+PrezCash2.report | 3 src/tools/ListAndFixSavedFiles.java | 268 src/tools/formatxml.pl | 23 src/version.number | 5 test/data/test/1835_PRHasTwoExcessTrains.report | 1141 tools/formatxml.pl | 23 228 files changed, 47213 insertions(+), 9356 deletions(-) New commits: commit bc91566270779d8a245d05219b01392563cab91b Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 12:20:16 2012 +0200 prepared for release 1.7.10 (cherry picked from commit ef4e13ac6c9dba970ff8e7720098eaf7d0d9a552) diff --git a/src/readme.txt b/src/readme.txt index ba355d5..5ef8bbc 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -1,4 +1,4 @@ -Rails release 1.7.9: +Rails release 1.7.10: A new maintenance release for Rails 1.x series @@ -6,8 +6,8 @@ This release fixes two bugs. Contributors: Stefan Frey -Bugs reported by Arne Ãsterlund +Bugs reported by theos and Russel J. Alphey Lists of bugs fixed: -- List of recent files does not work with few entries -- 1830 Coalfields (and others): Obsolete Trains in Pool should rust (previously the stayed forever) +- fixed bug in starting a company in 18EU if only one start price is possible +- fixed bug that the ReportWindow does not scroll down at game start \ No newline at end of file diff --git a/src/version.number b/src/version.number index 385bed2..2ab2e9d 100644 --- a/src/version.number +++ b/src/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.9 +version=1.7.10 # 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 9198df6e602f5195f1f38e65c412f668aabae76e Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 10:45:27 2012 +0200 fixed bug that the ReportWindow does not scrolldown at gameStart, added invokeLater to scrollDown to run in EDT, reported by Russel J. Alphey (cherry picked from commit 31879bbddbab1a44403379a4ab34004c3c903d53) diff --git a/src/rails/ui/swing/ReportWindowDynamic.java b/src/rails/ui/swing/ReportWindowDynamic.java index bed9f8e..2752af9 100644 --- a/src/rails/ui/swing/ReportWindowDynamic.java +++ b/src/rails/ui/swing/ReportWindowDynamic.java @@ -181,21 +181,25 @@ public class ReportWindowDynamic extends AbstractReportWindow implements Action @Override public void scrollDown() { // only set caret if visible - if (!this.isVisible()) return; + //if (!this.isVisible()) return; // find the active message in the parsed html code (not identical to the position in the html string) // thus the message indicator is used - int caretPosition; - try{ - String docText = editorPane.getDocument().getText(0, editorPane.getDocument().getLength()); - caretPosition = docText.indexOf(ReportBuffer.ACTIVE_MESSAGE_INDICATOR); - } catch (BadLocationException e){ - caretPosition = -1; - }; - final int caretPositionStore = caretPosition; - if (caretPosition != -1) { - editorPane.setCaretPosition(caretPositionStore); - } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + int caretPosition; + try{ + String docText = editorPane.getDocument().getText(0, editorPane.getDocument().getLength()); + caretPosition = docText.indexOf(ReportBuffer.ACTIVE_MESSAGE_INDICATOR); + } catch (BadLocationException e){ + caretPosition = -1; + }; + final int caretPositionStore = caretPosition; + if (caretPosition != -1) { + editorPane.setCaretPosition(caretPositionStore); + } + } + }); } public void actionPerformed(ActionEvent e) { commit afd21447aa9d4ae35f7e00f77c7a6be2b8690816 Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 10:35:49 2012 +0200 fixed bug in starting a company in 18EU if only one start price is possible, bug reported by theos (cherry picked from commit 4c1d24f937619baccda7e76d141a621319282d3d) Conflicts: src/rails/ui/swing/GameStatus.java diff --git a/src/rails/ui/swing/GameStatus.java b/src/rails/ui/swing/GameStatus.java index 9a5e758..0450dfd 100644 --- a/src/rails/ui/swing/GameStatus.java +++ b/src/rails/ui/swing/GameStatus.java @@ -18,6 +18,7 @@ import rails.game.*; import rails.game.action.*; import rails.game.correct.CashCorrectionAction; import rails.game.model.PortfolioModel; +import rails.game.specific._18EU.StartCompany_18EU; import rails.sound.SoundManager; import rails.ui.swing.elements.*; import rails.ui.swing.hexmap.HexHighlightMouseListener; @@ -769,7 +770,8 @@ public class GameStatus extends GridPanel implements ActionListener { } } int index = 0; - if (options.size() > 1) { + // check for instanceof StartCompany_18EU allows to continue with selecting the minor + if (options.size() > 1 || actions.get(0) instanceof StartCompany_18EU) { if (startCompany) { RadioButtonDialog dialog = new RadioButtonDialog ( GameUIManager.COMPANY_START_PRICE_DIALOG, commit 81f16a283eadc74d8aea660409b63a82eeb490ba Author: Stefan Frey <ste...@we...> Date: Mon Sep 17 20:18:41 2012 +0200 prepared for 1.7.9 release (cherry picked from commit 2a12d199876712dd7e83f5ed491e05365e644b5a) diff --git a/src/readme.txt b/src/readme.txt index 111a7c4..ba355d5 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -1,13 +1,13 @@ -Rails release 1.7.8: +Rails release 1.7.9: A new maintenance release for Rails 1.x series -This release fixes several bugs. +This release fixes two bugs. -Contributors: Erik Vos, Stefan Frey +Contributors: Stefan Frey -Bugs reported by Martin Brumm, John David Galt +Bugs reported by Arne Ãsterlund Lists of bugs fixed: -- All Games: Update "PD" label in GameStatus lower player names panel -- 1835 (and others with NoMapMode): Cannot save game file with ClosePrivate action +- List of recent files does not work with few entries +- 1830 Coalfields (and others): Obsolete Trains in Pool should rust (previously the stayed forever) diff --git a/src/version.number b/src/version.number index f74a335..385bed2 100644 --- a/src/version.number +++ b/src/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.8 +version=1.7.9 # 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 2dd67fc4bc701adad9b5e9998d33f0b13b7ef01b Author: Stefan Frey <ste...@we...> Date: Mon Sep 17 18:47:13 2012 +0200 fixed problem of obsoleting trains in the pool, as reported by arne oestlund (cherry picked from commit 1cb73edf9ec9657eaac3665cf7db57908556e88f) Conflicts: rails/game/TrainManager.java diff --git a/src/rails/game/TrainManager.java b/src/rails/game/TrainManager.java index 289491d..02b3d0e 100644 --- a/src/rails/game/TrainManager.java +++ b/src/rails/game/TrainManager.java @@ -328,6 +328,8 @@ public class TrainManager extends RailsManager implements Configurable { private boolean isTrainObsolete(Train train, Owner lastBuyingCompany) { // check fist if train can obsolete at all if (!train.getCertType().isObsoleting()) return false; + // and if it is in the pool (always rust) + if (train.getOwner() == pool.getParent()) return false; // then check if obsolete type if (obsoleteTrainFor == ObsoleteTrainForType.ALL) { commit 68d5723375b9b4a73adf03ea7af7f7b31738d27c Author: Stefan Frey <ste...@we...> Date: Mon Sep 10 15:29:29 2012 +0200 fixed recent file list bug (cherry picked from commit 0eeb12fa8e0383287abe41d85a8dfc311a0e6126) Commit was already included, kept for reference. commit 78c45672597422a92362e0f1c424782c2cbc74d7 Author: Stefan Frey <ste...@we...> Date: Mon Jul 23 17:01:38 2012 +0200 prepared for 1.7.8 release (cherry picked from commit 18c0f865fc235df7a4d370114d3d26cb3eff4f76) diff --git a/src/readme.txt b/src/readme.txt index 33de310..111a7c4 100644 --- a/src/readme.txt +++ b/src/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/src/version.number b/src/version.number index 60520e3..f74a335 100644 --- a/src/version.number +++ b/src/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 d0c93922e840fca16e8c628e654e53e411b3b6d7 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) (cherry picked from commit 59d48a43689c5128a9487290d0682e0961201c6e) Conflicts: src/rails/ui/swing/GameStatus.java diff --git a/src/rails/ui/swing/GameStatus.java b/src/rails/ui/swing/GameStatus.java index 9e22716..9a5e758 100644 --- a/src/rails/ui/swing/GameStatus.java +++ b/src/rails/ui/swing/GameStatus.java @@ -977,8 +977,9 @@ public class GameStatus extends GridPanel implements ActionListener { public void setPriorityPlayer(int index) { for (int j = 0; j < np; j++) { - upperPlayerCaption[j].setText(players[j].getId() - + (j == index ? " PD" : "")); + String playerNameAndPriority = players[j].getId() + (j == index ? " PD" : ""); + upperPlayerCaption[j].setText(playerNameAndPriority); + lowerPlayerCaption[j].setText(playerNameAndPriority); } } commit 5d1855c07242cdad121ee11c6a210c3a55cd946c 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 (cherry picked from commit b564e00983be9033464fd3e0658d61143ab5bf5f) Conflicts: src/rails/game/correct/ClosePrivate.java diff --git a/src/rails/game/correct/ClosePrivate.java b/src/rails/game/correct/ClosePrivate.java index 0ffea43..7a10c3e 100644 --- a/src/rails/game/correct/ClosePrivate.java +++ b/src/rails/game/correct/ClosePrivate.java @@ -18,7 +18,7 @@ public class ClosePrivate extends PossibleAction { /* Preconditions */ /** private company to close */ - private PrivateCompany privateCompany; + transient private PrivateCompany privateCompany; /** converted to name */ private String privateCompanyName; commit c910d16695395424919bc5312cfebf04b95d18d3 Author: Stefan Frey <ste...@we...> Date: Fri Jun 15 17:35:37 2012 +0200 prepared for release 1.7.7 (cherry picked from commit 90ba59260b14c2a7d5f14a37c730d7d0cc5e0baf) diff --git a/src/readme.txt b/src/readme.txt index a1180ee..33de310 100644 --- a/src/readme.txt +++ b/src/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/src/version.number b/src/version.number index cde0424..60520e3 100644 --- a/src/version.number +++ b/src/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 65107299650c9c09229f3f88bf03f952eb494115 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) (cherry picked from commit bf16424ac310389b5b48fabfc11a86a6f2a93a29) Conflicts: src/rails/util/GameFileIO.java diff --git a/src/rails/util/GameFileIO.java b/src/rails/util/GameFileIO.java index 7e97190..f4feece 100644 --- a/src/rails/util/GameFileIO.java +++ b/src/rails/util/GameFileIO.java @@ -227,16 +227,17 @@ public class GameFileIO { gameManager.setReloading(true); int count = -1; - // set possible actions for first action - gameManager.getCurrentRound().setPossibleActions(); - - 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) { + // set possible actions for first action + gameManager.getCurrentRound().setPossibleActions(); + 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 58a2f91d034602a80a8b25970bacb3137d3bfc0f 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) (cherry picked from commit 3892c7f2d7d9685cc3a1e5b69e4be900fe7bc4e7) Includes change of method signature of Stop.getBaseTokens() to ImmutableSet Conflicts: src/rails/ui/swing/ORUIManager.java diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 206496f..c533027 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -971,7 +971,7 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable { if (mStops == null || mStops.isEmpty()) return null; ImmutableSet.Builder<BaseToken> tokens = ImmutableSet.builder(); for (Stop city : mStops) { - tokens.addAll(city.getBaseTokens().items()); + tokens.addAll(city.getBaseTokens()); } return tokens.build(); } @@ -1019,7 +1019,7 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable { public ImmutableSet<BaseToken> getTokens(int cityNumber) { // TODO: Is the test for null still required if (mStops.size() > 0 && mStops.get(cityNumber) != null) { - return (mStops.get(cityNumber)).getBaseTokens().items(); + return (mStops.get(cityNumber)).getBaseTokens(); } else { return ImmutableSet.of(); // empty set } diff --git a/src/rails/game/Stop.java b/src/rails/game/Stop.java index 9a2f398..df104d3 100644 --- a/src/rails/game/Stop.java +++ b/src/rails/game/Stop.java @@ -3,6 +3,8 @@ package rails.game; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.ImmutableSet; + import rails.game.state.GenericState; import rails.game.state.Owner; import rails.game.state.PortfolioSet; @@ -213,8 +215,8 @@ public class Stop extends RailsAbstractItem implements Owner { initStopProperties(); } - public PortfolioSet<BaseToken> getBaseTokens() { - return tokens; + public ImmutableSet<BaseToken> getBaseTokens() { + return tokens.items(); } public boolean hasTokens() { diff --git a/src/rails/ui/swing/ORUIManager.java b/src/rails/ui/swing/ORUIManager.java index e07708d..4cd507c 100644 --- a/src/rails/ui/swing/ORUIManager.java +++ b/src/rails/ui/swing/ORUIManager.java @@ -963,16 +963,20 @@ public class ORUIManager implements DialogOwner { * 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] + * + * TODO: (Rails2.0) Check if this still works */ 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 = Iterables.get(s1.getBaseTokens(), 0).getParent().getHomeHexes().contains(hex); - boolean home2 = Iterables.get(s2.getBaseTokens(), 0).getParent().getHomeHexes().contains(hex); - if (home1 && !home2) { + Set<BaseToken> tokens; + boolean stop1IsHome = !((tokens = s1.getBaseTokens()).isEmpty()) + && Iterables.get(tokens, 0).getParent().getHomeHexes().contains(hex); + boolean stop2IsHome = !((tokens = s2.getBaseTokens()).isEmpty()) + && Iterables.get(tokens, 0).getParent().getHomeHexes().contains(hex); + if (stop1IsHome && !stop2IsHome) { return -1; - } else if (home2 && !home1) { + } else if (stop2IsHome && !stop1IsHome) { return 1; } else { return 0; // Doesn't matter @@ -991,7 +995,7 @@ public class ORUIManager implements DialogOwner { if (oldStop.hasTokens()) { // Assume only 1 token (no exceptions known) // TODO: Rewrite this to make this code nicer - PublicCompany company = (Iterables.get(oldStop.getBaseTokens().items(), 0)).getParent(); + PublicCompany company = (Iterables.get(oldStop.getBaseTokens(), 0)).getParent(); List<String> prompts = new ArrayList<String>(); Map<String, Integer> promptToCityMap = new HashMap<String, Integer>(); commit d91e830cc4130ed708e769b4e9ad521127e7b4ff 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 (cherry picked from commit 18b22dec3aeaa01d27250baf5b7dc0256c777d64) Conflicts: src/rails/ui/swing/ORUIManager.java diff --git a/src/data/1835/CompanyManager.xml b/src/data/1835/CompanyManager.xml index 9f28099..bfdbb7f 100644 --- a/src/data/1835/CompanyManager.xml +++ b/src/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/src/rails/ui/swing/ORUIManager.java b/src/rails/ui/swing/ORUIManager.java index 35ca9b0..e07708d 100644 --- a/src/rails/ui/swing/ORUIManager.java +++ b/src/rails/ui/swing/ORUIManager.java @@ -941,12 +941,53 @@ public class ORUIManager implements DialogOwner { */ protected void relayBaseTokens (LayTile action) { - MapHex hex = action.getChosenHex(); + final MapHex hex = action.getChosenHex(); Tile newTile = action.getLaidTile(); Tile 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 = Iterables.get(s1.getBaseTokens(), 0).getParent().getHomeHexes().contains(hex); + boolean home2 = Iterables.get(s2.getBaseTokens(), 0).getParent().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) // TODO: Rewrite this to make this code nicer @@ -956,7 +997,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( @@ -992,8 +1033,10 @@ public class ORUIManager implements DialogOwner { prompts.toArray(), prompts.get(0)); if (selected == null) return; action.addRelayBaseToken(company.getId(), promptToCityMap.get(selected)); + --freeSlots[promptToCityMap.get(selected)]; } else { action.addRelayBaseToken(company.getId(), promptToCityMap.get(prompts.toArray() [0])); + --freeSlots[promptToCityMap.get(prompts.toArray()[0])]; } } } commit 41575ef06b40d98705a3dfe6ff36f27fe12e37be 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 (cherry picked from commit 1686fd33004bbef7c25eeabab96e649f8d1849f8) Conflicts: src/rails/game/ReportBuffer.java diff --git a/src/rails/game/ReportBuffer.java b/src/rails/game/ReportBuffer.java index 8e9751b..53e9767 100644 --- a/src/rails/game/ReportBuffer.java +++ b/src/rails/game/ReportBuffer.java @@ -333,7 +333,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.getId() + " says: ' "); + // at gamestart no player is defined, this is a bug-fix + if (item.player == null) { + s.append("'"); + } else { + s.append(item.player.getId() + " says: '"); + } s.append(comment + "'" + NEWLINE_STRING); s.append("</span>"); } commit 309e95ba38a50e10a77f93081fb100141bf95ac2 Author: Stefan Frey <ste...@we...> Date: Wed Jun 13 19:42:52 2012 +0200 removed the limitation text for the 1830 coalfield variant (cherry picked from commit ae10a615c47ca248f0f7d9a5c2c5c38946ced196) diff --git a/src/data/GamesList.xml b/src/data/GamesList.xml index 3674b65..06fe440 100644 --- a/src/data/GamesList.xml +++ b/src/data/GamesList.xml @@ -12,11 +12,6 @@ Coalfields variant by Alan R. Moon Limitations: - The M&H/NYC share swap can only be executed in the SR, in the owning player's turn. - Privates cannot be traded between players. -- The Coalfields variant is playable with the following workarounds: - - Coalfield certificates cannot yet be bought. Execute a Cash Correction to mimic this action. - - Route and revenue calculation will always include the Coalfields, if reachable. - If you have not bought a Coalfields certificate, you'll have to calculate the correct revenue - yourself, and enter it manually. </Description> <!-- GAME OPTIONS must have: - a name, which must also exist as an entry in LocalText.properties, commit 44d3ab262ef9cc7b61afee69a260b803de7a75b1 Author: Stefan Frey <ste...@we...> Date: Tue Jun 12 08:37:03 2012 +0200 1835: Allow manual close of Pfalzbahn (supports play after rules interpretation by John David Galt) (cherry picked from commit b8b5db220ec42180d2799567e6f9343e1207a6c8) diff --git a/src/data/1835/CompanyManager.xml b/src/data/1835/CompanyManager.xml index baa4fd8..9f28099 100644 --- a/src/data/1835/CompanyManager.xml +++ b/src/data/1835/CompanyManager.xml @@ -70,6 +70,7 @@ <ClosingConditions> <Phase>5</Phase> <SpecialProperties condition="ifAllExercised"/> + <CloseManually/> <!-- If tile is laid not via special property--> </ClosingConditions> </Company> <Company name="LD" longname="Leipzig-Dresdner Bahn" type="Private" basePrice="190"> commit fa2dc21691fa5a95753714b1b30f8bd2929e8b09 Author: Stefan Frey <ste...@we...> Date: Wed Jun 6 18:06:51 2012 +0200 added little fun variant 18Lummer (cherry picked from commit 29aeea878329201b84d6238f7b5fd78f0c7d084f) diff --git a/src/data/18Lummer/CompanyManager.xml b/src/data/18Lummer/CompanyManager.xml new file mode 100644 index 0000000..6d3339d --- /dev/null +++ b/src/data/18Lummer/CompanyManager.xml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<CompanyManager> + <CompanyType name="Private" class="rails.game.PrivateCompany"> + <ClosingConditions> + <Phase>5</Phase> + </ClosingConditions> + <Tradeable toCompany="yes" lowerPriceFactor="0.5" upperPriceFactor="2.0"/> + <Tradeable toPlayer="yes"/> + </CompanyType> + <CompanyType name="Public" class="rails.game.PublicCompany"> + <CanBuyPrivates/> + <PoolPaysOut/> + <Float percentage="60"/> + <ShareUnit percentage="10"/> + <BaseTokens> + <!-- HomeBase lay options: "whenStarted", "whenFloated", "firstOR" (default) --> + <HomeBase lay="firstOR"/> + <!-- LayCost methods: only "sequence" (1830 style) implemented so far (default) --> + <LayCost method="sequence" cost="0,40"/> + </BaseTokens> + <Certificate type="President" shares="2"/> + <Certificate shares="1" number="8"/> + <Trains limit="4,3,2"/> + <CanUseSpecialProperties/> + </CompanyType> + <Company name="Post" type="Private" basePrice="20" revenue="5" + longname="Postschiff" /> + <Company name="JK" type="Public" tokens="2" fgColour="255,255,255" bgColour="0,0,255" + longname="Jim Knopf"> + <Home hex="C4"/> + </Company> + <Company name="LL" type="Public" tokens="2" fgColour="FFFFFF" bgColour="FF0000" + longname="Lukas Lokomotivfuehrer"> + <Home hex="C8"/> + </Company> + <StartPacket roundClass="rails.game.StartRound_1830"> + <Bidding initial="5" minimum="5" increment="1"/> + <Item name="Post" type="Private" basePrice="20"/> + </StartPacket> +</CompanyManager> + + + \ No newline at end of file diff --git a/src/data/18Lummer/Game.xml b/src/data/18Lummer/Game.xml new file mode 100644 index 0000000..79fc4ac --- /dev/null +++ b/src/data/18Lummer/Game.xml @@ -0,0 +1,102 @@ +<?xml version="1.0"?> +<ComponentManager> + <Component name="GameManager" class="rails.game.GameManager"> + <Game name="18Lummer"/> + <GameOption name="RouteAwareness" values="Highlight,Deactivate" default="Highlight" /> + <GameOption name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest" /> + + <GameParameters> + <PlayerShareLimit percentage="60"> + <!-- Option "NumberOfPlayers" is automatically set + by the game engine --> + <IfOption name="NumberOfPlayers" value="2"> + <IfOption name="TwoPlayersCertLimit70Percent" value="yes"> + <Attributes percentage="70"/> + </IfOption> + </IfOption> + </PlayerShareLimit> + <BankPoolLimit percentage="50"/> + <StockRound> + <NoSaleInFirstSR/> + </StockRound> + <OperatingRound> + <EmergencyTrainBuying mustBuyCheapestTrain="no" mayBuyFromCompany="yes"/> + </OperatingRound> + </GameParameters> + <EndOfGame> + <Bankruptcy/> + <BankBreaks limit="0" finish="setOfORs"/> + <!-- "Runs out"; when "broken", -1 is the limit --> + </EndOfGame> + </Component> + <Component name="PlayerManager" class="rails.game.PlayerManager"> + <Players number="2" cash="600" certLimit="28"/> + <Players number="3" cash="400" certLimit="20"/> + <Players number="4" cash="300" certLimit="16"/> + </Component> + <Component name="Bank" class="rails.game.Bank"> + <Bank amount="2000"/> + <Money format="$@"/> + </Component> + <Component name="TileManager" class="rails.game.TileManager" + file="TileSet.xml"/> + <Component name="Map" class="rails.game.MapManager" file="Map.xml"/> + <Component name="CompanyManager" class="rails.game.CompanyManager" + file="CompanyManager.xml"/> + <Component name="StockMarket" class="rails.game.StockMarket" + file="StockMarket.xml"/> + <Component name="TrainManager" class="rails.game.TrainManager"> + <Defaults> + <Reach base="stops" countTowns="yes"/> + <Score towns="yes"/> + </Defaults> + <TrainType name="2" majorStops="2" cost="80" quantity="2"/> + <TrainType name="3" majorStops="3" cost="180" quantity="1"> + <NewPhase phaseName="3"/> + </TrainType> + <TrainType name="4" majorStops="4" cost="300" quantity="1"> + <NewPhase phaseName="4"/> + </TrainType> + <TrainType name="5" majorStops="5" cost="450" quantity="1"> + <NewPhase phaseName="5"/> + </TrainType> + <TrainType name="6" majorStops="6" cost="630" quantity="1"> + <NewPhase phaseName="6"/> + </TrainType> + <TrainType name="D" majorStops="99" cost="1100" quantity="1"> + <NewPhase phaseName="D"/> + <Exchange cost="800"/> + </TrainType> + </Component> + <Component name="PhaseManager" class="rails.game.PhaseManager"> + <Phase name="2" > + <Tiles colour="yellow"/> + <Privates sellingAllowed="no"/> + <OperatingRounds number="1"/> + <Trains onePerTurn="yes" tradingAllowed="yes"/> + </Phase> + <Phase name="3"> + <Tiles colour="yellow,green"/> + <Privates sellingAllowed="yes"/> + <OperatingRounds number="2"/> + </Phase> + <Phase name="4"> + <Trains rusted="2" limitStep="2"/> + </Phase> + <Phase name="5"> + <Tiles colour="yellow,green,brown"/> + <Trains limitStep="3"/> + <!--Privates close="yes"/--> + <OperatingRounds number="3"/> + <OffBoardRevenue step="2"/> + </Phase> + <Phase name="6"> + <Trains rusted="3"> + <Attributes released="D"/> + </Trains> + </Phase> + <Phase name="D"> + <Trains rusted="4"/> + </Phase> + </Component> +</ComponentManager> diff --git a/src/data/18Lummer/Map.xml b/src/data/18Lummer/Map.xml new file mode 100644 index 0000000..4c7ecb8 --- /dev/null +++ b/src/data/18Lummer/Map.xml @@ -0,0 +1,17 @@ +<Map tileOrientation="EW" letterOrientation="vertical" even="A"> + <Defaults> + <Access type="city" runTo="yes" runThrough="yes" loop="yes" score="major"/> + <Access type="town" runTo="yes" runThrough="yes" loop="yes" score="minor"/> + </Defaults> + <!-- The above defaults are redundant, these settings are the system defaults anyway --> + <Hex name="B3" tile="-7" orientation="0"/> + <Hex name="B5" tile="-1" /> + <Hex name="B7" tile="0" /> + <Hex name="B9" tile="-7" orientation="2"/> + <Hex name="C4" tile="-10" /> + <Hex name="C6" tile="-20" cost="120" /> + <Hex name="C8" tile="-10" /> + <Hex name="D5" tile="0" /> + <Hex name="D7" tile="-1" /> + <Hex name="E6" tile="-7" orientation="4"/> +</Map> \ No newline at end of file diff --git a/src/data/18Lummer/StockMarket.xml b/src/data/18Lummer/StockMarket.xml new file mode 100755 index 0000000..770d885 --- /dev/null +++ b/src/data/18Lummer/StockMarket.xml @@ -0,0 +1,149 @@ +<StockMarket type="rectangular"> + <!-- Note two supported colour specification formats: + RGB decimal with commas and RGB hexadecimal without commas --> + <StockSpaceType name="yellow" colour="255,255,0"> + <NoCertLimit/> + </StockSpaceType> + <StockSpaceType name="orange" colour="FF8000"> + <NoCertLimit/> + <NoHoldLimit/> + </StockSpaceType> + <StockSpaceType name="brown" colour="884000"> + <NoCertLimit/> + <NoHoldLimit/> + <NoBuyLimit/> + </StockSpaceType> + + <StockSpace name="A1" price="60" type="yellow"/> + <StockSpace name="A2" price="53" type="yellow"/> + <StockSpace name="A3" price="46" type="yellow"/> + <StockSpace name="A4" price="39" type="orange"/> + <StockSpace name="A5" price="32" type="orange"/> + <StockSpace name="A6" price="25" type="brown"/> + <StockSpace name="A7" price="18" type="brown"/> + <StockSpace name="A8" price="10" type="brown"/> + <StockSpace name="B1" price="67" /> + <StockSpace name="B2" price="60" type="yellow"/> + <StockSpace name="B3" price="55" type="yellow"/> + <StockSpace name="B4" price="48" type="yellow"/> + <StockSpace name="B5" price="41" type="orange"/> + <StockSpace name="B6" price="34" type="orange"/> + <StockSpace name="B7" price="27" type="brown"/> + <StockSpace name="B8" price="20" type="brown"/> + <StockSpace name="B9" price="10" type="brown"/> + <StockSpace name="C1" price="71" /> + <StockSpace name="C2" price="66" /> + <StockSpace name="C3" price="60" type="yellow"/> + <StockSpace name="C4" price="54" type="yellow"/> + <StockSpace name="C5" price="48" type="yellow"/> + <StockSpace name="C6" price="42" type="orange"/> + <StockSpace name="C7" price="36" type="orange"/> + <StockSpace name="C8" price="30" type="brown"/> + <StockSpace name="C9" price="20" type="brown"/> + <StockSpace name="C10" price="10" type="brown"/> + <StockSpace name="D1" price="76" /> + <StockSpace name="D2" price="70" /> + <StockSpace name="D3" price="65" /> + <StockSpace name="D4" price="60" type="yellow"/> + <StockSpace name="D5" price="55" type="yellow"/> + <StockSpace name="D6" price="50" type="yellow"/> + <StockSpace name="D7" price="45" type="orange"/> + <StockSpace name="D8" price="40" type="orange"/> + <StockSpace name="D9" price="30" type="brown"/> + <StockSpace name="D10" price="20" type="brown"/> + <StockSpace name="D11" price="10" type="brown"/> + <StockSpace name="E1" price="82" /> + <StockSpace name="E2" price="76" /> + <StockSpace name="E3" price="70" /> + <StockSpace name="E4" price="66" /> + <StockSpace name="E5" price="62" /> + <StockSpace name="E6" price="58" type="yellow"/> + <StockSpace name="E7" price="54" type="yellow"/> + <StockSpace name="E8" price="50" type="yellow"/> + <StockSpace name="E9" price="40" type="orange"/> + <StockSpace name="E10" price="30" type="brown"/> + <StockSpace name="E11" price="20" type="brown"/> + <StockSpace name="F1" price="90" /> + <StockSpace name="F2" price="82" /> + <StockSpace name="F3" price="76" /> + <StockSpace name="F4" price="71" /> + <StockSpace name="F5" price="67" /> + <StockSpace name="F6" price="65" /> + <StockSpace name="F7" price="63" /> + <StockSpace name="F8" price="60" type="yellow"/> + <StockSpace name="F9" price="50" type="yellow"/> + <StockSpace name="F10" price="40" type="orange"/> + <StockSpace name="F11" price="30" type="brown"/> + <StockSpace name="G1" price="100" > + <StartSpace/> + </StockSpace> + <StockSpace name="G2" price="90" > + <StartSpace/> + </StockSpace> + <StockSpace name="G3" price="82" > + <StartSpace/> + </StockSpace> + <StockSpace name="G4" price="76" > + <StartSpace/> + </StockSpace> + <StockSpace name="G5" price="71" > + <StartSpace/> + </StockSpace> + <StockSpace name="G6" price="67" > + <StartSpace/> + </StockSpace> + <StockSpace name="G7" price="67" /> + <StockSpace name="G8" price="67" /> + <StockSpace name="G9" price="60" type="yellow"/> + <StockSpace name="G10" price="50" type="yellow"/> + <StockSpace name="G11" price="40" type="orange"/> + <StockSpace name="H1" price="112" /> + <StockSpace name="H2" price="100" /> + <StockSpace name="H3" price="90" /> + <StockSpace name="H4" price="82" /> + <StockSpace name="H5" price="76" /> + <StockSpace name="H6" price="71" /> + <StockSpace name="H7" price="69" /> + <StockSpace name="H8" price="68" /> + <StockSpace name="I1" price="126" /> + <StockSpace name="I2" price="112" /> + <StockSpace name="I3" price="100" /> + <StockSpace name="I4" price="90" /> + <StockSpace name="I5" price="82" /> + <StockSpace name="I6" price="75" /> + <StockSpace name="I7" price="70" /> + <StockSpace name="J1" price="142" /> + <StockSpace name="J2" price="126" /> + <StockSpace name="J3" price="111" /> + <StockSpace name="J4" price="100" /> + <StockSpace name="J5" price="90" /> + <StockSpace name="J6" price="80" /> + <StockSpace name="K1" price="160" /> + <StockSpace name="K2" price="142" /> + <StockSpace name="K3" price="125" /> + <StockSpace name="K4" price="110" /> + <StockSpace name="K5" price="100" /> + <StockSpace name="L1" price="180" /> + <StockSpace name="L2" price="160" /> + <StockSpace name="L3" price="140" /> + <StockSpace name="L4" price="120" /> + <StockSpace name="M1" price="200" /> + <StockSpace name="M2" price="180" /> + <StockSpace name="M3" price="155" /> + <StockSpace name="M4" price="130" /> + <StockSpace name="N1" price="225" /> + <StockSpace name="N2" price="200" /> + <StockSpace name="N3" price="170" /> + <StockSpace name="O1" price="250" /> + <StockSpace name="O2" price="220" /> + <StockSpace name="O3" price="185" /> + <StockSpace name="P1" price="275" /> + <StockSpace name="P2" price="240" /> + <StockSpace name="P3" price="200" /> + <StockSpace name="Q1" price="300" /> + <StockSpace name="Q2" price="260" /> + <StockSpace name="R1" price="325" /> + <StockSpace name="R2" price="280" /> + <StockSpace name="S1" price="350" /> + <StockSpace name="S2" price="300" /> +</StockMarket> diff --git a/src/data/18Lummer/TileSet.xml b/src/data/18Lummer/TileSet.xml new file mode 100644 index 0000000..371e6e3 --- /dev/null +++ b/src/data/18Lummer/TileSet.xml @@ -0,0 +1,145 @@ +<TileManager tiles="Tiles.xml"> + <Defaults> + <Access type="offmap" loop="yes"/> + </Defaults> + <!-- Preprinted tiles --> + <Tile id="0"><!-- Empty space --> + <Upgrade id="7,8,9"/> + </Tile> + <Tile id="-1"><!-- 1 town --> + <Upgrade id="3,4,58"/> + </Tile> + <Tile id="-2"><!-- 2 towns --> + <Upgrade id="1,2,55,56,69"/> + </Tile> + <Tile id="-3"/> + <Tile id="-5"/> + <Tile id="-7"/> + <Tile id="-10"><!-- 1 city --> + <Upgrade id="57"/> + </Tile> + <Tile id="-11"><!-- B yellow --> + <Upgrade id="53"/> + </Tile> + <Tile id="-20"><!-- 2 OO cities --> + <Upgrade id="59" relayBaseTokens="yes"/> + </Tile> + <Tile id="-21"><!-- New York --> + <Upgrade id="54"/> + </Tile> + <Tile id="-58"/> + <Tile id="-101"/><!-- Altoona --> + <Tile id="-102"/><!-- Rochester --> + <Tile id="-103"/><!-- Montreal --> + <Tile id="-104"/><!-- Norfolk --> + <Tile id="-105"/><!-- Cleveland --> + <Tile id="-901"/> + <Tile id="-902"/> + <Tile id="-903"/> + <Tile id="-908"/><!-- Coalfields: K1 --> + <Tile id="-25007"/><!-- Wabash: D20--> + <Tile id="-30001"/><!-- Coalfields: N of Boston --> + <Tile id="-30003" pic="-30002"/><!-- Coalfields: Altoona --> + <Tile id="-30004"/><!-- Coalfields: Coalfields --> + <Tile id="-30005"/><!-- Coalfields: Norfolk --> + <Tile id="-30007" pic="-30006"/><!-- Reading: Reading--> + + <!-- Yellow tiles --> + <Tile id="1" quantity="1"> + </Tile> + <Tile id="2" quantity="1"> + </Tile> + <Tile id="3" quantity="2" /> + <Tile id="4" quantity="2" /> + <Tile id="7" quantity="4"> + <Upgrade id="18,26,27,28,29" /> + </Tile> + <Tile id="8" quantity="8"> + <Upgrade id="16,19,23,24,25,28,29" /> + </Tile> + <Tile id="9" quantity="7"> + <Upgrade id="18,19,20,23,24,26,27" /> + </Tile> + <Tile id="55" quantity="1"> + </Tile> + <Tile id="56" quantity="1"> + </Tile> + <Tile id="57"> + <Attributes quantity="4"/> + <Upgrade id="14,15" /> + </Tile> + <Tile id="58" quantity="2" /> + <Tile id="69" quantity="1"> + </Tile> + + <!-- Green tiles --> + <Tile id="14"> + <Attributes quantity="3"/> + <Upgrade id="63" /> + </Tile> + <Tile id="15" quantity="2"> + <Upgrade id="63" /> + </Tile> + <Tile id="16" quantity="1"> + <Upgrade id="43,70" /> + </Tile> + <Tile id="18" quantity="1"> + <Upgrade id="43" /> + </Tile> + <Tile id="19" quantity="1"> + <Upgrade id="45,46" /> + </Tile> + <Tile id="20" quantity="1"> + <Upgrade id="44,47" /> + </Tile> + <Tile id="23" quantity="3"> + <Upgrade id="41,43,45,47" /> + </Tile> + <Tile id="24" quantity="3"> + <Upgrade id="42,43,46,47" /> + </Tile> + <Tile id="25" quantity="1"> + <Upgrade id="40,45,46" /> + </Tile> + <Tile id="26" quantity="1"> + <Upgrade id="42,44,45" /> + </Tile> + <Tile id="27" quantity="1"> + <Upgrade id="41,44,46" /> + </Tile> + <Tile id="28" quantity="1"> +... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-10-02 09:14:33
|
Tag 'v1.7.10' created by Stefan Frey <ste...@we...> at 2012-10-02 09:13 +0000 bug fix release 1.7.10 Changes since v1.7.9-2: --- 0 files changed --- |
From: Stefan F. <ste...@us...> - 2012-10-02 09:14:31
|
rails/game/OperatingRound.java | 4 ++-- rails/ui/swing/GameStatus.java | 4 +++- rails/ui/swing/ReportWindowDynamic.java | 28 ++++++++++++++++------------ readme.txt | 8 ++++---- version.number | 2 +- 5 files changed, 26 insertions(+), 20 deletions(-) New commits: commit 1b235aa8d988b7253906a8c89a5b36edf36951ed Author: Stefan Frey <ste...@we...> Date: Thu Sep 27 15:33:15 2012 +0200 fixed bug in 1889: the free tile lay of private C is not offered if cash was not sufficient to pay potential cost diff --git a/rails/game/OperatingRound.java b/rails/game/OperatingRound.java index d799ad9..af6df5e 100644 --- a/rails/game/OperatingRound.java +++ b/rails/game/OperatingRound.java @@ -1771,8 +1771,8 @@ public class OperatingRound extends Round implements Observer { for (String colour : layableColours) { if (hexes != null) { for (MapHex hex : hexes) { - // Check if the company can pay any costs - if (cash < hex.getTileCost()) continue; + // Check if the company can pay any costs (if not free) + if (!stl.isFree() && cash < hex.getTileCost()) continue; // At least one hex does not have that colour yet if (hex.getCurrentTile().getColourNumber() + 1 commit ef4e13ac6c9dba970ff8e7720098eaf7d0d9a552 Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 12:20:16 2012 +0200 prepared for release 1.7.10 diff --git a/readme.txt b/readme.txt index ba355d5..5ef8bbc 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ -Rails release 1.7.9: +Rails release 1.7.10: A new maintenance release for Rails 1.x series @@ -6,8 +6,8 @@ This release fixes two bugs. Contributors: Stefan Frey -Bugs reported by Arne Ãsterlund +Bugs reported by theos and Russel J. Alphey Lists of bugs fixed: -- List of recent files does not work with few entries -- 1830 Coalfields (and others): Obsolete Trains in Pool should rust (previously the stayed forever) +- fixed bug in starting a company in 18EU if only one start price is possible +- fixed bug that the ReportWindow does not scroll down at game start \ No newline at end of file diff --git a/version.number b/version.number index 385bed2..2ab2e9d 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.9 +version=1.7.10 # 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 31879bbddbab1a44403379a4ab34004c3c903d53 Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 10:45:27 2012 +0200 fixed bug that the ReportWindow does not scrolldown at gameStart, added invokeLater to scrollDown to run in EDT, reported by Russel J. Alphey diff --git a/rails/ui/swing/ReportWindowDynamic.java b/rails/ui/swing/ReportWindowDynamic.java index df789f8..83bf69f 100644 --- a/rails/ui/swing/ReportWindowDynamic.java +++ b/rails/ui/swing/ReportWindowDynamic.java @@ -181,21 +181,25 @@ public class ReportWindowDynamic extends AbstractReportWindow implements Action @Override public void scrollDown() { // only set caret if visible - if (!this.isVisible()) return; + //if (!this.isVisible()) return; // find the active message in the parsed html code (not identical to the position in the html string) // thus the message indicator is used - int caretPosition; - try{ - String docText = editorPane.getDocument().getText(0, editorPane.getDocument().getLength()); - caretPosition = docText.indexOf(ReportBuffer.ACTIVE_MESSAGE_INDICATOR); - } catch (BadLocationException e){ - caretPosition = -1; - }; - final int caretPositionStore = caretPosition; - if (caretPosition != -1) { - editorPane.setCaretPosition(caretPositionStore); - } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + int caretPosition; + try{ + String docText = editorPane.getDocument().getText(0, editorPane.getDocument().getLength()); + caretPosition = docText.indexOf(ReportBuffer.ACTIVE_MESSAGE_INDICATOR); + } catch (BadLocationException e){ + caretPosition = -1; + }; + final int caretPositionStore = caretPosition; + if (caretPosition != -1) { + editorPane.setCaretPosition(caretPositionStore); + } + } + }); } public void actionPerformed(ActionEvent e) { commit 4c1d24f937619baccda7e76d141a621319282d3d Author: Stefan Frey <ste...@we...> Date: Fri Sep 21 10:35:49 2012 +0200 fixed bug in starting a company in 18EU if only one start price is possible, bug reported by theos diff --git a/rails/ui/swing/GameStatus.java b/rails/ui/swing/GameStatus.java index 498522a..d3bad8b 100644 --- a/rails/ui/swing/GameStatus.java +++ b/rails/ui/swing/GameStatus.java @@ -14,6 +14,7 @@ import rails.common.LocalText; import rails.game.*; import rails.game.action.*; import rails.game.correct.CashCorrectionAction; +import rails.game.specific._18EU.StartCompany_18EU; import rails.sound.SoundManager; import rails.ui.swing.elements.*; import rails.ui.swing.hexmap.HexHighlightMouseListener; @@ -765,7 +766,8 @@ public class GameStatus extends GridPanel implements ActionListener { } } int index = 0; - if (options.size() > 1) { + // check for instanceof StartCompany_18EU allows to continue with selecting the minor + if (options.size() > 1 || actions.get(0) instanceof StartCompany_18EU) { if (startCompany) { RadioButtonDialog dialog = new RadioButtonDialog ( GameUIManager.COMPANY_START_PRICE_DIALOG, |
From: Stefan F. <ste...@us...> - 2012-09-21 10:37:53
|
New branch 'rails2.0_merge' available with the following commits: commit b2c2bf637cadcd9c261e6e99521410dfd5b19813 Author: Erik Vos <eri...@xs...> Date: Thu Nov 24 22:09:55 2011 +0100 Fixed offering special token lays where that is not actually allowed. Cases: - Company has no tokens. - Company already has token on target location - Target location is blocked (e.g. another home token is not yet placed). ==> THIS FIX MAY BREAK EXISTING SAVED FILES. Three test cases had to be withdrawn because of this fix.(cherry picked from commit 50a81714eb68f951868feb7d0f3d7d32241ae648) Conflicts: src/rails/game/OperatingRound.java src/test/data/test/1835_NatDoubleShare.rails src/test/data/test/1835_NatDoubleShare.report src/test/data/test/1835_NatSingleShare.rails src/test/data/test/1835_NatSingleShare.report commit c2f0fc99db1c395ac33988d3af8c848ec01202a1 Author: Erik Vos <eri...@xs...> Date: Wed Nov 23 17:20:57 2011 +0100 Fixed PR train discarding bugs. PR did not discard excess trains after forced merge at first 5-train, and would (probably) never discard more than one train, even if having two or more excess trains.(cherry picked from commit 7f688a6ee82a52d57e6909303f91103016a29b24) commit 0e2099f181fb6574ef4aff74ea4f34338575afde Author: Erik Vos <eri...@xs...> Date: Wed Nov 23 00:36:27 2011 +0100 Restored removed field numberSold from SellShares action. This proved necessary for backwards compatibility. Refreshed the related new test cases.(cherry picked from commit 5183cc7a7d798f17479525d466fbc4fcc82e149f) commit b3eb348c4bcc15b03a0885b6a00320170cc4f3cf Author: Erik Vos <eri...@xs...> Date: Wed Nov 23 00:14:38 2011 +0100 Fix: BA home token is now laid in its first OR. This fixes the problem that, if the BA has floated but not yet operated, its home token is already on the map and must find a place when another player lays a green XX tile on the BA home hex. In this case, the wrong player was asked for that place.(cherry picked from commit 92e0d2c13973185cb85ede8b9a83250c1295a610) commit 6814dc74a5b760d6736df3b70a6b97e2a8b82865 Author: Erik Vos <eri...@xs...> Date: Tue Nov 22 14:14:22 2011 +0100 Added five test cases and fixed two. The new test cases check recently fixed 1835 omissions with nationalisation and share selling. The fixed test cases 18GA_A and 18EU_A have failed for some time because of earlier fixes.(cherry picked from commit 13bd6bb91c38ffa428902c7798859fb00f06f31c) Conflicts: src/test/data/real/18EU_A.report commit 6e7b730bf23c57818ffda93cc93e940d0ab42d80 Author: Erik Vos <eri...@xs...> Date: Mon Nov 21 17:40:58 2011 +0100 Fixed presidency dumping issues after previous commit. Added 5 test cases for share selling and nationalisation issues.(cherry picked from commit cd74aa6bf8943b56ce719db283e90fa0bac4e275) Conflicts: src/rails/game/StockRound.java commit f6e4baf421b5e56f2d06514f9c75f183ad86708f Author: Erik Vos <eri...@xs...> Date: Sat Nov 19 10:35:35 2011 +0100 Fixes for 1835: Nationalisation rewritten to handle mixed shares. Rewrote nationalisation to make it able to handle both 10% and 20% shares. The nationalisation code has also been refactored into setBuyableCerts(). Suppressed empty share field tooltips. Moved the SHARES update key from ShareModel to ViewUpdate, where the other keys are.(cherry picked from commit 605008e5a969b1f3fe46a584a5ab86a32176e639) Conflicts: rails/game/model/ShareModel.java src/rails/game/model/ViewUpdate.java src/rails/game/specific/_1835/StockRound_1835.java src/rails/ui/swing/elements/Field.java commit 693c9e5ff1345d49d65978ad1f7e37701b146478 Author: Erik Vos <eri...@xs...> Date: Sun Nov 20 17:37:39 2011 +0100 1835 fix: allow dumped president's share to be exchanged against a 20% share.(cherry picked from commit eaa0aa5957c29448c317bcdec0edb0fc28bebdc8) Conflicts: rails/game/Portfolio.java src/rails/game/PublicCompany.java src/rails/game/ShareSellingRound.java src/rails/game/StockRound.java src/rails/game/TreasuryShareRound.java src/rails/game/action/SellShares.java src/rails/game/specific/_1856/CGRFormationRound.java commit fa68d86848aed54b806136e7eddd6603c7e9203c Author: Erik Vos <eri...@xs...> Date: Sat Nov 19 09:35:58 2011 +0100 Fixes for 1835: Rewrote nationalisation to make it able to handle both 10% and 20% shares. The nationalisation code has also been refactored into setBuyableCerts(). Suppressed empty share field tooltips. Moved the SHARES update key from ShareModel to ViewUpdate, joining with the other keys.(cherry picked from commit 9f97d651984b68e5c9dd68ddfb7361a7151a083f) Conflicts: rails/game/model/ShareModel.java src/rails/game/model/ViewUpdate.java src/rails/game/specific/_1835/StockRound_1835.java src/rails/ui/swing/elements/Field.java commit 8a79a819215aba2679f8ad6e173f247baaada5f1 Author: Erik Vos <eri...@xs...> Date: Wed Nov 16 23:05:48 2011 +0100 Added tooltips to Game Status share fields to display portfolio composition.(cherry picked from commit 902cac06c959dc53ef89aec36cdedb9db2cce2ac) Fixed the ViewUpdate and other modfications. Conflicts: rails/game/model/ShareModel.java src/rails/ui/swing/elements/Field.java commit d31d1814abbcdfb923c899845df54a5d5fe9ff33 Author: Stefan Frey <ste...@we...> Date: Wed Nov 16 12:25:21 2011 +0100 added 18AL map converted from 18AL gamekit by John David Galt (used with his permission) (cherry picked from commit 73f7d400b1be00a4b9fe9574f9fb25e180f5f8b1) commit 1ad02bcad97aaddba673d5252ef243499c3241ab Author: Erik Vos <eri...@xs...> Date: Sun Nov 13 20:37:38 2011 +0100 1835 declared "fully playable"(cherry picked from commit 280f9cca14585646c93a981d7e2426d93f419f41) commit 7d6564981cf191e59badfb72a4e4b3f0ff8e26f3 Author: Erik Vos <eri...@xs...> Date: Sun Nov 13 14:35:29 2011 +0100 Fixed two 18AL bugs. 1. (reported by Thomas Wall Hannaford): Green tile #25 was not upgradeable to #45 and #46. This fix also applies to 1870 and 18Kaas. 2. (reported by Hildebrand Tigelaar): The registration of buying one train to prevent any further buys was not undoable. This fix probably also applies to other games where similar buying restrictions exist. (cherry picked from commit e9fbe53c5ef3c0b6f047771d478dbd919a7ad1db) Conflicts: src/rails/game/OperatingRound.java commit bef70046449e7ab24311e0edbb421de145375c3c Author: Erik Vos <eri...@xs...> Date: Fri Nov 11 22:39:34 2011 +0100 Added blue water tile -4000 and half tiles -4004 and -4005. Applied to 1825 (all units and regional kits). The tiles have type "fixed", so that no track can be laid towards any of them.(cherry picked from commit 8f9b2d141ab02bfb31b78c4f4063116fc88fd7eb) Conflicts: src/data/1825/Map.xml src/data/1825/Tiles.xml src/tiles/HandmadeTiles.xml commit 2c50653a58d7fd19303f2951b1e6274e448fdcaa Author: Stefan Frey <ste...@we...> Date: Fri Nov 11 16:36:27 2011 +0100 updated version number to rails 1.5.3 (this corresponds to release 1.5.3 in branch 1.5.x) (cherry picked from commit e161ea2c8e3da97064fc12a127ebaacf88fca30d) Conflicts: src/rails/game/RailsRoot.java commit 214afafbd9d3270962253d31f9912d403e82c552 Author: Stefan Frey <ste...@we...> Date: Fri Nov 11 16:34:58 2011 +0100 reverted commenting-out automated pass execution code (see commit 1893c3) (cherry picked from commit 2fef5fe020452f1c1901f3ce1e1ee7ab1e49aa50) commit b33b3c15121d4d3059ed4166db3ac13b7dbf7eef Author: Erik Vos <eri...@xs...> Date: Fri Nov 11 16:27:44 2011 +0100 Applied half-hexes etc. to 1825 Units 2 & 3. Also added the Unit 2 & 3 companies, so that these are at least *somewhat* playable.(cherry picked from commit 415ee8339e845cd3c7a306118d7be83539cab712) Conflicts: data/1825/CompanyManager.xml src/data/1825/Map.xml commit 77bf24bded67715038eaf06384f83a4029758fed Author: Erik Vos <eri...@xs...> Date: Wed Nov 9 21:54:40 2011 +0100 Added new empty half-hex preprinted tiles. Co-authored by Stefan Frey <ste...@we...>. Thanks to Stefan for the half-hex pictures. For 1825, to help recognising allowed track laying on some board edges. Applied to Unit 1 only, at the borders with Unit 2 and kits R1-3. All Unit 1 'open' attributes have been removed. Q11 (Crewe) SW is now impassable.(cherry picked from commit f5e251419ca78926162c0183be12fc8fb8abf5ed) commit 137e388575d96c322cb383555f63c66ebfe02ce5 Author: Erik Vos <eri...@xs...> Date: Wed Nov 9 16:29:17 2011 +0100 18EU: entities in company names changed to Unicode characters. Actually, entities are safer, as these are encoding-independent. Characters (like Ã) require file encoding to be understood as UTF-8. To ensure this, added Eclipse preference to encode/decode fiels as UTF-8 (this affects reading/writing non-java and non-XML files). Also set line delimiter to newline only. (cherry picked from commit 6ca045795458ba9c3a9d8e14451bde3dbfaad23e) commit 9fc21a09be43c310c4e529ff8512bf4b481ee353 Author: Stefan Frey <ste...@we...> Date: Tue Nov 8 23:51:01 2011 +0100 Fixed issues with displaying SVG background maps. Added Peter Mumford 18GA redesigned map. (cherry picked from commit 7cf64e84042d36e1f0c1d902e767efc987f797be) commit 484e1b5e6676d95b3c0a5236b13b4b2a1fb74960 Author: Stefan Frey <ste...@we...> Date: Thu Nov 3 13:04:00 2011 +0100 prepared for release 1.5.2 (cherry picked from commit 38a485f50cf2229bce22bf90103de1f767b42358) Conflicts: src/rails/game/RailsRoot.java commit eb53a131cb49550362bad2163f13b61e7c009b80 Author: Stefan Frey <ste...@we...> Date: Wed Oct 12 16:14:20 2011 +0200 fixed display of operating companies in networkinfo menu (cherry picked from commit cea7752364090c76b28874e85cdb8f58e03ce90d) commit fa97b5d9794c297e3d66d87bea10c865c4ab9ab9 Author: Erik Vos <eri...@xs...> Date: Tue Nov 1 14:10:21 2011 +0100 18EU: fixed wrong train limit step from phase 5. Added train limits to Company Info. Added train limit steps to Phase Info. (cherry picked from commit 68d4bf75fa548674c61cdfa1e2670a2d7df4f2b1) commit 17e511fbfd71804b89ed6f3c084ff4d224607d6d Author: Stefan Frey <ste...@we...> Date: Wed Sep 19 15:40:22 2012 +0200 fixed extraTile handling, still todo for simplification and undo proofness commit bd60b41ee6ffa94dad5af8663ea00ffff3270f1c Author: Stefan Frey <ste...@we...> Date: Wed Sep 19 14:37:47 2012 +0200 fixed merge error in StockRound commit 53c9ad902e7f43a6f9b934c6185fd2af3b6553e0 Author: Erik Vos <eri...@xs...> Date: Wed Oct 12 00:37:21 2011 +0200 Phase management upgrade step 5: extra tile lays Extra tile lays are now registered in <Phase> rather than <CompanyType>. Affects Game.xml and CompanyManager.xml of the following games: 1825, 1835,1851, 1880, 18EU, 18TN. Additional fix: In 18EU, minors can no longer select yellow tiles for upgrading. Green tiles will no longer be displayed in this case. (cherry picked from commit 8d2469c1076b10c883cc6cd1c21f78f8bb668df1) Conflicts: rails/game/CompanyManager.java rails/game/CompanyManagerI.java rails/game/PhaseI.java rails/game/PublicCompanyI.java src/rails/game/OperatingRound.java src/rails/game/PublicCompany.java src/rails/ui/swing/UpgradesPanel.java commit 454c908bcb7995c911eaa3ebadcbe2632e1a4db6 Author: Erik Vos <eri...@xs...> Date: Sun Oct 30 23:45:41 2011 +0100 18Jr prototype removed. As requested by the designer: Scott Petersen.(cherry picked from commit 6915bd88f7d018bcbb3e7dcdd9f3d82cf7973c87) Conflicts: src/data/18JR/CompanyManager.xml src/data/18JR/Game.xml src/data/18JR/Map.xml src/data/18JR/StockMarket.xml src/data/18JR/TileSet.xml src/data/18JR/Tiles.xml commit aab630cf3b00cb9a825a37cf04f124007469db8a Author: Erik Vos <eri...@xs...> Date: Sun Oct 30 21:32:37 2011 +0100 Fix to error message if a Right cannot be bought(cherry picked from commit 81bf33b01a64d3d74edb8fa0b46199c350b05372) commit 59b4903f34ee9209f3f5d9fcc505bd5c804c8c0e Author: Erik Vos <eri...@xs...> Date: Sun Oct 30 21:16:37 2011 +0100 Fix: Buying Coalfields right is now refused if the company does not have enough cash. Reported by Charles Strong. This is the easy fix. In fact, the option to buy this right should not be offered at all if the company lacks cash, but fixing that is a bit more complex and omitted for now. (cherry picked from commit 8dd8adf3e2da0056bb7b254f3a0d796288d73b1d) Conflicts: src/rails/game/OperatingRound.java commit 57d55d6ad2db406348c2c3d88314317be004e6a6 Author: Martin Brumm <Dr....@t-...> Date: Sun Oct 30 18:18:40 2011 +0100 Fixed 18TN grey tile being not available due to error in phase definition. Also fixed wrong availability of Tile 170. (cherry picked from commit c631bc3e4f4873e8245bec880a4e3166da45ba39) commit 79ba8677a49dfc355bb5457b912d31b6ea877afd Author: Erik Vos <eri...@xs...> Date: Thu Oct 27 10:11:08 2011 +0200 Added "Yellow Plain" value for the Unlimited Tiles game option. The default value is "Yellow Plain" for 1826 and 1851, "No" for all other games.(cherry picked from commit ec5c857b605051bfb7924810ce4b518af86d2ade) commit 03dce6df52ddf0475fff9199e43132ae7017c7ea Author: Erik Vos <eri...@xs...> Date: Tue Oct 25 16:05:55 2011 +0200 Fixed 18GA: missing cost of hex J10 Bug #3326993.(cherry picked from commit 147edb8de4cad85a7308a1bad4e9248815c29427) commit f74e90217b8ecf558c6cbef99f248f331fc89827 Author: Erik Vos <eri...@xs...> Date: Mon Oct 24 19:39:22 2011 +0200 Fixed 18GA stock market value of square M3 from 100 to 190.(cherry picked from commit 6213166fdf63a04d45364cb9d0cea534fbb574b6) commit 9eba117073a346f1d14d33382b76bddeb7c931e0 Author: Erik Vos <eri...@xs...> Date: Thu Oct 13 22:30:03 2011 +0200 In 1835 Start Round, removed popups that reported forced passes. Also removed some redundant/ineffective code.(cherry picked from commit 1893c34a2ea53e78be3bd4828ccff1e675018e0c) Conflicts: src/rails/game/action/PossibleActions.java commit 399f04516e2e561de206339d1dfddbcba7b96bb0 Author: Erik Vos <eri...@xs...> Date: Thu Oct 13 21:15:53 2011 +0200 Moved StartRound_1835 to the game-specific package.(cherry picked from commit b5cb481a353309e04d48c49b9ca363f4f9e6c532) Conflicts: rails/game/StartRound_1835.java rails/game/specific/_1835/StartRound_1835.java src/rails/game/StartRound_1835.java commit d27c0c6cf0adad4cbff2c497fff35b634ae66848 Author: Erik Vos <eri...@xs...> Date: Thu Oct 13 17:31:12 2011 +0200 Fixed two 1835 bugs and updated Game Notes. - Crash in final PR formation round. Cause: already closed privates were not excluded from the merge process. - Hangs in first OR if Start Packet not sold. Caused by missing call to setPossibleActions() in StartRound_1835. Also corrected 'operate' flag for this case when creating OR object (unclear if this omission was causing problems). Removed bug description and workaround from the Game Notes. Replaced workaround for the non-closing privates bug.(cherry picked from commit d5283097c814b535456a530af604b9640b68d603) Conflicts: src/rails/game/specific/_1835/PrussianFormationRound.java commit cae10a6136e3424f0680084c29d6e6813ec70760 Author: Erik Vos <eri...@xs...> Date: Thu Oct 13 17:11:37 2011 +0200 Fixed 1835 bug: Hangs in first OR if Start Packet not sold. Missing call to setPossibleActions() in StartRound_1835. Also corrected 'operate' flag for this case when creating OR object (unclear if this omission was causing problems).(cherry picked from commit cd9efcef8d70134015e96e25a809f49b468800ea) Conflicts: src/rails/game/StartRound_1835.java src/rails/game/specific/_1835/GameManager_1835.java src/rails/game/specific/_1835/OperatingRound_1835.java commit 5ef4c91198ab26cb631e71718d616fd1fba6724b Author: Erik Vos <eri...@xs...> Date: Thu Oct 13 13:14:01 2011 +0200 Updated 1835 Game Notes(cherry picked from commit df31d98077ce7d818cae7c671c77a403fdc3eeca) commit 27fa9f7790cef9e6243fb6f785f4b44917fb32e7 Author: Erik Vos <eri...@xs...> Date: Thu Oct 13 12:54:13 2011 +0200 Some code cleanups(cherry picked from commit adfb01e778893115aec455fd3755bd0e1bad3502) Conflicts: src/rails/game/Stop.java commit 4e685c78c9e0362c4f756a2b9b7cdce70a44e0f9 Author: Erik Vos <eri...@xs...> Date: Wed Oct 12 15:28:57 2011 +0200 Fixed wrong revenue value (20) of NW city on tile -803 (1835 Hamburg)(cherry picked from commit c7277d4d9659931ddd2996d48fc20e6bf32b80fc) commit 718fe74f6e2bb25d2212018e6b1f6e232f6cee2f Author: Erik Vos <eri...@xs...> Date: Wed Oct 12 13:24:16 2011 +0200 In GameStatus window, make train list fields auto-wrapping. By embedding the text in <html>...</html> and setting the JLabel preferred size to (1,1).(cherry picked from commit 919a2ba43dec0595a445e163d2f008104dc27852) Conflicts: src/rails/ui/swing/GameStatus.java src/rails/ui/swing/elements/Field.java commit 840a9b408bd5c0f75444df9cc69a40494de1cdf6 Author: Erik Vos <eri...@xs...> Date: Mon Oct 10 16:12:11 2011 +0200 Set version # to 1.5.1+(cherry picked from commit 15fa441bd80ceb32615bd8706d620d811166be77) Conflicts: src/rails/game/RailsRoot.java commit af0ebda22c225d3c1db50ccf88adebdc385fbed3 Author: Stefan Frey <ste...@we...> Date: Mon Oct 10 20:51:52 2011 +0200 adding further test games (cherry picked from commit 4b9247bd63ddf2003e0c8f5538d29b207cb92ed7) commit f35b716cbff0d301cf3ef2411c096a343125dfff Author: Stefan Frey <ste...@we...> Date: Mon Oct 10 20:40:19 2011 +0200 updated shell script to manage releases (cherry picked from commit 22b79e84bee3711a29aaf25333be26f85a62a5bf) commit 18792b5d4323eb8eb8cb1eb56f38f65a26d4c486 Author: Stefan Frey <ste...@we...> Date: Sun Oct 9 17:40:34 2011 +0200 Changed Montgomery and Tallahassee to major scoring locations.(cherry picked from commit 48aa0f099ef6335a9ab7d60eca11e86f54b0ea6d) commit bb4ef21a364107d38be54dc1b81113ac21a035bf Author: Erik Vos <eri...@xs...> Date: Fri Oct 7 14:41:44 2011 +0200 Fixed positioning bug of base tokens on corner-facing cities. This was a bug in ConvertXML.java. Replaced Tiles.xml: generic, 1825, 1830 and 1835 versions. Added "universal" XML formatting Perl script under tools.(cherry picked from commit 9fd64c124f5f348217c0273bf54250707b8b2dd1) commit 956be3bf41d06063dc9d76483653d7b032e3cced Author: Erik Vos <eri...@xs...> Date: Tue Oct 4 19:34:19 2011 +0200 Allow game-specific StartRoundWindow classes. Added empty StartRoundWindow_1880 class.(cherry picked from commit 49c5d96547d2904ccfc803dc9018b56233b39537) Conflicts: src/rails/ui/swing/GameUIManager.java src/rails/ui/swing/StartRoundWindow.java commit 1a14e77d7fc7ba63acab782c38767883c2046e30 Author: Erik Vos <eri...@xs...> Date: Tue Oct 4 19:07:55 2011 +0200 Fix bug that disallows selling a share after buying one in some cases. Relates to the "don't sell a just bought certificate" rule. The fix is to reverse the sequence of that and the pool size check.(cherry picked from commit 8fce0f10a5c8ebcb6528a991efcfc74abe45a686) Conflicts: src/rails/game/StockRound.java commit 44f674cfedb5ec2f6eb22ea97c54671c76ca1e46 Author: Erik Vos <eri...@xs...> Date: Mon Oct 3 11:46:12 2011 +0200 Javadoc comments added to the LayBaseToken constructors.(cherry picked from commit 9502e7165a2752f013bd2793f49c774ac4a83acf) commit c2499124771b146974aa374104c158e216deb5d2 Author: Stefan Frey <ste...@we...> Date: Fri Sep 30 22:57:50 2011 +0200 added test case for 1856 token bug (cherry picked from commit ff1134c23f7a2d1438504c9b6e87cd93dbc5e226) commit d14cea725ed29e1d9a97a89aa7796ecdee7bd783 Author: Stefan Frey <ste...@we...> Date: Fri Sep 23 08:09:31 2011 +0200 Prepared for release 1.5(cherry picked from commit eb7868e9d88a51b11c39f56283617dcf9acec2aa) Conflicts: rails.bat rails.sh |
From: Stefan F. <ste...@us...> - 2012-09-19 11:54:01
|
src/rails/game/model/SpecialPropertiesModel.java | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) New commits: commit 6040f259cdca8439ff68fca311fee508a92e8439 Author: Stefan Frey <ste...@we...> Date: Wed Sep 19 09:51:56 2012 +0200 fixed issues with 1856 testgames diff --git a/src/rails/game/model/SpecialPropertiesModel.java b/src/rails/game/model/SpecialPropertiesModel.java new file mode 100644 index 0000000..4d3fa5a --- /dev/null +++ b/src/rails/game/model/SpecialPropertiesModel.java @@ -0,0 +1,71 @@ +package rails.game.model; + +import rails.common.LocalText; +import rails.game.Bonus; +import rails.game.Currency; +import rails.game.PublicCompany; +import rails.game.ReportBuffer; +import rails.game.state.Change; +import rails.game.state.Model; +import rails.game.state.Observable; +import rails.game.state.Owner; +import rails.game.state.PortfolioChange; +import rails.game.state.PortfolioSet; +import rails.game.state.Triggerable; +import rails.game.special.LocatedBonus; +import rails.game.special.SpecialProperty; + +public class SpecialPropertiesModel extends Model implements Triggerable { + + public final static String ID = "SpecialPropertiesModel"; + + private final PortfolioSet<SpecialProperty> specialProperties; + + private SpecialPropertiesModel(Owner parent) { + super(parent, ID); + // specialProperties have the Owner as parent directly + specialProperties = PortfolioSet.create(parent, "specialProperties", SpecialProperty.class); + // so make this model updating + specialProperties.addModel(this); + // and add it as triggerable + specialProperties.addTrigger(this); + } + + public static SpecialPropertiesModel create(Owner parent) { + return new SpecialPropertiesModel(parent); + } + + @Override + public Owner getParent() { + return (Owner)super.getParent(); + } + + PortfolioSet<SpecialProperty> getPortfolio() { + return specialProperties; + } + + // triggerable interface + + public void triggered(Observable observable, Change change) { + + // checks if the specialproperty moved into the portfolio carries a LocatedBonus + @SuppressWarnings("rawtypes") + PortfolioChange pchange = (PortfolioChange)change; + if (!pchange.isIntoPortfolio()) return; + + SpecialProperty property = (SpecialProperty)pchange.getItem(); + if (getParent() instanceof PublicCompany && property instanceof LocatedBonus) { + PublicCompany company = (PublicCompany)getParent(); + LocatedBonus locBonus = (LocatedBonus)property; + Bonus bonus = new Bonus(company, locBonus.getId(), locBonus.getValue(), + locBonus.getLocations()); + company.addBonus(bonus); + ReportBuffer.add(LocalText.getText("AcquiresBonus", + getParent().getId(), + locBonus.getName(), + Currency.format(company, locBonus.getValue()), + locBonus.getLocationNameString())); + } + } + +} |
From: Stefan F. <ste...@us...> - 2012-09-19 09:38:45
|
dev/null |binary src/data/18EU/Game.xml | 2 src/data/profiles/test.profile | 2 src/rails/algorithms/NetworkTrain.java | 2 src/rails/algorithms/RevenueAdapter.java | 1 src/rails/game/Bank.java | 15 src/rails/game/BankPortfolio.java | 4 src/rails/game/BaseToken.java | 2 src/rails/game/Certificate.java | 2 src/rails/game/GameManager.java | 21 src/rails/game/MapHex.java | 29 src/rails/game/OperatingRound.java | 32 src/rails/game/Player.java | 5 src/rails/game/PlayerManager.java | 6 src/rails/game/PrivateCompany.java | 10 src/rails/game/PublicCompany.java | 56 src/rails/game/RailsRoot.java | 8 src/rails/game/StartRound.java | 4 src/rails/game/StockMarket.java | 4 src/rails/game/StockRound.java | 8 src/rails/game/Stop.java | 6 src/rails/game/Train.java | 2 src/rails/game/TrainCertificateType.java | 4 src/rails/game/TrainManager.java | 4 src/rails/game/TreasuryShareRound.java | 2 src/rails/game/action/BuyBonusToken.java | 2 src/rails/game/action/BuyCertificate.java | 2 src/rails/game/action/BuyTrain.java | 3 src/rails/game/action/ExchangeTokens.java | 9 src/rails/game/action/ExchangeableToken.java | 7 src/rails/game/action/StartCompany.java | 3 src/rails/game/model/CertificatesModel.java | 23 src/rails/game/model/PortfolioModel.java | 378 +-- src/rails/game/special/LocatedBonus.java | 4 src/rails/game/special/SellBonusToken.java | 4 src/rails/game/specific/_1835/FoldIntoPrussian.java | 8 src/rails/game/specific/_1835/GameManager_1835.java | 10 src/rails/game/specific/_1835/PrussianFormationRound.java | 10 src/rails/game/specific/_1856/CGRFormationRound.java | 13 src/rails/game/specific/_1856/OperatingRound_1856.java | 5 src/rails/game/specific/_1856/PublicCompany_1856.java | 3 src/rails/game/specific/_1856/PublicCompany_CGR.java | 2 src/rails/game/specific/_1856/StockRound_1856.java | 5 src/rails/game/specific/_18AL/NameTrains.java | 28 src/rails/game/specific/_18AL/NameableTrain.java | 9 src/rails/game/specific/_18AL/NamedTrainToken.java | 10 src/rails/game/specific/_18AL/OperatingRound_18AL.java | 2 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 12 src/rails/game/specific/_18EU/PullmanRevenueModifier.java | 3 src/rails/game/specific/_18EU/StartCompany_18EU.java | 10 src/rails/game/specific/_18EU/StockRound_18EU.java | 25 src/rails/game/state/Observable.java | 6 src/rails/game/state/PortfolioChange.java | 11 src/rails/game/state/StateManager.java | 14 src/rails/game/state/Trigger.java | 11 src/rails/game/state/Triggerable.java | 11 src/rails/ui/swing/GameSetupWindow.java | 7 src/rails/ui/swing/GameUIManager.java | 2 src/rails/ui/swing/ORUIManager.java | 4 src/rails/ui/swing/gamespecific/_18AL/NameTrainsDialog.java | 2 src/rails/ui/swing/gamespecific/_18EU/StatusWindow_18EU.java | 2 src/test/TestGameBuilder.java | 4 src/test/data/real/1830_A.report | 2 src/test/data/real/1856_A.report | 2 src/test/data/real/1889_B.report | 2 src/test/data/real/1889_C.report | 2 src/test/data/real/18AL_A.report | 2 src/test/data/real/18EU_A.report | 23 src/test/data/test/1835_PR_3rdTrain.rails |binary src/test/data/test/1835_PR_3rdTrain.report | 43 src/test/data/test/18EU_After2nd8Train.report | 1194 ----------- 71 files changed, 497 insertions(+), 1668 deletions(-) New commits: commit 61df3a9f1a6ae65aa4fa34a31a7caa21e820dd89 Author: Stefan Frey <ste...@we...> Date: Wed Sep 19 11:38:07 2012 +0200 fixed issues with 1835 test game diff --git a/src/rails/game/PublicCompany.java b/src/rails/game/PublicCompany.java index 660d0a4..36aa8a0 100644 --- a/src/rails/game/PublicCompany.java +++ b/src/rails/game/PublicCompany.java @@ -221,8 +221,8 @@ public class PublicCompany extends RailsAbstractItem implements Company, MoneyOw boolean certsAreInitiallyAvailable = true; /** What percentage of ownership constitutes "one share" */ - protected IntegerState shareUnit = null; // configured see below - + protected IntegerState shareUnit = IntegerState.create(this, "shareUnit", DEFAULT_SHARE_UNIT); + /** What number of share units relates to the share price * (normally 1, but 2 for 1835 Prussian) */ @@ -364,7 +364,7 @@ public class PublicCompany extends RailsAbstractItem implements Company, MoneyOw Tag shareUnitTag = tag.getChild("ShareUnit"); if (shareUnitTag != null) { - shareUnit = IntegerState.create(this, "shareUnit", shareUnitTag.getAttributeAsInteger("percentage", DEFAULT_SHARE_UNIT)); + shareUnit.set(shareUnitTag.getAttributeAsInteger("percentage", DEFAULT_SHARE_UNIT)); shareUnitsForSharePrice = shareUnitTag.getAttributeAsInteger("sharePriceUnits", shareUnitsForSharePrice); } @@ -656,10 +656,6 @@ public class PublicCompany extends RailsAbstractItem implements Company, MoneyOw } - if (shareUnit == null) { - shareUnit = IntegerState.create(this, "shareUnit", DEFAULT_SHARE_UNIT); - } - int certIndex = 0; if (certificateTags != null) { int shareTotal = 0; diff --git a/src/rails/game/action/StartCompany.java b/src/rails/game/action/StartCompany.java index 8539e4c..0299976 100644 --- a/src/rails/game/action/StartCompany.java +++ b/src/rails/game/action/StartCompany.java @@ -51,7 +51,8 @@ public class StartCompany extends BuyCertificate { public boolean equalsAsOption(PossibleAction action) { if (!(action.getClass() == StartCompany.class)) return false; StartCompany a = (StartCompany) action; - return a.company == company && a.from == from && Ints.asList(startPrices).contains(a.price); + return a.company == company && a.from == from + && (startPrices == null && a.startPrices == null || Ints.asList(startPrices).contains(a.price)); } @Override diff --git a/src/rails/game/specific/_1835/FoldIntoPrussian.java b/src/rails/game/specific/_1835/FoldIntoPrussian.java index c8322ab..b84b585 100644 --- a/src/rails/game/specific/_1835/FoldIntoPrussian.java +++ b/src/rails/game/specific/_1835/FoldIntoPrussian.java @@ -6,6 +6,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.google.common.collect.ImmutableSet; + import rails.game.*; import rails.game.action.PossibleAction; import rails.util.Util; @@ -73,7 +75,7 @@ public class FoldIntoPrussian extends PossibleAction { public boolean equalsAsOption(PossibleAction action) { if (!(action instanceof FoldIntoPrussian)) return false; FoldIntoPrussian a = (FoldIntoPrussian) action; - return a.foldableCompanyNames.equals(foldableCompanyNames); + return ImmutableSet.copyOf(a.foldableCompanies).equals(ImmutableSet.copyOf(foldableCompanies)); } @Override @@ -95,7 +97,9 @@ public class FoldIntoPrussian extends PossibleAction { if (foldableCompanyNames != null) { foldableCompanies = new ArrayList<Company>(); for (String name : foldableCompanyNames.split(",")) { - foldableCompanies.add(cmgr.getPublicCompany(name)); + company = cmgr.getPublicCompany(name); + if (company == null) company = cmgr.getPrivateCompany(name); + if (company != null) foldableCompanies.add(company); } } if (Util.hasValue(foldedCompanyNames)) { diff --git a/src/rails/game/specific/_1835/GameManager_1835.java b/src/rails/game/specific/_1835/GameManager_1835.java index 3852cb3..0b83cb4 100644 --- a/src/rails/game/specific/_1835/GameManager_1835.java +++ b/src/rails/game/specific/_1835/GameManager_1835.java @@ -54,9 +54,15 @@ public class GameManager_1835 extends GameManager { } public void startPrussianFormationRound(OperatingRound_1835 or) { - interruptedRound = or; - createRound(PrussianFormationRound.class, "PrussianFormationRound").start (); + String roundName; + if (interruptedRound == null) { + // after a round + roundName = "PrussianFormationRound_after_" + previousRound.getId(); + } else { + roundName = "PrussianFormationRound_in_" + or.getId(); + } + createRound(PrussianFormationRound.class, roundName).start(); } public void setPrussianFormationStartingPlayer(Player prFormStartingPlayer) { diff --git a/src/rails/game/specific/_1835/PrussianFormationRound.java b/src/rails/game/specific/_1835/PrussianFormationRound.java index 344b6fc..35804ae 100644 --- a/src/rails/game/specific/_1835/PrussianFormationRound.java +++ b/src/rails/game/specific/_1835/PrussianFormationRound.java @@ -250,7 +250,7 @@ public class PrussianFormationRound extends StockRound { String message = LocalText.getText("START_MERGED_COMPANY", PR_ID, Currency.format(this, prussian.getIPOPrice()), - prussian.getStartSpace()); + prussian.getStartSpace().toText()); ReportBuffer.add(message); if (display) DisplayBuffer.add(message); @@ -342,7 +342,7 @@ public class PrussianFormationRound extends StockRound { player.getId(), cert.getShare(), PR_ID, - ipo.getId(), + ipo.getParent().getId(), company.getId()); ReportBuffer.add(message); if (display) DisplayBuffer.add (message); diff --git a/src/test/data/test/1835_PR_3rdTrain.rails b/src/test/data/test/1835_PR_3rdTrain.rails index e2e9503..e9709aa 100644 Binary files a/src/test/data/test/1835_PR_3rdTrain.rails and b/src/test/data/test/1835_PR_3rdTrain.rails differ diff --git a/src/test/data/test/1835_PR_3rdTrain.report b/src/test/data/test/1835_PR_3rdTrain.report index 6ddf818..2e256e6 100644 --- a/src/test/data/test/1835_PR_3rdTrain.report +++ b/src/test/data/test/1835_PR_3rdTrain.report @@ -1058,46 +1058,3 @@ FirstTrainBought,5 StartOfPhase,5 PrivateCloses,OBB PrivateCloses,PfB -CompanyDiscardsTrain,SX,3 - -EndOfOperatingRound,7.1 -ORWorthIncrease,Alice,7.1,549 -ORWorthIncrease,Bob,7.1,824 -ORWorthIncrease,Charlie,7.1,946 -Has,BY,250 -Has,SX,175 -Has,BA,24 -Has,WT,752 -Has,HE,649 -Has,PR,663 -Has,Alice,317 -Has,Bob,770 -Has,Charlie,615 -START_OR,7.2 - -CompanyOperates,BY,Alice -LaysTileAt,BY,220,E19,SW -CompanyRevenue,BY,140 -CompanyPaysOutFull,BY,140 -Payout,Alice,98,7,10 -Payout,Bob,28,2,10 -Payout,Charlie,14,1,10 -PRICE_MOVES_LOG,BY,232,J1,258,K1 -BuysTrain,BY,5,WT,1 - -CompanyOperates,SX,Charlie -LaysTileAt,SX,216,H20,E -CompanyRevenue,SX,300 -CompanyWithholds,SX,300 -PRICE_MOVES_LOG,SX,166,G1,148,F1 - -CompanyOperates,PR,Bob -LaysTileAtFor,PR,221,C11,SW,50 -CompanyRevenue,PR,350 -CompanyPaysOutFull,PR,350 -Payout,Alice,105,6,5 -Payout,Bob,123,7,5 -Payout,Charlie,123,7,5 -PRICE_MOVES_LOG,PR,154,I4,172,J4 -BuysTrain,PR,5,IPO,500 -All 5-trains are sold out, 5+5-trains now available commit 75076388bb90838d87bd4d3da4aa3bf379ac89d0 Author: Stefan Frey <ste...@we...> Date: Wed Sep 19 09:53:40 2012 +0200 renamed cert# into cert_ diff --git a/src/rails/game/PublicCompany.java b/src/rails/game/PublicCompany.java index fd812e3..660d0a4 100644 --- a/src/rails/game/PublicCompany.java +++ b/src/rails/game/PublicCompany.java @@ -693,7 +693,7 @@ public class PublicCompany extends RailsAbstractItem implements Company, MoneyOw } for (int k = 0; k < number; k++) { - certificate = new PublicCertificate(this, "cert#" + certIndex, shares, president, + certificate = new PublicCertificate(this, "cert_" + certIndex, shares, president, certIsInitiallyAvailable, certificateCount, certIndex++); certificates.add(certificate); shareTotal += shares * shareUnit.value(); commit 45cda25271bcf5a37bdba7aecaea9d2e466977cb Author: Stefan Frey <ste...@we...> Date: Wed Sep 19 09:51:56 2012 +0200 fixed issues with 1856 testgames diff --git a/src/rails/game/Bank.java b/src/rails/game/Bank.java index ffe7616..6a03798 100644 --- a/src/rails/game/Bank.java +++ b/src/rails/game/Bank.java @@ -14,7 +14,7 @@ import rails.game.model.WalletMoneyModel; import rails.game.state.BooleanState; import rails.game.state.Change; import rails.game.state.Observable; -import rails.game.state.Trigger; +import rails.game.state.Triggerable; import rails.game.state.UnknownOwner; import rails.util.Util; @@ -52,7 +52,7 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable { // Instance initializer to create a BankBroken model { - new Trigger() { + new Triggerable() { {// instance initializer cash.addTrigger(this); } diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java index 3f1d159..a9fb0dc 100644 --- a/src/rails/game/OperatingRound.java +++ b/src/rails/game/OperatingRound.java @@ -2095,7 +2095,7 @@ public class OperatingRound extends Round implements Observer { ReportBuffer.add(LocalText.getText("BuysBonusTokenFrom", operatingCompany.value().getId(), - sbt.getId(), + sbt.getName(), bank.getCurrency().format(sbt.getValue()), // TODO: Do this nicer seller.getId(), bank.getCurrency().format(sbt.getPrice()))); // TODO: Do this nicer diff --git a/src/rails/game/PrivateCompany.java b/src/rails/game/PrivateCompany.java index 7e1abd2..b968d14 100644 --- a/src/rails/game/PrivateCompany.java +++ b/src/rails/game/PrivateCompany.java @@ -519,7 +519,7 @@ public class PrivateCompany extends OwnableItem<PrivateCompany> implements Compa * @return Boolean */ public boolean hasSpecialProperties() { - return specialProperties != null && !specialProperties.isEmpty(); + return !specialProperties.isEmpty(); } // Company methods @@ -550,7 +550,7 @@ public class PrivateCompany extends OwnableItem<PrivateCompany> implements Compa public ImmutableSet<SpecialProperty> getSpecialProperties() { return specialProperties.items(); } - + // RailsItem methods @Override public RailsItem getParent() { diff --git a/src/rails/game/PublicCompany.java b/src/rails/game/PublicCompany.java index 4c29ee0..fd812e3 100644 --- a/src/rails/game/PublicCompany.java +++ b/src/rails/game/PublicCompany.java @@ -758,8 +758,8 @@ public class PublicCompany extends RailsAbstractItem implements Company, MoneyOw // Can companies acquire special rights (such as in 1830 Coalfields)? // TODO: Can this be simplified? - if (portfolio.getSpecialProperties() != null) { - for (SpecialProperty sp : portfolio.getSpecialProperties()) { + if (portfolio.hasSpecialProperties()) { + for (SpecialProperty sp : portfolio.getPersistentSpecialProperties()) { if (sp instanceof SpecialRight) { gameManager.setGuiParameter (GuiDef.Parm.HAS_ANY_RIGHTS, true); // Initialize rights here to prevent overhead if not used, @@ -2030,7 +2030,7 @@ public class PublicCompany extends RailsAbstractItem implements Company, MoneyOw } public ImmutableSet<SpecialProperty> getSpecialProperties() { - return portfolio.getSpecialProperties().items(); + return portfolio.getPersistentSpecialProperties(); } diff --git a/src/rails/game/action/ExchangeTokens.java b/src/rails/game/action/ExchangeTokens.java index e8cda22..aad52c7 100644 --- a/src/rails/game/action/ExchangeTokens.java +++ b/src/rails/game/action/ExchangeTokens.java @@ -74,7 +74,14 @@ public class ExchangeTokens extends PossibleORAction { public boolean equalsAsOption(PossibleAction action) { if (!(action instanceof ExchangeTokens)) return false; ExchangeTokens a = (ExchangeTokens) action; - return a.tokensToExchange == tokensToExchange && a.company == company; + if (a.company != this.company) return false; + // check if all tokensToExchange are equal as option (without selected) + for (int i=0; i< tokensToExchange.size(); i++) { + if (!(a.tokensToExchange.get(i).equalsAsOption(tokensToExchange.get(i)))) { + return false; + } + } + return true; } @Override diff --git a/src/rails/game/action/ExchangeableToken.java b/src/rails/game/action/ExchangeableToken.java index 5add07a..34ac130 100644 --- a/src/rails/game/action/ExchangeableToken.java +++ b/src/rails/game/action/ExchangeableToken.java @@ -8,6 +8,8 @@ package rails.game.action; import java.io.Serializable; +import com.google.common.base.Objects; + /** * A simple, serializable class that holds the <i>original</i> location * of a Base token, to facilitate its replacement even after its company @@ -44,6 +46,11 @@ public class ExchangeableToken implements Serializable { this.selected = selected; } + public boolean equalsAsOption(ExchangeableToken other) { + return Objects.equal(this.cityName, other.cityName) + && Objects.equal(this.oldCompanyName, other.oldCompanyName); + } + public String toString() { return cityName+"["+oldCompanyName+"]" + (selected ? "*" : ""); diff --git a/src/rails/game/model/PortfolioModel.java b/src/rails/game/model/PortfolioModel.java index df3d495..db3bc30 100644 --- a/src/rails/game/model/PortfolioModel.java +++ b/src/rails/game/model/PortfolioModel.java @@ -19,10 +19,8 @@ import com.google.common.collect.ImmutableSortedSet; import rails.common.LocalText; import rails.game.Bank; import rails.game.BankPortfolio; -import rails.game.Bonus; import rails.game.BonusToken; import rails.game.Company; -import rails.game.Currency; import rails.game.GameManager; import rails.game.MoneyOwner; import rails.game.Player; @@ -33,7 +31,6 @@ import rails.game.ReportBuffer; import rails.game.Train; import rails.game.TrainCertificateType; import rails.game.TrainType; -import rails.game.special.LocatedBonus; import rails.game.special.SpecialProperty; import rails.game.state.Model; import rails.game.state.Owner; @@ -47,13 +44,12 @@ import rails.game.state.PortfolioSet; */ public class PortfolioModel extends Model { public static final String ID = "PortfolioModel"; - - protected static Logger log = - LoggerFactory.getLogger(PortfolioModel.class); - + + protected static Logger log = LoggerFactory.getLogger(PortfolioModel.class); + /** Owned certificates */ private final CertificatesModel certificates; - + /** Owned private companies */ private final PrivatesModel privates; @@ -63,13 +59,13 @@ public class PortfolioModel extends Model { /** Owned tokens */ // TODO Currently only used to discard expired Bonus tokens. private final Portfolio<BonusToken> bonusTokens; - + /** * Private-independent special properties. When moved here, a special * property no longer depends on the private company being alive. Example: * 18AL named train tokens. */ - private final Portfolio<SpecialProperty> specialProperties; + private final SpecialPropertiesModel specialProperties; private final GameManager gameManager; @@ -83,9 +79,10 @@ public class PortfolioModel extends Model { certificates = CertificatesModel.create(parent); privates = PrivatesModel.create(parent); trains = TrainsModel.create(parent); - bonusTokens = PortfolioSet.create(parent, "BonusTokens", BonusToken.class); - specialProperties = PortfolioSet.create(parent, "SpecialProperties", SpecialProperty.class); - + bonusTokens = + PortfolioSet.create(parent, "BonusTokens", BonusToken.class); + specialProperties = SpecialPropertiesModel.create(parent); + // change display style dependent on owner if (parent instanceof PublicCompany) { trains.setAbbrList(false); @@ -98,7 +95,7 @@ public class PortfolioModel extends Model { gameManager.addPortfolio(this); } - + public static PortfolioModel create(PortfolioOwner parent) { return new PortfolioModel(parent, ID); } @@ -106,20 +103,20 @@ public class PortfolioModel extends Model { public void finishConfiguration() { certificates.initShareModels(gameManager.getAllPublicCompanies()); } - + @Override public PortfolioOwner getParent() { - return (PortfolioOwner)super.getParent(); + return (PortfolioOwner) super.getParent(); } - - // returns the associated MoneyOwner + + // returns the associated MoneyOwner public MoneyOwner getMoneyOwner() { if (getParent() instanceof BankPortfolio) { - return ((BankPortfolio)getParent()).getParent(); + return ((BankPortfolio) getParent()).getParent(); } - return (MoneyOwner)getParent(); + return (MoneyOwner) getParent(); } - + public void transferAssetsFrom(PortfolioModel otherPortfolio) { // Move trains @@ -129,39 +126,44 @@ public class PortfolioModel extends Model { otherPortfolio.moveAllCertificates(this.getParent()); } - /** Low-level method, only to be called by the local addObject() method and by initialisation code. */ + /** + * Low-level method, only to be called by the local addObject() method and + * by initialisation code. + */ // TODO: Ignores position now, is this necessary? public void addPrivateCompany(PrivateCompany company) { // add to private Model privates.moveInto(company); - - if (company.getSpecialProperties() != null) { + + if (company.hasSpecialProperties()) { log.debug(company.getId() + " has special properties!"); } else { log.debug(company.getId() + " has no special properties"); } - // TODO: This should not be necessary as soon as a PlayerModel works correctly - updatePlayerWorth (); + // TODO: This should not be necessary as soon as a PlayerModel works + // correctly + updatePlayerWorth(); } - // FIXME: Solve the presidentShare problem, should not be identified at position zero - - protected void updatePlayerWorth () { + // FIXME: Solve the presidentShare problem, should not be identified at + // position zero + + protected void updatePlayerWorth() { if (getParent() instanceof Player) { - ((Player)getParent()).updateWorth(); + ((Player) getParent()).updateWorth(); } } - - public CertificatesModel getCertificatesModel() { - return certificates; - } - - public ShareModel getShareModel(PublicCompany company) { - return certificates.getShareModel(company); - } - + + public CertificatesModel getCertificatesModel() { + return certificates; + } + + public ShareModel getShareModel(PublicCompany company) { + return certificates.getShareModel(company); + } + public ImmutableSet<PrivateCompany> getPrivateCompanies() { return privates.getPortfolio().items(); } @@ -173,7 +175,9 @@ public class PortfolioModel extends Model { /** Get the number of certificates that count against the certificate limit */ public float getCertificateCount() { - float number = privates.getPortfolio().size(); // TODO: May not hold for all games, for example 1880 + float number = privates.getPortfolio().size(); // TODO: May not hold for + // all games, for example + // 1880 return number + certificates.getCertificateCount(); } @@ -182,13 +186,14 @@ public class PortfolioModel extends Model { return certificates.getPortfolio().view(); } - public ImmutableSortedSet<PublicCertificate> getCertificates(PublicCompany company) { + public ImmutableSortedSet<PublicCertificate> getCertificates( + PublicCompany company) { return certificates.getPortfolio().items(company); } /** * Find a certificate for a given company. - * + * * @param company The public company for which a certificate is found. * @param president Whether we look for a president or non-president * certificate. If there is only one certificate, this parameter has no @@ -200,14 +205,17 @@ public class PortfolioModel extends Model { return findCertificate(company, 1, president); } - /** Find a specified certificate - * @return (first) certificate found, null if not found */ - public PublicCertificate findCertificate(PublicCompany company, - int shares, boolean president) { + /** + * Find a specified certificate + * + * @return (first) certificate found, null if not found + */ + public PublicCertificate findCertificate(PublicCompany company, int shares, + boolean president) { for (PublicCertificate cert : certificates.getPortfolio().items(company)) { if (company.getShareUnit() == 100 || president - && cert.isPresidentShare() || !president - && !cert.isPresidentShare() && cert.getShares() == shares) { + && cert.isPresidentShare() || !president + && !cert.isPresidentShare() && cert.getShares() == shares) { return cert; } } @@ -223,16 +231,16 @@ public class PortfolioModel extends Model { } return list.build(); } - - public PublicCertificate getAnyCertOfType(String certTypeId) { - for (PublicCertificate cert : certificates) { - if (cert.getTypeId().equals(certTypeId)) { - return cert; - } - } - return null; + + public PublicCertificate getAnyCertOfType(String certTypeId) { + for (PublicCertificate cert : certificates) { + if (cert.getTypeId().equals(certTypeId)) { + return cert; + } + } + return null; } - + /** * Returns percentage that a portfolio contains of one company. */ @@ -244,7 +252,8 @@ public class PortfolioModel extends Model { boolean president) { int certs = 0; if (certificates.contains(company)) { - for (PublicCertificate cert : certificates.getPortfolio().items(company)) { + for (PublicCertificate cert : certificates.getPortfolio().items( + company)) { if (president) { if (cert.isPresidentShare()) return 1; } else if (cert.getShares() == unit) { @@ -254,7 +263,7 @@ public class PortfolioModel extends Model { } return certs; } - + public void moveAllCertificates(Owner owner) { certificates.getPortfolio().moveAll(owner); } @@ -262,7 +271,7 @@ public class PortfolioModel extends Model { /** * Swap this Portfolio's President certificate for common shares in another * Portfolio. - * + * * @param company The company whose Presidency is handed over. * @param other The new President's portfolio. * @return The common certificates returned. @@ -302,11 +311,11 @@ public class PortfolioModel extends Model { public void discardTrain(Train train) { // FIXME: This is a horrible list of method calls - GameManager.getInstance().getBank().getPool().getPortfolioModel().getTrainsModel().getPortfolio().moveInto(train); - - + GameManager.getInstance().getBank().getPool().getPortfolioModel().getTrainsModel().getPortfolio().moveInto( + train); + ReportBuffer.add(LocalText.getText("CompanyDiscardsTrain", - getParent().getId(), train.toText() )); + getParent().getId(), train.toText())); } // FIXME: Is this still needed? @@ -341,7 +350,7 @@ public class PortfolioModel extends Model { Set<Train> trainsFound = new HashSet<Train>(); Map<TrainType, Object> trainTypesFound = - new HashMap<TrainType, Object>(); + new HashMap<TrainType, Object>(); for (Train train : trains.getPortfolio()) { if (!trainTypesFound.containsKey(train.getType())) { trainsFound.add(train); @@ -355,7 +364,7 @@ public class PortfolioModel extends Model { public Train getTrainOfType(TrainCertificateType type) { return trains.getTrainOfType(type); } - + /** * Add a train to the train portfolio */ @@ -363,140 +372,78 @@ public class PortfolioModel extends Model { return trains.getPortfolio().moveInto(train); } - /** - * Add a special property. Used to make special properties independent of - * the private company that originally held it. - * Low-level method, only to be called by Move objects. - * - * @param property The special property object to add. - * @return True if successful. - */ - @Deprecated - public boolean addSpecialProperty(SpecialProperty property, int position) { - - /* - boolean result = specialProperties.addObject(property, position); - if (!result) return false; - - property.setOwner(specialProperties); - */ - // Special case for bonuses with predefined locations - // TODO Does this belong here? - // FIXME: This does not belong here as this method is not called anymore from anywhere - if (getParent() instanceof PublicCompany && property instanceof LocatedBonus) { - PublicCompany company = (PublicCompany)getParent(); - LocatedBonus locBonus = (LocatedBonus)property; - Bonus bonus = new Bonus(company, locBonus.getId(), locBonus.getValue(), - locBonus.getLocations()); - company.addBonus(bonus); - ReportBuffer.add(LocalText.getText("AcquiresBonus", - getParent().getId(), - locBonus.getId(), - Currency.format(getParent(), locBonus.getValue()), - locBonus.getLocationNameString())); - } - - return false; - } - - /** - * Add an object. - * Low-level method, only to be called by Move objects. + * Add an object. Low-level method, only to be called by Move objects. + * * @param object The object to add. * @return True if successful. */ // TODO: Is this still required? - /* public boolean addObject(Holdable object, int position) { - if (object instanceof PublicCertificate) { - if (position == null) position = new int[] {-1, -1, -1}; - addCertificate((PublicCertificate) object, position); - return true; - } else if (object instanceof PrivateCompany) { - addPrivate((PrivateCompany) object, position == null ? -1 : position[0]); - return true; - } else if (object instanceof Train) { - if (position == null) position = new int[] {-1, -1, -1}; - addTrain((Train) object, position); - return true; - } else if (object instanceof SpecialProperty) { - return addSpecialProperty((SpecialProperty) object, position == null ? -1 : position[0]); - } else if (object instanceof Token) { - return addToken((Token) object, position == null ? -1 : position[0]); - } else { - return false; - } - } -*/ - + /* + * public boolean addObject(Holdable object, int position) { if (object + * instanceof PublicCertificate) { if (position == null) position = new + * int[] {-1, -1, -1}; addCertificate((PublicCertificate) object, position); + * return true; } else if (object instanceof PrivateCompany) { + * addPrivate((PrivateCompany) object, position == null ? -1 : position[0]); + * return true; } else if (object instanceof Train) { if (position == null) + * position = new int[] {-1, -1, -1}; addTrain((Train) object, position); + * return true; } else if (object instanceof SpecialProperty) { return + * addSpecialProperty((SpecialProperty) object, position == null ? -1 : + * position[0]); } else if (object instanceof Token) { return + * addToken((Token) object, position == null ? -1 : position[0]); } else { + * return false; } } + */ + /** - * Remove an object. - * Low-level method, only to be called by Move objects. - * + * Remove an object. Low-level method, only to be called by Move objects. + * * @param object The object to remove. * @return True if successful. */ // TODO: Is this still required? -/* - public boolean removeObject(Holdable object) { - if (object instanceof PublicCertificate) { - removeCertificate((PublicCertificate) object); - return true; - } else if (object instanceof PrivateCompany) { - removePrivate((PrivateCompany) object); - return true; - } else if (object instanceof Train) { - removeTrain((Train) object); - return true; - } else if (object instanceof SpecialProperty) { - return removeSpecialProperty((SpecialProperty) object); - } else if (object instanceof Token) { - return removeToken((Token) object); - } else { - return false; - } - } -*/ - + /* + * public boolean removeObject(Holdable object) { if (object instanceof + * PublicCertificate) { removeCertificate((PublicCertificate) object); + * return true; } else if (object instanceof PrivateCompany) { + * removePrivate((PrivateCompany) object); return true; } else if (object + * instanceof Train) { removeTrain((Train) object); return true; } else if + * (object instanceof SpecialProperty) { return + * removeSpecialProperty((SpecialProperty) object); } else if (object + * instanceof Token) { return removeToken((Token) object); } else { return + * false; } } + */ + // TODO: Check if this is still required -/* public int[] getListIndex (Holdable object) { - if (object instanceof PublicCertificate) { - PublicCertificate cert = (PublicCertificate) object; - return new int[] { - certificates.indexOf(object), - certPerCompany.get(cert.getCompany().getId()).indexOf(cert), - certsPerType.get(cert.getTypeId()).indexOf(cert) - }; - } else if (object instanceof PrivateCompany) { - return new int[] {privateCompanies.indexOf(object)}; - } else if (object instanceof Train) { - Train train = (Train) object; - return new int[] { - trains.indexOf(train), - train.getPreviousType() != null ? trainsPerType.get(train.getPreviousType()).indexOf(train) : -1, - trainsPerCertType.get(train.getCertType()).indexOf(train) - }; - } else if (object instanceof SpecialProperty) { - return new int[] {specialProperties.indexOf(object)}; - } else if (object instanceof Token) { - return new int[] {tokens.indexOf(object)}; - } else { - return Holdable.AT_END; - } - } -*/ - + /* + * public int[] getListIndex (Holdable object) { if (object instanceof + * PublicCertificate) { PublicCertificate cert = (PublicCertificate) object; + * return new int[] { certificates.indexOf(object), + * certPerCompany.get(cert.getCompany().getId()).indexOf(cert), + * certsPerType.get(cert.getTypeId()).indexOf(cert) }; } else if (object + * instanceof PrivateCompany) { return new int[] + * {privateCompanies.indexOf(object)}; } else if (object instanceof Train) { + * Train train = (Train) object; return new int[] { trains.indexOf(train), + * train.getPreviousType() != null ? + * trainsPerType.get(train.getPreviousType()).indexOf(train) : -1, + * trainsPerCertType.get(train.getCertType()).indexOf(train) }; } else if + * (object instanceof SpecialProperty) { return new int[] + * {specialProperties.indexOf(object)}; } else if (object instanceof Token) + * { return new int[] {tokens.indexOf(object)}; } else { return + * Holdable.AT_END; } } + */ + /** * @return Set of all special properties we have. */ public ImmutableSet<SpecialProperty> getPersistentSpecialProperties() { - return specialProperties.items(); + return specialProperties.getPortfolio().items(); } public ImmutableList<SpecialProperty> getAllSpecialProperties() { - ImmutableList.Builder<SpecialProperty> sps = new ImmutableList.Builder<SpecialProperty>(); - if (specialProperties != null) sps.addAll(specialProperties); + ImmutableList.Builder<SpecialProperty> sps = + new ImmutableList.Builder<SpecialProperty>(); + sps.addAll(specialProperties.getPortfolio().items()); for (PrivateCompany priv : privates.getPortfolio()) { if (priv.getSpecialProperties() != null) { sps.addAll(priv.getSpecialProperties()); @@ -507,18 +454,13 @@ public class PortfolioModel extends Model { /** * Do we have any special properties? - * + * * @return Boolean */ public boolean hasSpecialProperties() { - return specialProperties != null && !specialProperties.isEmpty(); + return !specialProperties.getPortfolio().isEmpty(); } - public Portfolio<SpecialProperty> getSpecialProperties() { - return specialProperties; - } - - // TODO: Check if this code can be simplified @SuppressWarnings("unchecked") public <T extends SpecialProperty> List<T> getSpecialProperties( @@ -526,7 +468,8 @@ public class PortfolioModel extends Model { List<T> result = new ArrayList<T>(); Set<SpecialProperty> sps; - if (getParent() instanceof Player || getParent() instanceof PublicCompany) { + if (getParent() instanceof Player + || getParent() instanceof PublicCompany) { for (PrivateCompany priv : privates.getPortfolio()) { @@ -535,27 +478,29 @@ public class PortfolioModel extends Model { for (SpecialProperty sp : sps) { if ((clazz == null || clazz.isAssignableFrom(sp.getClass())) - && sp.isExecutionable() - && (!sp.isExercised() || includeExercised) - && (getParent() instanceof Company && sp.isUsableIfOwnedByCompany() - || getParent()instanceof Player && sp.isUsableIfOwnedByPlayer())) { - log.debug("Portfolio "+getParent().getId()+" has SP " + sp); + && sp.isExecutionable() + && (!sp.isExercised() || includeExercised) + && (getParent() instanceof Company + && sp.isUsableIfOwnedByCompany() || getParent() instanceof Player + && sp.isUsableIfOwnedByPlayer())) { + log.debug("Portfolio " + getParent().getId() + + " has SP " + sp); result.add((T) sp); } } } // Private-independent special properties - if (specialProperties != null) { - for (SpecialProperty sp : specialProperties) { - if ((clazz == null || clazz.isAssignableFrom(sp.getClass())) - && sp.isExecutionable() - && (!sp.isExercised() || includeExercised) - && (getParent() instanceof Company && sp.isUsableIfOwnedByCompany() - || getParent() instanceof Player && sp.isUsableIfOwnedByPlayer())) { - log.debug("Portfolio "+getParent().getId()+" has persistent SP " + sp); - result.add((T) sp); - } + for (SpecialProperty sp : specialProperties.getPortfolio()) { + if ((clazz == null || clazz.isAssignableFrom(sp.getClass())) + && sp.isExecutionable() + && (!sp.isExercised() || includeExercised) + && (getParent() instanceof Company + && sp.isUsableIfOwnedByCompany() || getParent() instanceof Player + && sp.isUsableIfOwnedByPlayer())) { + log.debug("Portfolio " + getParent().getId() + + " has persistent SP " + sp); + result.add((T) sp); } } @@ -568,14 +513,14 @@ public class PortfolioModel extends Model { return privates; } - public boolean addBonusToken(BonusToken token){ + public boolean addBonusToken(BonusToken token) { return bonusTokens.moveInto(token); } - + public Portfolio<BonusToken> getTokenHolder() { return bonusTokens; } - + public void rustObsoleteTrains() { List<Train> trainsToRust = new ArrayList<Train>(); @@ -590,7 +535,7 @@ public class PortfolioModel extends Model { ReportBuffer.add(LocalText.getText("TrainsObsoleteRusted", train.toText(), getParent().getId())); log.debug("Obsolete train " + train.getId() + " (owned by " - + getParent().getId() + ") rusted"); + + getParent().getId() + ") rusted"); train.setRusted(); } // FIXME:: Still required? @@ -604,18 +549,18 @@ public class PortfolioModel extends Model { public String getName() { return getParent().getId(); } - + /** - * Used to identify portfolios on reload - * TODO: Remove that in the future + * Used to identify portfolios on reload TODO: Remove that in the future */ @Deprecated - public String getUniqueName () { + public String getUniqueName() { // For BankPortfolios use Bank if (getParent() instanceof BankPortfolio) { return Bank.class.getSimpleName() + "_" + getParent().getId(); } - return getParent().getClass().getSimpleName() + "_" + getParent().getId(); + return getParent().getClass().getSimpleName() + "_" + + getParent().getId(); } } diff --git a/src/rails/game/special/LocatedBonus.java b/src/rails/game/special/LocatedBonus.java index c20d58c..a603480 100644 --- a/src/rails/game/special/LocatedBonus.java +++ b/src/rails/game/special/LocatedBonus.java @@ -70,6 +70,10 @@ public final class LocatedBonus extends SpecialProperty { public int getValue() { return value; } + + public String getName() { + return name; + } @Override public String toText() { diff --git a/src/rails/game/specific/_1856/CGRFormationRound.java b/src/rails/game/specific/_1856/CGRFormationRound.java index 7252db9..cc0cb02 100644 --- a/src/rails/game/specific/_1856/CGRFormationRound.java +++ b/src/rails/game/specific/_1856/CGRFormationRound.java @@ -436,8 +436,7 @@ public class CGRFormationRound extends SwitchableUIRound { ReportBuffer.add(message); // Move the remaining CGR shares to the ipo. - // Clone the shares list first - cgr.getPortfolioModel().moveAllCertificates(ipo.getParent()); + Portfolio.moveAll(unavailable.getCertificates(cgr), ipo.getParent()); // Assign the new president if (newPresident.getPortfolioModel().getShare(cgr) == cgr.getShareUnit()) { @@ -630,7 +629,7 @@ bonuses: for (Bonus bonus : bonuses) { String cityName; for (BaseToken token : nonHomeTokens) { if (token.getOwner() instanceof Stop) { - cityName = token.getOwner().getId(); + cityName = ((Stop)token.getOwner()).getSpecificId(); if (oldTokens.containsKey(cityName)) { oldTokens.put(cityName, oldTokens.get(cityName)+","+token.getParent().getId()); diff --git a/src/rails/game/state/Observable.java b/src/rails/game/state/Observable.java index 08ae14d..95d72af 100644 --- a/src/rails/game/state/Observable.java +++ b/src/rails/game/state/Observable.java @@ -69,15 +69,15 @@ public abstract class Observable implements Item { return getStateManager().getModels(this); } - public void addTrigger(Trigger m) { + public void addTrigger(Triggerable m) { getStateManager().addTrigger(m, this); } - public boolean removeTrigger(Trigger m) { + public boolean removeTrigger(Triggerable m) { return getStateManager().removeTrigger(m, this); } - public ImmutableSet<Trigger> getTriggers() { + public ImmutableSet<Triggerable> getTriggers() { return getStateManager().getTriggers(this); } diff --git a/src/rails/game/state/PortfolioChange.java b/src/rails/game/state/PortfolioChange.java index d1cc3d5..f82b67e 100644 --- a/src/rails/game/state/PortfolioChange.java +++ b/src/rails/game/state/PortfolioChange.java @@ -1,6 +1,6 @@ package rails.game.state; -final class PortfolioChange<T extends Ownable> extends Change { +public final class PortfolioChange<T extends Ownable> extends Change { private final Portfolio<T> portfolio; private final T item; @@ -36,5 +36,14 @@ final class PortfolioChange<T extends Ownable> extends Change { return "Change for " + portfolio + ": Remove " + item; } } + + // external information + public T getItem() { + return item; + } + + public boolean isIntoPortfolio() { + return intoPortfolio; + } } diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java index 26648a1..f987953 100644 --- a/src/rails/game/state/StateManager.java +++ b/src/rails/game/state/StateManager.java @@ -27,7 +27,7 @@ public final class StateManager extends Manager{ HashSetState.create(this, "allStates"); private final HashMultimapState<Observable, Model> models = HashMultimapState.create(this, "models"); - private final HashMultimapState<Observable, Trigger> triggers = + private final HashMultimapState<Observable, Triggerable> triggers = HashMultimapState.create(this, "triggers"); @@ -122,25 +122,25 @@ public final class StateManager extends Manager{ /** * Adds the combination of trigger to observable - * @param Trigger the trigger that tracks the observable + * @param Triggerable the trigger that tracks the observable * @param Observable the observable to monitor */ - void addTrigger(Trigger trigger, Observable observable) { + void addTrigger(Triggerable trigger, Observable observable) { triggers.put(observable, trigger); } - boolean removeTrigger(Trigger trigger, Observable observable) { + boolean removeTrigger(Triggerable trigger, Observable observable) { return triggers.remove(observable, trigger); } - ImmutableSet<Trigger> getTriggers(Observable observable) { + ImmutableSet<Triggerable> getTriggers(Observable observable) { return triggers.get(observable); } void informTriggers(State state, Change change) { // Inform direct triggers - for (Trigger t:getTriggers(state)) { + for (Triggerable t:getTriggers(state)) { t.triggered(state, change); log.debug("State " + state + " sends change to Trigger " + t); } @@ -152,7 +152,7 @@ public final class StateManager extends Manager{ // Inform indirect triggers for (Model m:allModels) { - for (Trigger t:getTriggers(m)) { + for (Triggerable t:getTriggers(m)) { t.triggered(m, change); log.debug("Model " + m + " sends change to Trigger " + t); } diff --git a/src/rails/game/state/Trigger.java b/src/rails/game/state/Trigger.java deleted file mode 100644 index 6d98021..0000000 --- a/src/rails/game/state/Trigger.java +++ /dev/null @@ -1,11 +0,0 @@ -package rails.game.state; - -public interface Trigger { - - /** - * Method that is called if something has changed - */ - public void triggered(Observable observable, Change change); - - -} diff --git a/src/rails/game/state/Triggerable.java b/src/rails/game/state/Triggerable.java new file mode 100644 index 0000000..7f984f4 --- /dev/null +++ b/src/rails/game/state/Triggerable.java @@ -0,0 +1,11 @@ +package rails.game.state; + +public interface Triggerable { + + /** + * Method that is called if something has changed + */ + public void triggered(Observable observable, Change change); + + +} diff --git a/src/test/data/real/1856_A.report b/src/test/data/real/1856_A.report index e063728..e3ea294 100644 --- a/src/test/data/real/1856_A.report +++ b/src/test/data/real/1856_A.report @@ -1807,8 +1807,8 @@ CompanyOperates,CV,Joakim LaysTileAt,CV,24,L11,NE CompanyRevenue,CV,630 CompanyPaysOutFull,CV,630 -Payout,Joakim,378,6,10 BankIsBrokenReportText +Payout,Joakim,378,6,10 Payout,Aliza,126,2,10 Payout,Ed,63,1,10 Payout,Adam,63,1,10 commit a7726f3b4592029e679c8c72388afee840d38b1c Author: Stefan Frey <ste...@we...> Date: Tue Sep 18 12:26:28 2012 +0200 Fixed issue with ClosesOnFirstTrain for 1830_5forDtrainExchange test game diff --git a/src/rails/game/PublicCompany.java b/src/rails/game/PublicCompany.java index 4199638..4c29ee0 100644 --- a/src/rails/game/PublicCompany.java +++ b/src/rails/game/PublicCompany.java @@ -462,7 +462,7 @@ public class PublicCompany extends RailsAbstractItem implements Company, MoneyOw firstTrainTag.getAttributeAsString("type", "Private"); if (typeName.equalsIgnoreCase("Private")) { privateToCloseOnFirstTrainName = - firstTrainTag.getAttributeAsString("getId()"); + firstTrainTag.getAttributeAsString("name"); } else { throw new ConfigurationException( "Only Privates can be closed on first train buy"); commit e66c163215df2b40f79e97538428b246120eef43 Author: Stefan Frey <ste...@we...> Date: Tue Sep 18 11:46:21 2012 +0200 Fixed issues with test 18EU games 18EU_A is wrong in the processing the Pullman purchases from the Pool 18EU_After2nd8Train is removed due to invalid action 247 diff --git a/src/rails/game/StartRound.java b/src/rails/game/StartRound.java index c0b63a8..5b1d8a1 100644 --- a/src/rails/game/StartRound.java +++ b/src/rails/game/StartRound.java @@ -261,7 +261,7 @@ public abstract class StartRound extends Round { String priceText = Currency.toBank(player, price); ReportBuffer.add(LocalText.getText("BuysItemFor", player.getId(), - primary.getId(), + primary.getName(), priceText )); transferCertificate (primary, player.getPortfolioModel()); checksOnBuying(primary, sharePrice); diff --git a/src/rails/game/specific/_18EU/StockRound_18EU.java b/src/rails/game/specific/_18EU/StockRound_18EU.java index 1fbf341..59b1947 100644 --- a/src/rails/game/specific/_18EU/StockRound_18EU.java +++ b/src/rails/game/specific/_18EU/StockRound_18EU.java @@ -429,7 +429,7 @@ public class StockRound_18EU extends StockRound { currentPlayer.getId(), cert2.getShare(), company.getId(), - ipo.getId(), + ipo.getParent().getId(), minor.getId() )); } else { ReportBuffer.add(LocalText.getText("SelectedHomeBase", diff --git a/src/test/data/real/18EU_A.report b/src/test/data/real/18EU_A.report index b43ad0b..316b937 100644 --- a/src/test/data/real/18EU_A.report +++ b/src/test/data/real/18EU_A.report @@ -1740,7 +1740,7 @@ Payout,Arne,23,1,10 Payout,Joakim,115,5,10 Payout,Ed,46,2,10 PRICE_MOVES_LOG,KKÃB,165,I2,180,J2 -BuysTrain,KKÃB,P,SNCF,100 +BuysTrain,KKÃB,P,Pool,100 CompanyOperates,SNCF,Arne LaysTileAt,SNCF,513,I6,S @@ -1790,7 +1790,7 @@ SNCB receives 110 Payout,Arne,11,1,10 Payout,Joakim,55,5,10 PRICE_MOVES_LOG,SNCB,70,D6,75,E6 -BuysTrain,SNCB,P,KKÃB,100 +BuysTrain,SNCB,P,Pool,100 CompanyOperates,FS,Chris LaysTileAt,FS,582,S8,NE @@ -1812,9 +1812,9 @@ Has,SNCB,48 Has,NS,47 Has,KBS,8 Has,KPEV,670 -Has,KKÃB,221 +Has,KKÃB,121 Has,FS,2 -Has,SNCF,174 +Has,SNCF,74 Has,DR,18 Has,Chris,476 Has,Joakim,556 @@ -1870,9 +1870,9 @@ Has,SNCB,48 Has,NS,47 Has,KBS,8 Has,KPEV,670 -Has,KKÃB,221 +Has,KKÃB,121 Has,FS,2 -Has,SNCF,174 +Has,SNCF,74 Has,DR,18 Has,Chris,431 Has,Joakim,556 @@ -1931,6 +1931,7 @@ Payout,Arne,24,1,10 Payout,Joshua,144,6,10 PRICE_MOVES_LOG,KPEV,122,G3,135,H3 BuysTrain,KPEV,8,IPO,800 +CompanyDiscardsTrain,KPEV,P CompanyOperates,DR,Chris LaysTileAt,DR,513,G4,S @@ -1973,9 +1974,9 @@ Has,SNCB,48 Has,NS,47 Has,KBS,8 Has,KPEV,50 -Has,KKÃB,221 +Has,KKÃB,121 Has,FS,2 -Has,SNCF,174 +Has,SNCF,74 Has,DR,18 Has,Chris,1053 Has,Joakim,1179 @@ -2061,8 +2062,8 @@ LAYS_FREE_TOKEN_ON,FS,S8 CompanyRevenue,FS,350 CompanyPaysOutFull,FS,350 Payout,Arne,35,1,10 -BankIsBrokenReportText Payout,Ed,70,2,10 +BankIsBrokenReportText Payout,Chris,140,4,10 PRICE_MOVES_LOG,FS,70,D6,75,E6 @@ -2077,9 +2078,9 @@ Has,SNCB,48 Has,NS,47 Has,KBS,8 Has,KPEV,50 -Has,KKÃB,221 +Has,KKÃB,121 Has,FS,2 -Has,SNCF,174 +Has,SNCF,74 Has,DR,18 Has,Chris,1713 Has,Joakim,1911 diff --git a/src/test/data/test/18EU_After2nd8Train.rails b/src/test/data/test/18EU_After2nd8Train.rails deleted file mode 100644 index 6c8dcb7..0000000 Binary files a/src/test/data/test/18EU_After2nd8Train.rails and /dev/null differ diff --git a/src/test/data/test/18EU_After2nd8Train.report b/src/test/data/test/18EU_After2nd8Train.report deleted file mode 100644 index 6ec498c..0000000 --- a/src/test/data/test/18EU_After2nd8Train.report +++ /dev/null @@ -1,1194 +0,0 @@ -GameIs,18EU -PlayerIs,1,Alice -PlayerIs,2,Bob -PlayerIs,3,Charlie -PlayerCash,450 -BankHas,10650 -StartOfPhase,2 -BankSizeIs,10650 -StartOfInitialRound -HasPriority,Alice - -SelectForAuctioning,Alice,1 -BID_ITEM,Alice,100,1 -PASSES,Bob -PASSES,Charlie -BuysItemFor,Alice,1,100 -Floats,1 - -SelectForAuctioning,Bob,2 -BID_ITEM,Bob,100,2 -PASSES,Charlie -PASSES,Alice -BuysItemFor,Bob,2,100 -Floats,2 - -SelectForAuctioning,Charlie,3 -BID_ITEM,Charlie,100,3 -PASSES,Alice -PASSES,Bob -BuysItemFor,Charlie,3,100 -Floats,3 - -SelectForAuctioning,Alice,4 -BID_ITEM,Alice,100,4 -PASSES,Bob -PASSES,Charlie -BuysItemFor,Alice,4,100 -Floats,4 - -SelectForAuctioning,Bob,5 -BID_ITEM,Bob,100,5 -PASSES,Charlie -PASSES,Alice -BuysItemFor,Bob,5,100 -Floats,5 - -SelectForAuctioning,Charlie,6 -BID_ITEM,Charlie,100,6 -PASSES,Alice -PASSES,Bob -BuysItemFor,Charlie,6,100 -Floats,6 - -SelectForAuctioning,Alice,7 -BID_ITEM,Alice,100,7 -PASSES,Bob -PASSES,Charlie -BuysItemFor,Alice,7,100 -Floats,7 - -SelectForAuctioning,Bob,8 -BID_ITEM,Bob,100,8 -PASSES,Charlie -PASSES,Alice -BuysItemFor,Bob,8,100 -Floats,8 - -SelectForAuctioning,Charlie,9 -BID_ITEM,Charlie,100,9 -PASSES,Alice -PASSES,Bob -BuysItemFor,Charlie,9,100 -Floats,9 - -SelectForAuctioning,Alice,10 -BID_ITEM,Alice,100,10 -PASSES,Bob -PASSES,Charlie -BuysItemFor,Alice,10,100 -Floats,10 - -SelectForAuctioning,Bob,11 -BID_ITEM,Bob,100,11 -PASSES,Charlie -PASSES,Alice -BuysItemFor,Bob,11,100 -Floats,11 - -SelectForAuctioning,Charlie,12 -BID_ITEM,Charlie,100,12 -PASSES,Alice -PASSES,Bob -BuysItemFor,Charlie,12,100 -Floats,12 - -SelectForAuctioning,Alice,13 -PASSES,Bob -PASSES,Charlie -ITEM_PRICE_REDUCED,13,90 -PASSES,Alice -PASSES,Bob -PASSES,Charlie -ITEM_PRICE_REDUCED,13,80 -PASSES,Alice -PASSES,Bob -PASSES,Charlie -ITEM_PRICE_REDUCED,13,70 -PASSES,Alice -PASSES,Bob -PASSES,Charlie -ITEM_PRICE_REDUCED,13,60 -PASSES,Alice -PASSES,Bob -PASSES,Charlie -ITEM_PRICE_REDUCED,13,50 -BuysItemFor,Alice,13,50 -Floats,13 - -SelectForAuctioning,Bob,14 -PASSES,Charlie -PASSES,Alice -ITEM_PRICE_REDUCED,14,90 -PASSES,Bob -PASSES,Charlie -PASSES,Alice -ITEM_PRICE_REDUCED,14,80 -PASSES,Bob -PASSES,Charlie -PASSES,Alice -ITEM_PRICE_REDUCED,14,70 -PASSES,Bob -PASSES,Charlie -PASSES,Alice -ITEM_PRICE_REDUCED,14,60 -PASSES,Bob -PASSES,Charlie -PASSES,Alice -ITEM_PRICE_REDUCED,14,50 -BuysItemFor,Bob,14,50 -Floats,14 - -SelectForAuctioning,Charlie,15 -PASSES,Alice -PASSES,Bob -ITEM_PRICE_REDUCED,15,90 -PASSES,Charlie -PASSES,Alice -PASSES,Bob -ITEM_PRICE_REDUCED,15,80 -PASSES,Charlie -PASSES,Alice -PASSES,Bob -ITEM_PRICE_REDUCED,15,70 -PASSES,Charlie -PASSES,Alice -PASSES,Bob -ITEM_PRICE_REDUCED,15,60 -PASSES,Charlie -PASSES,Alice -PASSES,Bob -ITEM_PRICE_REDUCED,15,50 -BuysItemFor,Charlie,15,50 -All 2-trains are sold out, 3-trains now available -Floats,15 -Has,1,0 -Has,2,0 -Has,3,0 -Has,4,0 -Has,5,0 -Has,6,0 -Has,7,0 -Has,8,0 -Has,9,0 -Has,10,0 -Has,11,0 -Has,12,0 -Has,13,0 -Has,14,0 -Has,15,0 -Has,Alice,0 -Has,Bob,0 -Has,Charlie,0 -START_OR,0.1 - -CompanyOperates,1,Alice -LaysTileAt,1,8,I2,SW -LaysTileAt,1,58,G2,S -CompanyRevenue,1,90 -CompanySplits,1,90 -1 receives 45 -Payout,Alice,45,1,100 - -CompanyOperates,2,Bob -LaysTileAt,2,201,H3,NE -LaysTileAt,2,4,F3,SW -CompanyRevenue,2,40 -CompanySplits,2,40 -2 receives 20 -Payout,Bob,20,1,100 - -CompanyOperates,3,Charlie -LaysTileAt,3,8,K2,S -LaysTileAt,3,3,M2,N -CompanyRevenue,3,50 -CompanySplits,3,50 -3 receives 25 -Payout,Charlie,25,1,100 - -CompanyOperates,4,Alice -LaysTileAt,4,202,G10,NE -LaysTileAt,4,4,H9,NW -CompanyRevenue,4,40 -CompanySplits,4,40 -4 receives 20 -Payout,Alice,20,1,100 - -CompanyOperates,5,Bob -LaysTileAt,5,201,S8,SW -LaysTileAt,5,8,U8,SW -CompanyRevenue,5,60 -CompanySplits,5,60 -5 receives 30 -Payout,Bob,30,1,100 - -CompanyOperates,6,Charlie -LaysTileAt,6,58,L11,S -LaysTileAt,6,57,K10,NW -CompanyRevenue,6,60 -CompanySplits,6,60 -6 receives 30 -Payout,Charlie,30,1,100 - -CompanyOperates,7,Alice -LaysTileAt,7,9,F9,SW -LaysTileAt,7,58,G8,NW -CompanyRevenue,7,40 -CompanyS... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-09-17 18:19:56
|
Tag 'v1.7.9' created by Stefan Frey <ste...@we...> at 2012-09-17 18:19 +0000 release 1.7.9 Changes since v1.7.8-2: --- 0 files changed --- |
From: Stefan F. <ste...@us...> - 2012-09-17 18:19:53
|
readme.txt | 12 ++++++------ version.number | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) New commits: commit 2a12d199876712dd7e83f5ed491e05365e644b5a Author: Stefan Frey <ste...@we...> Date: Mon Sep 17 20:18:41 2012 +0200 prepared for 1.7.9 release diff --git a/readme.txt b/readme.txt index 111a7c4..ba355d5 100644 --- a/readme.txt +++ b/readme.txt @@ -1,13 +1,13 @@ -Rails release 1.7.8: +Rails release 1.7.9: A new maintenance release for Rails 1.x series -This release fixes several bugs. +This release fixes two bugs. -Contributors: Erik Vos, Stefan Frey +Contributors: Stefan Frey -Bugs reported by Martin Brumm, John David Galt +Bugs reported by Arne Ãsterlund Lists of bugs fixed: -- All Games: Update "PD" label in GameStatus lower player names panel -- 1835 (and others with NoMapMode): Cannot save game file with ClosePrivate action +- List of recent files does not work with few entries +- 1830 Coalfields (and others): Obsolete Trains in Pool should rust (previously the stayed forever) diff --git a/version.number b/version.number index f74a335..385bed2 100644 --- a/version.number +++ b/version.number @@ -1,5 +1,5 @@ #Property file that contains version number and the develop indicator -version=1.7.8 +version=1.7.9 # 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 |
From: Stefan F. <ste...@us...> - 2012-09-17 16:48:19
|
rails/game/TrainManager.java | 2 +- rails/ui/swing/GameSetupWindow.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) New commits: commit 1cb73edf9ec9657eaac3665cf7db57908556e88f Author: Stefan Frey <ste...@we...> Date: Mon Sep 17 18:47:13 2012 +0200 fixed problem of obsoleting trains in the pool, as reported by arne oestlund diff --git a/rails/game/TrainManager.java b/rails/game/TrainManager.java index b99b128..be27fa9 100644 --- a/rails/game/TrainManager.java +++ b/rails/game/TrainManager.java @@ -1 +1 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/TrainManager.java,v 1.28 2010/04/21 21:25:50 evos Exp $ */ package rails.game; import java.util.*; import org.apache.log4j.Logger; import rails.common.LocalText; import rails.common.parser.ConfigurableComponentI; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.move.ObjectMove; import rails.game.state.BooleanState; import rails.game.state.IntegerState; import rails.util.Util; public class TrainManager implements ConfigurableComponentI { // Static attributes protected List<TrainType> lTrainTypes = new ArrayList<TrainType>(); protected Map<String, TrainType> mTrainTypes = new HashMap<String, TrainType>(); protected List<TrainCertificateType> trainCertTypes = new ArrayList<TrainCertificateType>(); protected Map<String, TrainCertificateType> trainCertTypeMap = new HashMap<String, TrainCertificateType>(); protected Map<String, TrainI> trainMap = new HashMap<String, TrainI>(); protected Map<TrainCertificateType, List<TrainI>> trainsPerCertType = new HashMap<TrainCertificateType, List<TrainI>>(); protected TrainType defaultType = null; // Only required locally and in ChoiceType private boolean removeTrain = false; // defines obsolescence public enum ObsoleteTrainForType {ALL, EXCEPT_TRIGGERING} protected ObsoleteTrainForType obsoleteTrainFor = ObsoleteTrainForType.EXCEPT_TRIGGERING; // default is ALL // Dynamic attributes protected IntegerState newTypeIndex; protected Map<String, Integer> lastIndexPerType = new HashMap<String, Integer>(); protected boolean trainsHaveRusted = false; protected boolean phaseHasChanged = false; protected boolean trainAvailabilityChanged = false; protected List<PublicCompanyI> companiesWithExcessTrains; protected GameManagerI gameManager = null; protected Bank bank = null; /** Required for the sell- |
From: Erik V. <ev...@us...> - 2012-09-11 15:05:58
|
data/1835/Map.xml | 4 data/18EU/Map.xml | 17 + rails/algorithms/NetworkVertex.java | 12 - rails/game/Access.java | 278 ++++++++++++++++++++++++++++++ rails/game/MapHex.java | 329 +++++++++++++++--------------------- rails/game/MapManager.java | 122 +++++-------- rails/game/Round.java | 2 rails/game/Stop.java | 264 ++++++++++++++++------------ rails/game/Tile.java | 131 ++++++-------- rails/game/TileI.java | 11 - rails/game/TileManager.java | 2 11 files changed, 703 insertions(+), 469 deletions(-) New commits: commit a93d12400e721257f5d894be59f3e0db030b434b Author: Erik Vos <eri...@xs...> Date: Tue Sep 11 15:51:06 2012 +0200 Stop properties update diff --git a/data/1835/Map.xml b/data/1835/Map.xml index 961ff4a..2ad82bc 100644 --- a/data/1835/Map.xml +++ b/data/1835/Map.xml @@ -33,7 +33,9 @@ <Hex name="E13" tile="0"/> <Hex name="E15" tile="0" cost="50"/> <Hex name="E17" tile="0"/> - <Hex name="E19" tile="-806" city="Berlin" unlaidHomeBlocksTokens="no"/> + <Hex name="E19" tile="-806" city="Berlin" unlaidHomeBlocksTokens="no"> + <Access trainMutexID="Berlin"/> + </Hex> <Hex name="E21" tile="-143" orientation="3"/> <Hex name="F4" tile="-1"/> <Hex name="F6" tile="-1"/> diff --git a/data/18EU/Map.xml b/data/18EU/Map.xml index 3d4462c..5fa0e55 100644 --- a/data/18EU/Map.xml +++ b/data/18EU/Map.xml @@ -1,7 +1,10 @@ <Map tileOrientation="NS" letterOrientation="vertical" even="A"> <Image file="18EU/MapImage.svg" x="16" y="15" scale="0.955"/> + <Defaults> + <Access type="port" runTo="yes" runThrough="yes" loop="yes" score="minor"/> + </Defaults> <!-- Hex name="" tile="" orientation="" value="" impassable="" label="" cost="" value="" port="yes/no" --> - <Hex name="A4" port="yes" value="10" tile="-800" orientation="0"/> + <Hex name="A4" type="port" value="10" tile="-800" orientation="0"/> <Hex name="B7" value="30,50" tile="-903" pic="-939" orientation="1" city="Hamburg"> <Access runThrough="yes"/> </Hex> @@ -18,7 +21,7 @@ <Hex name="E6" tile="0" /> <Hex name="E8" tile="0" /> <Hex name="E10" label="B" tile="-3005" orientation="1" city="Berlin"> - <Access loop="no"/> + <Access loop="no" trainMutexID="Berlin"/> </Hex> <Hex name="E12" tile="-1" city="Thorn"/> <Hex name="E14" value="20,30" tile="-901" orientation="2" city="Warsaw"/> @@ -49,7 +52,7 @@ <Hex name="I10" cost="60" tile="0" /> <Hex name="I12" cost="60" tile="0" /> <Hex name="J1" label="P" tile="-3006" city="Paris"> - <Access loop="no"/> + <Access loop="no" trainMutexID="Paris"/> </Hex> <Hex name="J3" cost="60" tile="0" /> <Hex name="J5" tile="0" /> @@ -82,7 +85,7 @@ <Hex name="N7" tile="0" /> <Hex name="N9" cost="60" tile="-1" city="Salzburg"/> <Hex name="N11" label="V" tile="-3005" city="Vienna"> - <Access loop="no"/> + <Access loop="no" trainMutexID="Vienna"/> </Hex> <Hex name="N13" tile="0" /> <Hex name="O2" tile="0" /> @@ -123,11 +126,11 @@ <Hex name="T3" cost="60" tile="-1" city="Nice"/> <Hex name="T5" tile="-3008" city="Genoa"/> <Hex name="T7" tile="-1" city="Bologna"/> - <Hex name="T9" port="yes" value="10" tile="-800" orientation="3"/> - <Hex name="U2" port="yes" value="10" tile="-800" orientation="3"/> + <Hex name="T9" type="port" value="10" tile="-800" orientation="3"/> + <Hex name="U2" type="port" value="10" tile="-800" orientation="3"/> <Hex name="U4" tile="0" /> <Hex name="U6" tile="-1" city="Florence" reserved="10"/> <Hex name="U8" tile="0" /> - <Hex name="V5" port="yes" value="10" tile="-800" orientation="3"/> + <Hex name="V5" type="port" value="10" tile="-800" orientation="3"/> <Hex name="V7" label="V" value="30,50" tile="-903" orientation="4" city="Rome"/> </Map> diff --git a/rails/algorithms/NetworkVertex.java b/rails/algorithms/NetworkVertex.java index 91356af..d9b42b3 100644 --- a/rails/algorithms/NetworkVertex.java +++ b/rails/algorithms/NetworkVertex.java @@ -228,14 +228,14 @@ public final class NetworkVertex implements Comparable<NetworkVertex> { // check if it has to be removed because it is run-to only // if company == null, then no vertex gets removed if (company != null && !city.isRunToAllowedFor(company)) { - log.info("Vertex is removed"); - return false; + log.info("Vertex is removed"); + return false; } // check if it is a major or minor - if (city.getScoreType() == Stop.Score.MAJOR) { + if (city.getScoreType() == Access.ScoreType.MAJOR) { setStationType(StationType.MAJOR); - } else if (city.getScoreType() == Stop.Score.MINOR) { + } else if (city.getScoreType() == Access.ScoreType.MINOR) { setStationType(StationType.MINOR); } @@ -256,6 +256,10 @@ public final class NetworkVertex implements Comparable<NetworkVertex> { if (hex.getCityName() != null && !hex.getCityName().equals("") && station.getCityName() != null && !station.getCityName().equals("")) { cityName = hex.getCityName() + "." + station.getCityName(); + /* EV: To use the new trainMutexID, the above two lines should be changed to: + && city.getTrainMutexID() != null && !city.getTrainMutexID().equals("")) { + cityName = hex.getCityName() + "." + city.getTrainMutexID(); + */ } } diff --git a/rails/game/Access.java b/rails/game/Access.java new file mode 100644 index 0000000..894d6ad --- /dev/null +++ b/rails/game/Access.java @@ -0,0 +1,278 @@ +package rails.game; + +import rails.common.parser.ConfigurationException; +import rails.util.Util; + + +public class Access { + + /** An Access object represents a set of parameters that may affect how trains can run through stops + * and what revenue is scored. + * The final repository of an Access objects is the class Stop, where all train-run affecting aspects + * come together.<p> + * Stop objects collect all of its Access parameters from Access objects + * in other classes, as listed below, in precedence sequence:<br> + * 1. Specific MapHex Stop (defined in TileSet.xml with 'stop' value > 0)<br> + * 2. Specific Tile Station (defined in TileSet.xml with 'station' value > 0). For preprinted tiles (id<=0) only.<br> + * 3. MapHex (defined in Map.xml with 'stop' value absent or 0)<br> + * 4. Tile (defined in TileSet.xml with 'station' value absent or 0). For preprinted tiles (id<=0) only.<br> + * 5. MapManager default per stop type (defined as default in Map.xml)<br> + * 6. TileManager default per stop type (defined as default in TileSet.xml)<br> + * 7. MapManager general default (defined in Map.xml)<br> + * 8. TileManager general default (defined in TileSet.xml)<br> + * 9. Generic stop-type default (defined in the StopType enum below)<p> + * The precedence rule is, that a parameter that is not explicitly defined at a certain precedence level + * falls through to the next lower level, or ultimately to the stop-type default, as defined in this class. + * <p>For some properties, not all precedence levels apply. + */ + + /** The stop type (city, town, port, mine etc.). + * Normally the type will be derived from the tile properties. + * <p>The stop type can be configured on precedence levels 1-4. + * If still undefined after level 4, it is derived from the tile Station type. + */ + private StopType stopType = null; + + /** Run-to status of any stops on the hex (whether visible or not). CURRENTLY UNUSED. + * Indicates whether or not a single train can run from or to such stops, i.e. either enter or leave it. + * Has no meaning if no stops exist on this hex. + * <p>Values (see RunTo below for definitions): + * <br>- "yes" (default) means that trains of all companies may run to/from this station. + * <br>- "tokenOnly" means that trains may only access the station if it contains a base token + * of the operating company. Applies to the 18Scan off-map hexes. + * <br>- "no" would mean that the hex is inaccessible (like 1851 Birmingham in the early game), + * but this option is not yet useful as there is no provision yet to change this setting + * in an undoable way (no state variable). + * <p>The run-to status can be configured on all precedence levels. + */ + private RunTo runToAllowed = null; + + /** Run-through status of any stops on the hex (whether visible or not). CURRENTLY UNUSED. + * Indicates whether or not a single train can run through such stops, i.e. both enter and leave it. + * Has no meaning if no stops exist on this hex. + * <p>Values (see RunThrough below for definitions): + * <br>- "yes" (default for all except off-map hexes) means that trains of all companies + * may run through this station, unless it is completely filled with foreign base tokens. + * <br>- "tokenOnly" means that trains may only run through the station if it contains a base token + * of the operating company (applies to the 1830 PRR base). + * <br>- "no" (default for off-map hexes) means that no train may run through this hex. + * <p>The run-through status can be configured on all precedence levels. + */ + private RunThrough runThroughAllowed = null; + + /** May trains return to this tile? UNUSED, and probably obsolete. See trainMutexID */ + private Loop loopAllowed = null; + + /** + * Score type indicates whether stops on this hex count as 'major' or 'minor' stops. + * Many games don't make such a difference, but for instance 1835 and 18EU do. + * <p>The stop type can be configured on precedence levels 1-6. + */ + private ScoreType scoreType = null; + + /** An identifier of a train mutex group. Can be any non-empty string. CURRENTLY UNUSED.<p> + * One train may not access more than one stop with the same trainMutexID + * (at least, that is the intention of this item. It is not yet used). + * <p> The trainMutexID can be set on precedence levels 1-6. The default is null. + * */ + private String trainMutexID = null; + + public Access () {} + + public Access (Access copy) { + this.stopType = copy.stopType; + this.runToAllowed = copy.runToAllowed; + this.runThroughAllowed = copy.runThroughAllowed; + this.loopAllowed = copy.loopAllowed; + this.scoreType = copy.scoreType; + this.trainMutexID = copy.trainMutexID; + } + + public Access merge (Access lower) { + + if (lower != null) { + if (stopType == null) stopType = lower.stopType; + if (runToAllowed == null) runToAllowed = lower.runToAllowed; + if (runThroughAllowed == null) runThroughAllowed = lower.runThroughAllowed; + if (loopAllowed == null) loopAllowed = lower.loopAllowed; + if (scoreType == null) scoreType = lower.scoreType; + if (!Util.hasValue(trainMutexID)) trainMutexID = lower.trainMutexID; + } + + return this; + } + + public static StopType parseStopTypeString (String s, String sourceDescription) + throws ConfigurationException { + if (Util.hasValue(s)) { + try { + return StopType.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new ConfigurationException ("Illegal value for " + sourceDescription + +" type property: '"+s+"'", e); + } + } + return null; + } + + public static RunThrough parseRunThroughString (String s, String sourceDescription) + throws ConfigurationException { + if (Util.hasValue(s)) { + try { + return RunThrough.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new ConfigurationException ("Illegal value for " + sourceDescription + +" runThrough property: '"+s+"'", e); + } + } + return null; + } + + public static RunTo parseRunToString (String s, String sourceDescription) + throws ConfigurationException { + if (Util.hasValue(s)) { + try { + return RunTo.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new ConfigurationException ("Illegal value for " + sourceDescription + +" runTo property: '"+s+"'", e); + } + } + return null; + } + + public static Loop parseLoopString (String s, String sourceDescription) + throws ConfigurationException { + if (Util.hasValue(s)) { + try { + return Loop.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new ConfigurationException ("Illegal value for " + sourceDescription + +" loop property: "+s, e); + } + } + return null; + } + + public static ScoreType parseScoreTypeString (String s, String sourceDescription) + throws ConfigurationException { + if (Util.hasValue(s)) { + try { + return ScoreType.valueOf(s.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new ConfigurationException ("Illegal value for " + sourceDescription + +" score property: "+s, e); + } + } + return null; + } + + public StopType getStopType() { + return stopType; + } + + public void setStopType(StopType stopType) { + this.stopType = stopType; + } + + public RunTo getRunToAllowed() { + return runToAllowed; + } + + public void setRunToAllowed(RunTo runToAllowed) { + this.runToAllowed = runToAllowed; + } + + public RunThrough getRunThroughAllowed() { + return runThroughAllowed; + } + + public void setRunThroughAllowed(RunThrough runThroughAllowed) { + this.runThroughAllowed = runThroughAllowed; + } + + public Loop getLoopAllowed() { + return loopAllowed; + } + + public void setLoopAllowed(Loop loopAllowed) { + this.loopAllowed = loopAllowed; + } + + public ScoreType getScoreType() { + return scoreType; + } + + public void setScoreType(ScoreType scoreType) { + this.scoreType = scoreType; + } + + public String getTrainMutexID() { + return trainMutexID; + } + + public void setTrainMutexID(String trainMutexID) { + this.trainMutexID = trainMutexID; + } + + // --- Enumerations --- + public enum RunTo { + YES, + NO, + TOKENONLY + } + + public enum RunThrough { + YES, + NO, + TOKENONLY + } + + public enum Loop { + YES, + NO + } + + public enum StopType { + + CITY (RunTo.YES, RunThrough.YES, Loop.YES, ScoreType.MAJOR), + TOWN (RunTo.YES, RunThrough.YES, Loop.YES, ScoreType.MINOR), + HALT (RunTo.YES, RunThrough.YES, Loop.YES, ScoreType.MINOR), + OFFMAP (RunTo.YES, RunThrough.NO, Loop.NO, ScoreType.MAJOR), + PORT (RunTo.YES, RunThrough.NO, Loop.NO, ScoreType.MINOR), + MINE (RunTo.YES, RunThrough.NO, Loop.NO, ScoreType.MINOR), + PASS (RunTo.YES, RunThrough.YES, Loop.NO, ScoreType.MAJOR); + + private RunTo defaultRunToAllowed; + private RunThrough defaultRunThroughAllowed; + private Loop defaultLoopAllowed; + private ScoreType defaultScoreType; + private Access defaultAccessInfo; + + StopType (RunTo runTo, + RunThrough runThrough, + Loop loop, + ScoreType scoreType) { + + defaultAccessInfo = new Access(); + + defaultAccessInfo.setRunToAllowed(runTo); + defaultAccessInfo.setRunThroughAllowed(runThrough); + defaultAccessInfo.setLoopAllowed(loop); + defaultAccessInfo.setScoreType(scoreType); + } + + public RunTo getDefaultRunTo() { return defaultRunToAllowed; } + public RunThrough getDefaultRunThrough() { return defaultRunThroughAllowed; } + public Loop getDefaultLoop() { return defaultLoopAllowed; } + public ScoreType getDefaultScoreType() { return defaultScoreType; } + + public Access getAccessInfoDefaults() { return defaultAccessInfo; } + + } + + public enum ScoreType { + MAJOR, + MINOR + } +} diff --git a/rails/game/MapHex.java b/rails/game/MapHex.java index f02a37a..1ca6846 100644 --- a/rails/game/MapHex.java +++ b/rails/game/MapHex.java @@ -10,11 +10,6 @@ import org.apache.log4j.Logger; import rails.algorithms.RevenueBonusTemplate; import rails.common.LocalText; import rails.common.parser.*; -import rails.game.Stop.Loop; -import rails.game.Stop.RunThrough; -import rails.game.Stop.RunTo; -import rails.game.Stop.Score; -import rails.game.Stop.Type; import rails.game.action.LayTile; import rails.game.model.ModelObject; import rails.game.move.Moveable; @@ -121,43 +116,21 @@ StationHolder, TokenHolder { /** Any open sides against which track may be laid even at board edges (1825) */ protected boolean[] openHexSides; - /** Run-through status of any stops on the hex (whether visible or not). - * Indicates whether or not a single train can run through such stops, i.e. both enter and leave it. - * Has no meaning if no stops exist on this hex. - * <p>Values (see RunThrough below for definitions): - * <br>- "yes" (default for all except off-map hexes) means that trains of all companies - * may run through this station, unless it is completely filled with foreign base tokens. - * <br>- "tokenOnly" means that trains may only run through the station if it contains a base token - * of the operating company (applies to the 1830 PRR base). - * <br>- "no" (default for off-map hexes) means that no train may run through this hex. + /** Access info array with elements: + * [0] for per-hex access parameters. Must exist.<br> + * [1]... for each stop (station; if any). Will remain null if no stop-specific access values exist. + * + * <p>Stop-specific access parameters apply to one specific hex stop only. + * Tile station numbers are defined in Tiles.xml as "city1", ... where "1" is the number. + * (station numbers always start with 1). Hex stop numbers are initially copied from the + * tile station numbers of the preprinted tile on that hex. When upgraded, Rails attempts to transfer + * hex stop numbers unchanged from one tile to the next, based upon existing track connections. + * However, such attempts will often fail when the number of stations changes during an upgrade. + * It is therefore recommended to define access properties per hex stop only for fixed (not upgradeable) + * preprinted tiles + * <p>NOTE: per-station access parameters can also be defined in TileSet.xml. */ - protected RunThrough runThroughAllowed = null; - - /** Run-to status of any stops on the hex (whether visible or not). - * Indicates whether or not a single train can run from or to such stops, i.e. either enter or leave it. - * Has no meaning if no stops exist on this hex. - * <p>Values (see RunTo below for definitions): - * <br>- "yes" (default) means that trains of all companies may run to/from this station. - * <br>- "tokenOnly" means that trains may only access the station if it contains a base token - * of the operating company. Applies to the 18Scan off-map hexes. - * <br>- "no" would mean that the hex is inaccessible (like 1851 Birmingham in the early game), - * but this option is not yet useful as there is no provision yet to change this setting - * in an undoable way (no state variable). - */ - protected RunTo runToAllowed = null; - - /** Loop: may one train touch this hex twice or more? */ - protected Loop loopAllowed = null; - - /** Type of any stops on the hex. - * Normally the type will be derived from the tile properties. - */ - protected Type stopType = null; - - /** - * Score type: do stops on this hex count as major or minor stops with respect to n+m trains? - */ - protected Score scoreType = null; + protected Access[] accessInfo; protected MapManager mapManager = null; @@ -271,59 +244,46 @@ StationHolder, TokenHolder { } // Stop properties - Tag accessTag = tag.getChild("Access"); - if (accessTag != null) { - String runThroughString = accessTag.getAttributeAsString("runThrough"); - if (Util.hasValue(runThroughString)) { - try { - runThroughAllowed = RunThrough.valueOf(runThroughString.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for MapHex" - +name+" runThrough property: "+runThroughString, e); - } - } + accessInfo = new Access[1]; + accessInfo[0] = new Access(); - String runToString = accessTag.getAttributeAsString("runTo"); - if (Util.hasValue(runToString)) { - try { - runToAllowed = RunTo.valueOf(runToString.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for MapHex " - +name+" runTo property: "+runToString, e); - } - } + /* As a shortcut, the stopType (for all stations) can also be set in the Hex tag itself. + * Any different setting in <Access> will override this shortcut setting. + */ + accessInfo[0].setStopType(Access.parseStopTypeString(tag.getAttributeAsString("type"), + "Hex " + name)); - String loopString = accessTag.getAttributeAsString("loop"); - if (Util.hasValue(loopString)) { - try { - loopAllowed = Loop.valueOf(loopString.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for MapHex " - +name+" loop property: "+loopString, e); - } - } + List<Tag> accessTags = tag.getChildren("Access"); + if (accessTags != null) { + for (Tag accessTag : accessTags) { - String typeString = accessTag.getAttributeAsString("type"); - if (Util.hasValue(typeString)) { - try { - stopType = Type.valueOf(typeString.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for MapHex " - +name+" stop type property: "+typeString, e); - } - } + int stationNumber = accessTag.getAttributeAsInteger("station", 0); - String scoreTypeString = accessTag.getAttributeAsString("score"); - if (Util.hasValue(scoreTypeString)) { - try { - scoreType = Score.valueOf(scoreTypeString.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for MapHex " - +name+" score type property: "+scoreTypeString, e); + if (stationNumber > 0) { + if (stationNumber+1 > accessInfo.length) { + accessInfo = Arrays.copyOf(accessInfo, stationNumber+1); + } + if (accessInfo[stationNumber] == null) accessInfo[stationNumber] = new Access(); + } else if (stationNumber == 0) { + // That's OK, accessInfo already exists + } else { + // Please note, that we cannot check the maximum station number yet. + throw new ConfigurationException ("Invalid <Access> stop (staion) number in hex #"+name); } + Access ai = accessInfo[stationNumber]; + ai.setStopType(Access.parseStopTypeString(accessTag.getAttributeAsString("type"), + "Hex " + name)); + ai.setRunThroughAllowed(Access.parseRunThroughString(accessTag.getAttributeAsString("runThrough"), + "Hex " + name)); + ai.setRunToAllowed(Access.parseRunToString(accessTag.getAttributeAsString("runTo"), + "Hex " + name)); + ai.setLoopAllowed(Access.parseLoopString(accessTag.getAttributeAsString("loop"), + "Hex " + name)); + ai.setScoreType(Access.parseScoreTypeString(accessTag.getAttributeAsString("score"), + "Hex " + name)); + ai.setTrainMutexID(accessTag.getAttributeAsString("trainMutexID")); } } - } public void finishConfiguration (GameManagerI gameManager) { @@ -343,15 +303,18 @@ StationHolder, TokenHolder { mStops.put(c.getNumber(), c); } - /* Superseded by new code in Stop - or do we still need it? - if (runThroughAllowed == null) { - runThroughAllowed = currentTile.getColourName().equalsIgnoreCase("red") - ? RunThrough.NO : RunThrough.YES; - } - if (runToAllowed == null) { - runToAllowed = RunTo.YES; - } + /* Make sure that the accessInfo array is minimally as long as 1 + the number of stops on the initial + * (preprinted) tile. WARNING: the length does not (yet) change during updates + * (I'm not aware of any such cases, though [EV]). + * This will almost surely cause problems if the number of stops on a hex would increase. + * It is recommended not to use stop-specific access settings in Map.xml in combination with upgradeable hexes. + * Use TileSet.xml instead. */ + int maxStationNumber = getCurrentTile().getNumStations(); + if (maxStationNumber >= accessInfo.length) { + accessInfo = Arrays.copyOf(accessInfo, maxStationNumber+1); + } + } public void addImpassableSide (int orientation) { @@ -541,7 +504,7 @@ StationHolder, TokenHolder { /** * new wrapper function for the LayTile action that calls the actual - * upgrade mehod + * upgrade method * @param action executed LayTile action */ public void upgrade(LayTile action) { @@ -558,9 +521,9 @@ StationHolder, TokenHolder { */ public void upgrade(TileI newTile, int newRotation, Map<String, Integer> relaidTokens) { - Stop newCity; + Stop newStop; String newTracks; - List<Stop> newCities; + List<Stop> newStops; if (relaidTokens == null) relaidTokens = new HashMap<String, Integer>(); @@ -574,18 +537,18 @@ StationHolder, TokenHolder { // Check for manual handling of tokens for (String compName : relaidTokens.keySet()) { - for (Stop city : stops) { - if (city.hasTokenOf(compName)) { - citiesToStations.put(city, newTile.getStations().get(relaidTokens.get(compName)-1)); + for (Stop stop : stops) { + if (stop.hasTokenOf(compName)) { + citiesToStations.put(stop, newTile.getStations().get(relaidTokens.get(compName)-1)); } } } // Scan the old cities/stations, // and assign new stations where tracks correspond - for (Stop city : stops) { - if (citiesToStations.containsKey(city)) continue; - Station oldStation = city.getRelatedStation(); + for (Stop stop : stops) { + if (citiesToStations.containsKey(stop)) continue; + Station oldStation = stop.getRelatedStation(); int[] oldTrackEnds = getTrackEndPoints(currentTile, currentTileRotation, oldStation); @@ -597,7 +560,7 @@ StationHolder, TokenHolder { for (int j = 0; j < newTrackEnds.length; j++) { if (oldTrackEnds[i] == newTrackEnds[j]) { // Match found! - citiesToStations.put(city, newStation); + citiesToStations.put(stop, newStation); continue station; } } @@ -606,29 +569,29 @@ StationHolder, TokenHolder { } // Map any unassigned cities randomly - city: for (Stop city : stops) { - if (citiesToStations.containsKey(city)) continue; + city: for (Stop stop : stops) { + if (citiesToStations.containsKey(stop)) continue; for (Station newStation : newTile.getStations()) { if (citiesToStations.values().contains(newStation)) continue; - citiesToStations.put(city, newStation); + citiesToStations.put(stop, newStation); continue city; } } // Assign the new Stations to the existing cities - for (Stop city : citiesToStations.keySet()) { - Station newStation = citiesToStations.get(city); - Station oldStation = city.getRelatedStation(); - city.setRelatedStation(newStation); - city.setSlots(newStation.getBaseSlots()); + for (Stop stop : citiesToStations.keySet()) { + Station newStation = citiesToStations.get(stop); + Station oldStation = stop.getRelatedStation(); + stop.setRelatedStation(newStation); + stop.setSlots(newStation.getBaseSlots()); newTracks = getConnectionString(newTile, newRotation, newStation.getNumber()); - city.setTrackEdges(newTracks); + stop.setTrackEdges(newTracks); log.debug("Assigned " - + city.getUniqueId() + + stop.getUniqueId() + " from " + oldStation.getId() + " " @@ -638,7 +601,7 @@ StationHolder, TokenHolder { + " to " + newStation.getId() + " " + newTracks); } - newCities = stops; + newStops = stops; } else { // If the number of stations does change, @@ -646,25 +609,25 @@ StationHolder, TokenHolder { // Build a map from old to new cities, // so that we can move tokens at the end. - newCities = new ArrayList<Stop>(4); - Map<Integer, Stop> mNewCities = new HashMap<Integer, Stop>(4); - Map<Stop, Stop> oldToNewCities = new HashMap<Stop, Stop>(); - Map<Station, Stop> newStationsToCities = + newStops = new ArrayList<Stop>(4); + Map<Integer, Stop> mNewStops = new HashMap<Integer, Stop>(4); + Map<Stop, Stop> oldToNewStops = new HashMap<Stop, Stop>(); + Map<Station, Stop> newStationsToStops = new HashMap<Station, Stop>(); // Scan the old cities/stations, // and assign new stations where tracks correspond - int newCityNumber = 0; - for (Stop oldCity : stops) { - int cityNumber = oldCity.getNumber(); - Station oldStation = oldCity.getRelatedStation(); + int newStopNumber = 0; + for (Stop oldStop : stops) { + int cityNumber = oldStop.getNumber(); + Station oldStation = oldStop.getRelatedStation(); int[] oldTrackEnds = getTrackEndPoints(currentTile, currentTileRotation, oldStation); - log.debug("Old city #" + log.debug("Old stop #" + currentTile.getId() + " city " - + oldCity.getNumber() + + oldStop.getNumber() + ": " + getConnectionString(currentTile, currentTileRotation, oldStation.getNumber())); @@ -682,26 +645,26 @@ StationHolder, TokenHolder { for (int j = 0; j < newTrackEnds.length; j++) { if (oldTrackEnds[i] == newTrackEnds[j]) { // Match found! - if (!newStationsToCities.containsKey(newStation)) { - newCity = - new Stop(this, ++newCityNumber, + if (!newStationsToStops.containsKey(newStation)) { + newStop = + new Stop(this, ++newStopNumber, newStation); - newCities.add(newCity); - mNewCities.put(cityNumber, newCity); - newStationsToCities.put(newStation, newCity); - newCity.setSlots(newStation.getBaseSlots()); + newStops.add(newStop); + mNewStops.put(cityNumber, newStop); + newStationsToStops.put(newStation, newStop); + newStop.setSlots(newStation.getBaseSlots()); } else { - newCity = - newStationsToCities.get(newStation); + newStop = + newStationsToStops.get(newStation); } - oldToNewCities.put(oldCity, newCity); + oldToNewStops.put(oldStop, newStop); newTracks = getConnectionString(newTile, newRotation, newStation.getNumber()); - newCity.setTrackEdges(newTracks); + newStop.setTrackEdges(newTracks); log.debug("Assigned from " - + oldCity.getUniqueId() + + oldStop.getUniqueId() + " #" + currentTile.getId() + "/" @@ -712,7 +675,7 @@ StationHolder, TokenHolder { + getConnectionString(currentTile, currentTileRotation, oldStation.getNumber()) - + " to " + newCity.getUniqueId() + + " to " + newStop.getUniqueId() + " #" + newTile.getId() + "/" + newRotation + " " + newStation.getId() + " " @@ -728,9 +691,9 @@ StationHolder, TokenHolder { // If an old city is not yet connected, check if was // connected to another city it has merged into (1851 Louisville) - for (Stop oldCity : stops) { - if (oldToNewCities.containsKey(oldCity)) continue; - Station oldStation = oldCity.getRelatedStation(); + for (Stop oldStop : stops) { + if (oldToNewStops.containsKey(oldStop)) continue; + Station oldStation = oldStop.getRelatedStation(); int[] oldTrackEnds = getTrackEndPoints(currentTile, currentTileRotation, oldStation); @@ -739,16 +702,16 @@ StationHolder, TokenHolder { if (oldTrackEnds[i] < 0) { int oldStationNumber = -oldTrackEnds[i]; // Find the old city that has this number - for (Stop oldCity2 : stops) { - log.debug("Old city "+oldCity2.getNumber()+" has station "+oldCity2.getRelatedStation().getNumber()); - log.debug(" and links to new city "+oldToNewCities.get(oldCity2)); - if (oldCity2.getRelatedStation().getNumber() + for (Stop oldStop2 : stops) { + log.debug("Old city "+oldStop2.getNumber()+" has station "+oldStop2.getRelatedStation().getNumber()); + log.debug(" and links to new city "+oldToNewStops.get(oldStop2)); + if (oldStop2.getRelatedStation().getNumber() == oldStationNumber - && oldToNewCities.containsKey(oldCity2)) { - newCity = oldToNewCities.get(oldCity2); - oldToNewCities.put(oldCity, newCity); + && oldToNewStops.containsKey(oldStop2)) { + newStop = oldToNewStops.get(oldStop2); + oldToNewStops.put(oldStop, newStop); log.debug("Assigned from " - + oldCity.getUniqueId() + + oldStop.getUniqueId() + " #" + currentTile.getId() + "/" @@ -759,11 +722,11 @@ StationHolder, TokenHolder { + getConnectionString(currentTile, currentTileRotation, oldStation.getNumber()) - + " to " + newCity.getUniqueId() + + " to " + newStop.getUniqueId() + " #" + newTile.getId() + "/" + newRotation + " " - + newCity.getRelatedStation().getId() + " " - + newCity.getTrackEdges()); + + newStop.getRelatedStation().getId() + " " + + newStop.getTrackEdges()); break station; @@ -777,22 +740,22 @@ StationHolder, TokenHolder { // Check if there any new stations not corresponding // to an old city. for (Station newStation : newTile.getStations()) { - if (newStationsToCities.containsKey(newStation)) continue; + if (newStationsToStops.containsKey(newStation)) continue; // Create a new city for such a station. - int cityNumber; - for (cityNumber = 1; mNewCities.containsKey(cityNumber); cityNumber++) + int stopNumber; + for (stopNumber = 1; mNewStops.containsKey(stopNumber); stopNumber++) ; - newCity = new Stop(this, ++newCityNumber, newStation); - newCities.add(newCity); - mNewCities.put(cityNumber, newCity); - newStationsToCities.put(newStation, newCity); - newCity.setSlots(newStation.getBaseSlots()); + newStop = new Stop(this, ++newStopNumber, newStation); + newStops.add(newStop); + mNewStops.put(stopNumber, newStop); + newStationsToStops.put(newStation, newStop); + newStop.setSlots(newStation.getBaseSlots()); newTracks = getConnectionString(newTile, newRotation, newStation.getNumber()); - newCity.setTrackEdges(newTracks); - log.debug("New city added " + newCity.getUniqueId() + " #" + newStop.setTrackEdges(newTracks); + log.debug("New city added " + newStop.getUniqueId() + " #" + newTile.getId() + "/" + newRotation + " " + newStation.getId() + " " + newTracks); } @@ -801,15 +764,15 @@ StationHolder, TokenHolder { Map<TokenI, TokenHolder> tokenDestinations = new HashMap<TokenI, TokenHolder>(); - for (Stop oldCity : stops) { - newCity = oldToNewCities.get(oldCity); - if (newCity != null) { - oldtoken: for (TokenI token : oldCity.getTokens()) { + for (Stop oldStop : stops) { + newStop = oldToNewStops.get(oldStop); + if (newStop != null) { + oldtoken: for (TokenI token : oldStop.getTokens()) { if (token instanceof BaseToken) { // Check if the new city already has such a token PublicCompanyI company = ((BaseToken) token).getCompany(); - for (TokenI token2 : newCity.getTokens()) { + for (TokenI token2 : newStop.getTokens()) { if (token2 instanceof BaseToken && company == ((BaseToken) token2).getCompany()) { // No duplicate tokens in one city! @@ -817,7 +780,7 @@ StationHolder, TokenHolder { log.debug("Duplicate token " + token.getUniqueId() + " moved from " - + oldCity.getName() + " to " + + oldStop.getName() + " to " + company.getName()); ReportBuffer.add(LocalText.getText( "DuplicateTokenRemoved", @@ -827,10 +790,10 @@ StationHolder, TokenHolder { } } } - tokenDestinations.put(token, newCity); + tokenDestinations.put(token, newStop); log.debug("Token " + token.getUniqueId() - + " moved from " + oldCity.getName() + " to " - + newCity.getName()); + + " moved from " + oldStop.getName() + " to " + + newStop.getName()); } if (!tokenDestinations.isEmpty()) { for (TokenI token : tokenDestinations.keySet()) { @@ -847,7 +810,7 @@ StationHolder, TokenHolder { // Replace the tile new TileMove(this, currentTile, currentTileRotation, stops, - newTile, newRotation, newCities); + newTile, newRotation, newStops); /* TODO Further consequences to be processed here, e.g. new routes etc. */ } @@ -1376,23 +1339,11 @@ StationHolder, TokenHolder { return endpoints; } - public RunThrough isRunThroughAllowed() { - return runThroughAllowed; - } - - public RunTo isRunToAllowed() { - return runToAllowed; + public Access getAccessInfo(int stationNumber) { + if (stationNumber < 0 || stationNumber >= accessInfo.length) return null; + if (accessInfo[stationNumber] == null) return new Access(); + return accessInfo[stationNumber]; } - public Loop isLoopAllowed () { - return loopAllowed; - } - public Type getStopType() { - return stopType; - } - - public Score getScoreType() { - return scoreType; - } } \ No newline at end of file diff --git a/rails/game/MapManager.java b/rails/game/MapManager.java index 6cd4307..8d07665 100644 --- a/rails/game/MapManager.java +++ b/rails/game/MapManager.java @@ -7,12 +7,7 @@ import org.apache.log4j.Logger; import rails.common.Config; import rails.common.parser.*; -import rails.game.Stop.Loop; -import rails.game.Stop.RunThrough; -import rails.game.Stop.RunTo; -import rails.game.Stop.Score; -import rails.game.Stop.Type; -import rails.util.Util; +import rails.game.Access.StopType; /** * MapManager configures the map layout from XML @@ -56,10 +51,11 @@ public class MapManager implements ConfigurableComponentI { protected static final int[] yDeltaEW = new int[] { +1, 0, -1, -1, 0, +1 }; // Stop property defaults per stop type - protected Map<Type,RunTo> runToDefaults = new HashMap<Type, RunTo>(); - protected Map<Type,RunThrough> runThroughDefaults = new HashMap<Type, RunThrough>(); - protected Map<Type,Loop> loopDefaults = new HashMap<Type, Loop>(); - protected Map<Type,Score> scoreTypeDefaults = new HashMap<Type, Score>(); + //protected Map<Type,RunTo> runToDefaults = new HashMap<Type, RunTo>(); + //protected Map<Type,RunThrough> runThroughDefaults = new HashMap<Type, RunThrough>(); + //protected Map<Type,Loop> loopDefaults = new HashMap<Type, Loop>(); + //protected Map<Type,ScoreType> scoreTypeDefaults = new HashMap<Type, ScoreType>(); + protected Map<StopType, Access> accessDefaults = new HashMap<StopType, Access>(); protected static Logger log = Logger.getLogger(MapManager.class.getPackage().getName()); @@ -164,71 +160,42 @@ public class MapManager implements ConfigurableComponentI { } // Parse default stop types - Type type; - RunTo runTo; - RunThrough runThrough; - Loop loop; - Score score; - String s; + StopType stopType; + Access accessDetail; Tag defaultsTag = tag.getChild("Defaults"); if (defaultsTag != null) { List<Tag> accessTags = defaultsTag.getChildren("Access"); for (Tag accessTag : accessTags) { - // Type - s = accessTag.getAttributeAsString("type", null); - if (Util.hasValue(s)) { - try { - type = Type.valueOf(s.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for default property type: "+s, e); - } + + // Type. Create an Access object, even if stopType is null. + stopType = Access.parseStopTypeString(accessTag.getAttributeAsString("type"), + "MapManager default"); + if (!accessDefaults.containsKey(stopType)) { + accessDefaults.put(stopType, accessDetail = new Access()); } else { - type = null; // For default defaults - } - // RunTo - s = accessTag.getAttributeAsString("runTo", null); - if (Util.hasValue(s)) { - try { - runTo = RunTo.valueOf(s.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for " - +type+" default runTo property: "+s, e); - } - runToDefaults.put(type, runTo); + accessDetail = accessDefaults.get(stopType); } + // RunThrough - s = accessTag.getAttributeAsString("runThrough", null); - if (Util.hasValue(s)) { - try { - runThrough = RunThrough.valueOf(s.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for " - +type+" default runThrough property: "+s, e); - } - runThroughDefaults.put(type, runThrough); - } + accessDetail.setRunThroughAllowed(Access.parseRunThroughString(accessTag.getAttributeAsString("runThrough"), + "MapManager default, type=" + stopType)); + + // RunTo + accessDetail.setRunToAllowed(Access.parseRunToString(accessTag.getAttributeAsString("runTo"), + "MapManager default, type=" + stopType)); + // Loop - s = accessTag.getAttributeAsString("loop", null); - if (Util.hasValue(s)) { - try { - loop = Loop.valueOf(s.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for " - +type+" default loop property: "+s, e); - } - loopDefaults.put(type, loop); - } + accessDetail.setLoopAllowed(Access.parseLoopString(accessTag.getAttributeAsString("loop"), + "MapManager default, type=" + stopType)); + // Score type (not allowed for a null stop type) - s = accessTag.getAttributeAsString("scoreType", null); - if (type != null && Util.hasValue(s)) { - try { - score = Score.valueOf(s.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigurationException ("Illegal value for " - +type+" default score type property: "+s, e); - } - scoreTypeDefaults.put(type, score); + if (stopType != null) { + accessDetail.setScoreType(Access.parseScoreTypeString(accessTag.getAttributeAsString("score"), + "MapManager default, type=" + stopType)); } + + // Train Mutex ID (to allow exclusions) + accessDetail.setTrainMutexID(accessTag.getAttributeAsString("trainMutexID")); } } } @@ -553,20 +520,29 @@ public class MapManager implements ConfigurableComponentI { return mapImageUsed; } - public RunTo getRunToDefault(Type type) { - return runToDefaults.containsKey(type) ? runToDefaults.get(type) : null; + public Access getAccessInfoDefaults(StopType stopType) { + return accessDefaults.get(stopType); + } + + /* + public RunTo getRunToDefault(StopType stopType) { + return accessDefaults.containsKey(stopType) ? accessDefaults.get(stopType).getRunToAllowed() : null; } - public RunThrough getRunThroughDefault(Type type) { - return runThroughDefaults.containsKey(type) ? runThroughDefaults.get(type) : null; + public RunThrough getRunThroughDefault(StopType stopType) { + return accessDefaults.containsKey(stopType) ? accessDefaults.get(stopType).getRunThroughAllowed() : null; } - public Loop getLoopDefault(Type type) { - return loopDefaults.containsKey(type) ? loopDefaults.get(type) : null; + public Loop getLoopDefault(StopType stopType) { + return accessDefaults.containsKey(stopType) ? accessDefaults.get(stopType).getLoopAllowed() : null; } - public Score getScoreTypeDefault(Type type) { - return scoreTypeDefaults.containsKey(type) ? scoreTypeDefaults.get(type) : null; + public ScoreType getScoreTypeDefault(StopType stopType) { + return accessDefaults.containsKey(stopType) ? accessDefaults.get(stopType).getScoreType() : null; } + public String getTrainMutexIdDefault (StopType stopType) { + return accessDefaults.containsKey(stopType) ? accessDefaults.get(stopType).getTrainMutexID() : null; + } + */ } diff --git a/rails/game/Round.java b/rails/game/Round.java index 6e113ae..b162080 100644 --- a/rails/game/Round.java +++ b/rails/game/Round.java @@ -373,7 +373,7 @@ public abstract class Round implements RoundI { } else if (capitalisationMode == PublicCompanyI.CAPITALISE_WHEN_BOUGHT) { // Cash goes directly to treasury at each buy (as in 1856 before phase 6) capFactor = 0; - } + } int price = company.getIPOPrice(); cash = capFactor * price; } else { diff --git a/rails/game/Stop.java b/rails/game/Stop.java index 401f18f..8231673 100644 --- a/rails/game/Stop.java +++ b/rails/game/Stop.java @@ -6,6 +6,11 @@ import java.util.List; import org.apache.log4j.Logger; +import rails.game.Access.Loop; +import rails.game.Access.RunThrough; +import rails.game.Access.RunTo; +import rails.game.Access.ScoreType; +import rails.game.Access.StopType; import rails.game.move.Moveable; import rails.game.state.GenericState; import rails.util.Util; @@ -37,65 +42,13 @@ public class Stop implements TokenHolder { private String trackEdges; - private Type type = null; - private RunTo runToAllowed = null; - private RunThrough runThroughAllowed = null; - private Loop loopAllowed = null; - private Score scoreType = null; - protected static Logger log = - Logger.getLogger(Stop.class.getPackage().getName()); - - public enum RunTo { - YES, - NO, - TOKENONLY - } - - public enum RunThrough { - YES, - NO, - TOKENONLY - } - - public enum Loop { - YES, - NO - } - - public enum Type { + private StopType stopType = null; - CITY (RunTo.YES, RunThrough.YES, Loop.YES, Score.MAJOR), - TOWN (RunTo.YES, RunThrough.YES, Loop.YES, Score.MINOR), - OFFMAP (RunTo.YES, RunThrough.NO, Loop.NO, Score.MAJOR); + private Access accessInfo = new Access(); - private RunTo defaultRunToAllowed; - private RunThrough defaultRunThroughAllowed; - private Loop defaultLoopAllowed; - private Score defaultScoreType; - - Type (RunTo runTo, - RunThrough runThrough, - Loop loop, - Score scoreType) { - - this.defaultRunToAllowed = runTo; - this.defaultRunThroughAllowed = runThrough; - this.defaultLoopAllowed = loop; - this.defaultScoreType = scoreType; - } - - public RunTo getDefaultRunTo() { return defaultRunToAllowed; } - public RunThrough getDefaultRunThrough() { return defaultRunThroughAllowed; } - public Loop getDefaultLoop() { return defaultLoopAllowed; } - public Score getDefaultScoreType() { return defaultScoreType; } - - } - - public enum Score { - MAJOR, - MINOR - } + protected static Logger log = + Logger.getLogger(Stop.class.getPackage().getName()); public Stop(MapHex mapHex, int number, Station station) { this.mapHex = mapHex; @@ -112,73 +65,156 @@ public class Stop implements TokenHolder { private void initStopProperties () { + boolean logdetail = false; + String loghex = "J1"; + Station station = relatedStation.get(); + int stationNumber = station.getNumber(); TileI tile = station.getTile(); MapManager mapManager = mapHex.getMapManager(); TileManager tileManager = tile.getTileManager(); - // Stop type - type = mapHex.getStopType(); - if (type == null) type = tile.getStopType(); - if (type == null) { + /* Merge the configured stop property layers, + * using the upper four precedence levels (see class Access). + */ + if (logdetail && mapHex.getName().equalsIgnoreCase(loghex)) { + log.debug("+0+ Hex="+mapHex.getName()+" tile="+tile.getId()+" city="+number + +": stopType="+accessInfo.getStopType() + +" runTo="+accessInfo.getRunToAllowed() + +" runThrough="+accessInfo.getRunThroughAllowed() + +" loop="+accessInfo.getLoopAllowed() + +" scoreType="+accessInfo.getScoreType() + +" mutex="+accessInfo.getTrainMutexID()); + } + accessInfo.merge(mapHex.getAccessInfo(stationNumber)); + if (logdetail && mapHex.getName().equalsIgnoreCase(loghex)) { + log.debug("+1+ Hex="+mapHex.getName()+" tile="+tile.getId()+" city="+number + +": stopType="+accessInfo.getStopType() + +" runTo="+accessInfo.getRunToAllowed() + +" runThrough="+accessInfo.getRunThroughAllowed() + +" loop="+accessInfo.getLoopAllowed() + +" scoreType="+accessInfo.getScoreType() + +" mutex="+accessInfo.getTrainMutexID()); + } + accessInfo.merge(tile.getAccessInfo(stationNumber)); + if (logdetail && mapHex.getName().equalsIgnoreCase(loghex)) { + log.debug("+2+ Hex="+mapHex.getName()+" tile="+tile.getId()+" city="+number + +": stopType="+accessInfo.getStopType() + +" runTo="+accessInfo.getRunToAllowed() + +" runThrough="+accessInfo.getRunThroughAllowed() + +" loop="+accessInfo.getLoopAllowed() + +" scoreType="+accessInfo.getScoreType() + +" mutex="+accessInfo.getTrainMutexID()); + } + accessInfo.merge(mapHex.getAccessInfo(0)); + if (logdetail && mapHex.getName().equalsIgnoreCase(loghex)) { + log.debug("+3+ Hex="+mapHex.getName()+" tile="+tile.getId()+" city="+number + +": stopType="+accessInfo.getStopType() + +" runTo="+accessInfo.getRunToAllowed() + +" runThrough="+accessInfo.getRunThroughAllowed() + +" loop="+accessInfo.getLoopAllowed() + +" scoreType="+accessInfo.getScoreType() + +" mutex="+accessInfo.getTrainMutexID()); + } + accessInfo.merge(tile.getAccessInfo(0)); + if (logdetail && mapHex.getName().equalsIgnoreCase(loghex)) { + log.debug("+4a Hex="+mapHex.getName()+" tile="+tile.getId()+" city="+number + +": stopType="+accessInfo.getStopType() + +" runTo="+accessInfo.getRunToAllowed() + +" runThrough="+accessInfo.getRunThroughAllowed() + +" loop="+accessInfo.getLoopAllowed() + +" scoreType="+accessInfo.getScoreType() + +" mutex="+accessInfo.getTrainMutexID()); + } + + /* Check the stop type. + * If still null at this stage, determine it from the Station properties. + */ + stopType = accessInfo.getStopType(); + if (stopType == null) { String stationType = relatedStation.get().getType(); if (stationType.equals(Station.CITY)) { - type = Type.CITY; + stopType = StopType.CITY; } else if (stationType.equals(Station.TOWN)) { - type = Type.TOWN; + stopType = StopType.TOWN; } else if (stationType.equals(Station.OFF_MAP_AREA)) { - type = Type.OFFMAP; + stopType = StopType.OFFMAP; } else if (stationType.equ... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-09-08 07:09:27
|
junit/rails/game/state/BooleanStateTest.java | 4 junit/rails/game/state/CountableItemImpl.java | 13 junit/rails/game/state/GenericStateTest.java | 4 junit/rails/game/state/HashSetStateTest.java | 3 junit/rails/game/state/IntegerStateTest.java | 2 junit/rails/game/state/ModelImpl.java | 2 junit/rails/game/state/ObservableTest.java | 61 -- junit/rails/game/state/StateManagerTest.java | 4 junit/rails/game/state/StateTest.java | 12 junit/rails/game/state/StringStateTest.java | 8 junit/rails/game/state/WalletBagTest.java | 53 + junit/rails/game/state/WalletManagerTest.java | 110 ++++ src/rails/algorithms/NetworkGraphBuilder.java | 2 src/rails/game/Bank.java | 36 - src/rails/game/BaseToken.java | 1 src/rails/game/GameManager.java | 26 src/rails/game/MapHex.java | 353 ++++++------- src/rails/game/OperatingRound.java | 54 + src/rails/game/Player.java | 4 src/rails/game/PublicCompany.java | 141 ++--- src/rails/game/Round.java | 7 src/rails/game/ShareSellingRound.java | 3 src/rails/game/StartItem.java | 8 src/rails/game/StartRound.java | 3 src/rails/game/StartRound_1830.java | 5 src/rails/game/StartRound_1835.java | 3 src/rails/game/Station.java | 94 +-- src/rails/game/StationHolder.java | 15 src/rails/game/StockRound.java | 12 src/rails/game/Stop.java | 86 +-- src/rails/game/Tile.java | 77 +- src/rails/game/TileManager.java | 2 src/rails/game/Track.java | 27 src/rails/game/TreasuryShareRound.java | 7 src/rails/game/action/BuyCertificate.java | 15 src/rails/game/action/BuyTrain.java | 22 src/rails/game/action/DiscardTrain.java | 2 src/rails/game/action/LayTile.java | 48 - src/rails/game/action/PossibleORAction.java | 4 src/rails/game/action/StartCompany.java | 9 src/rails/game/correct/CashCorrectionManager.java | 3 src/rails/game/correct/CorrectionManager.java | 3 src/rails/game/correct/MapCorrectionAction.java | 4 src/rails/game/correct/MapCorrectionManager.java | 7 src/rails/game/model/BaseTokensModel.java | 45 + src/rails/game/model/PortfolioModel.java | 36 - src/rails/game/model/PresidentModel.java | 6 src/rails/game/model/WalletMoneyModel.java | 1 src/rails/game/specific/_1835/OperatingRound_1835.java | 3 src/rails/game/specific/_1835/PrussianFormationRound.java | 13 src/rails/game/specific/_1856/CGRFormationRound.java | 33 - src/rails/game/specific/_1880/StartRound_1880.java | 5 src/rails/game/specific/_1889/OperatingRound_1889.java | 9 src/rails/game/specific/_18AL/OperatingRound_18AL.java | 3 src/rails/game/specific/_18EU/FinalMinorExchangeRound.java | 3 src/rails/game/specific/_18EU/StartCompany_18EU.java | 4 src/rails/game/specific/_18EU/StartRound_18EU.java | 7 src/rails/game/specific/_18EU/StockRound_18EU.java | 9 src/rails/game/specific/_18GA/OperatingRound_18GA.java | 4 src/rails/game/state/ArrayListChange.java | 1 src/rails/game/state/Change.java | 2 src/rails/game/state/ChangeSet.java | 16 src/rails/game/state/ChangeStack.java | 14 src/rails/game/state/CountableItem.java | 4 src/rails/game/state/DelayedItem.java | 8 src/rails/game/state/HashMapState.java | 17 src/rails/game/state/Model.java | 30 - src/rails/game/state/Observable.java | 59 -- src/rails/game/state/PortfolioChange.java | 4 src/rails/game/state/PortfolioManager.java | 4 src/rails/game/state/Root.java | 15 src/rails/game/state/State.java | 17 src/rails/game/state/StateManager.java | 150 ++++- src/rails/game/state/TileMove.java | 70 -- src/rails/game/state/Trigger.java | 11 src/rails/game/state/UnknownOwner.java | 2 src/rails/game/state/Wallet.java | 6 src/rails/game/state/WalletBag.java | 7 src/rails/game/state/WalletManager.java | 4 src/rails/game/state/WalletSet.java | 5 src/rails/ui/swing/GameSetupWindow.java | 1 src/rails/ui/swing/RemainingTilesWindow.java | 2 src/rails/ui/swing/hexmap/GUIHex.java | 28 - src/rails/ui/swing/hexmap/GUITile.java | 2 src/rails/ui/swing/hexmap/HexMap.java | 2 src/rails/util/GameFileIO.java | 3 86 files changed, 1042 insertions(+), 982 deletions(-) New commits: commit 40392cca7044d06affcefc3fa6506194be0eff9d Author: Stefan Frey <ste...@we...> Date: Sat Sep 8 06:01:47 2012 +0200 adding Trigger interface, Bank's MoneyModel diff --git a/src/rails/game/Bank.java b/src/rails/game/Bank.java index 2bb285a..2e9d90d 100644 --- a/src/rails/game/Bank.java +++ b/src/rails/game/Bank.java @@ -12,6 +12,9 @@ import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.model.WalletMoneyModel; import rails.game.state.BooleanState; +import rails.game.state.Change; +import rails.game.state.Observable; +import rails.game.state.Trigger; import rails.game.state.UnknownOwner; import rails.util.Util; @@ -44,7 +47,23 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable { /** Is the bank broken */ private final BooleanState broken = BooleanState.create(this, "broken"); - + + // Instance initializer to create a BankBroken model + { + new Trigger() { + {// instance initializer + cash.addTrigger(this); + } + public void triggered(Observable obs, Change change) { + if (cash.value() <= 0 && !broken.value()) { + broken.set(true); + cash.setText(LocalText.getText("BROKEN")); + GameManager.getInstance().registerBrokenBank(); + } + } + }; + } + protected static Logger log = LoggerFactory.getLogger(Bank.class); @@ -137,16 +156,6 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable { return scrapHeap; } - /* FIXME: Add broken check somewhere - * Check if the bank has broken. In some games <0 could apply, so this - * will become configurable. - if (cash.value() <= 0 && !broken.booleanValue()) { - broken.set(true); - cash.setText(LocalText.getText("BROKEN")); - GameManager.getInstance().registerBrokenBank(); - } - */ - /** * @return Portfolio of stock in Bank Pool */ @@ -161,10 +170,10 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable { return unavailable; } - public String getId() { + public String toText() { return LocalText.getText("BANK"); } - + // MoneyOwner interface public int getCash() { return cash.value(); @@ -174,4 +183,5 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable { return cash; } + } diff --git a/src/rails/game/model/WalletMoneyModel.java b/src/rails/game/model/WalletMoneyModel.java index 4cbbf75..1d58f6e 100644 --- a/src/rails/game/model/WalletMoneyModel.java +++ b/src/rails/game/model/WalletMoneyModel.java @@ -17,6 +17,7 @@ public class WalletMoneyModel extends MoneyModel { private WalletMoneyModel(MoneyOwner parent, String id, Boolean init, Currency currency) { super(parent, id, currency); wallet = WalletBag.create(parent, "wallet", Currency.class, currency); + wallet.addModel(this); initialised = BooleanState.create(this, "initialised", init); } diff --git a/src/rails/game/state/ChangeSet.java b/src/rails/game/state/ChangeSet.java index 2203de5..5395dde 100644 --- a/src/rails/game/state/ChangeSet.java +++ b/src/rails/game/state/ChangeSet.java @@ -45,7 +45,7 @@ public class ChangeSet { log.debug("Add " + change); // immediate execution and information of models change.execute(); - change.getState().sendChangeToModels(change); + change.getState().informTriggers(change); } /** diff --git a/src/rails/game/state/Model.java b/src/rails/game/state/Model.java index 5bad3d9..5f3c727 100644 --- a/src/rails/game/state/Model.java +++ b/src/rails/game/state/Model.java @@ -16,12 +16,4 @@ public abstract class Model extends Observable { super(parent, id); } - /** - * Calling of update informs the model that some state has changed - * Overriding this does not require a call, as it usually does nothing - */ - public void update(Change change) { - // Standard behavior is do nothing - } - } diff --git a/src/rails/game/state/Observable.java b/src/rails/game/state/Observable.java index cab77d9..08ae14d 100644 --- a/src/rails/game/state/Observable.java +++ b/src/rails/game/state/Observable.java @@ -69,6 +69,18 @@ public abstract class Observable implements Item { return getStateManager().getModels(this); } + public void addTrigger(Trigger m) { + getStateManager().addTrigger(m, this); + } + + public boolean removeTrigger(Trigger m) { + return getStateManager().removeTrigger(m, this); + } + + public ImmutableSet<Trigger> getTriggers() { + return getStateManager().getTriggers(this); + } + /** * Text to delivered to Observers * Default is defined to be identical with toString() diff --git a/src/rails/game/state/State.java b/src/rails/game/state/State.java index ed4a580..c69b480 100644 --- a/src/rails/game/state/State.java +++ b/src/rails/game/state/State.java @@ -26,8 +26,8 @@ public abstract class State extends Observable { } } - void sendChangeToModels(Change change) { - this.getStateManager().sendChangeToModels(this, change); + void informTriggers(Change change) { + this.getStateManager().informTriggers(this, change); } } \ No newline at end of file diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java index 18a12b1..26648a1 100644 --- a/src/rails/game/state/StateManager.java +++ b/src/rails/game/state/StateManager.java @@ -27,6 +27,9 @@ public final class StateManager extends Manager{ HashSetState.create(this, "allStates"); private final HashMultimapState<Observable, Model> models = HashMultimapState.create(this, "models"); + private final HashMultimapState<Observable, Trigger> triggers = + HashMultimapState.create(this, "triggers"); + // observers is not a state variable (as the have to register and de-register themselves) // gui eleemnts do not have a state of their own (with respect to the game engine) @@ -102,7 +105,7 @@ public final class StateManager extends Manager{ /** * Adds the combination of model to observable - * @param Model the model that tracks the observable + * @param Model the model that is updated by the observable * @param Observable the observable to monitor */ void addModel(Model model, Observable observable) { @@ -117,16 +120,42 @@ public final class StateManager extends Manager{ return models.get(observable); } + /** + * Adds the combination of trigger to observable + * @param Trigger the trigger that tracks the observable + * @param Observable the observable to monitor + */ + void addTrigger(Trigger trigger, Observable observable) { + triggers.put(observable, trigger); + } + + boolean removeTrigger(Trigger trigger, Observable observable) { + return triggers.remove(observable, trigger); + } - void sendChangeToModels(State state, Change change) { + ImmutableSet<Trigger> getTriggers(Observable observable) { + return triggers.get(observable); + } + + void informTriggers(State state, Change change) { + + // Inform direct triggers + for (Trigger t:getTriggers(state)) { + t.triggered(state, change); + log.debug("State " + state + " sends change to Trigger " + t); + } + // check if there are models - ImmutableSet<Model> initModels = state.getModels(); + ImmutableSet<Model> initModels = getModels(state); if (initModels.isEmpty()) return; ImmutableList<Model> allModels = getModelsToUpdate(initModels); + // Inform indirect triggers for (Model m:allModels) { - m.update(change); - log.debug("State " + state + " sends change to Model " + m); + for (Trigger t:getTriggers(m)) { + t.triggered(m, change); + log.debug("Model " + m + " sends change to Trigger " + t); + } } } @@ -155,7 +184,7 @@ public final class StateManager extends Manager{ private static enum Color {WHITE, GREY, BLACK}; private void topoSort(final Observable v, final Map<Observable, Color> colors, final LinkedList<Model> topoList) { colors.put(v, Color.GREY); - for (Model m:v.getModels()) { + for (Model m:getModels(v)) { if (!colors.containsKey(m)) { topoSort(m, colors, topoList); } else if (colors.get(m) == Color.GREY) { @@ -170,7 +199,7 @@ public final class StateManager extends Manager{ void updateObservers(Set<State> states) { // all direct observers for (State s:states){ - Set<Observer> observers = s.getObservers(); + Set<Observer> observers = getObservers(s); if (observers.isEmpty()) continue; // cache StateText String stateText = s.toText(); @@ -182,7 +211,7 @@ public final class StateManager extends Manager{ // all indirect observers for (Model m:getModelsToUpdate(states)) { - Set<Observer> observers = m.getObservers(); + Set<Observer> observers = getObservers(m); if (observers.isEmpty()) continue; // cache ModelText String modelText = m.toText(); diff --git a/src/rails/game/state/Trigger.java b/src/rails/game/state/Trigger.java new file mode 100644 index 0000000..6d98021 --- /dev/null +++ b/src/rails/game/state/Trigger.java @@ -0,0 +1,11 @@ +package rails.game.state; + +public interface Trigger { + + /** + * Method that is called if something has changed + */ + public void triggered(Observable observable, Change change); + + +} commit 7e1968117743a8cff1d809da5381dc499061b1a7 Author: Stefan Frey <ste...@we...> Date: Fri Sep 7 12:48:10 2012 +0200 fixed several minor bugs diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index a108723..defc765 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -767,9 +767,10 @@ public class GameManager extends RailsManager implements Configurable, Owner { interruptedRound = getCurrentRound(); + // An id basd on interruptedRound and company id + String id = "SSR_" + interruptedRound.getId() + "_" + cashNeedingCompany.getId(); // check if other companies can be dumped - // FIXME: This ID will not work, as it will create duplication - createRound(shareSellingRoundClass, "ShareSellingRound").start( + createRound(shareSellingRoundClass, id).start( interruptedRound, player, cashToRaise, cashNeedingCompany, !problemDumpOtherCompanies || forcedSellingCompanyDump); // the last parameter indicates if the dump of other companies is allowed, either this is explicit or diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 3d0a8f4..7714ff8 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -20,8 +20,6 @@ import rails.game.Stop.RunTo; import rails.game.Stop.Score; import rails.game.Stop.Type; import rails.game.action.LayTile; -import rails.game.model.WalletMoneyModel; -import rails.game.model.PortfolioModel; import rails.game.state.BooleanState; import rails.game.state.GenericState; @@ -1278,8 +1276,8 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable { * * @TODO include tokens?? */ - public String getData() { - return currentTile.value().getNb() + "/" + currentTileRotation; + public String toText() { + return currentTile.value().getNb() + "/" + currentTileRotation.value(); } /** @@ -1352,27 +1350,4 @@ public class MapHex extends Model implements RailsItem, Owner, Configurable { return scoreType; } - // Owner interface - - public boolean hasPortfolio() { - return false; - } - - public PortfolioModel getPortfolioModel() { - return null; - } - - public boolean hasCash() { - return false; - } - - public WalletMoneyModel getCash() { - return null; - } - - public void update() { - // TODO Auto-generated method stub - - } - } diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java index aa0e49b..d0b5631 100644 --- a/src/rails/game/OperatingRound.java +++ b/src/rails/game/OperatingRound.java @@ -308,7 +308,7 @@ public class OperatingRound extends Round implements Observer { result = done(nullAction); break; case NullAction.SKIP: - skip(); + skip(nullAction); result = true; break; } @@ -703,10 +703,11 @@ public class OperatingRound extends Round implements Observer { } while (++stepIndex < steps.length) { step = steps[stepIndex]; - log.debug("Step " + step); + log.debug("OR considers step " + step); if (step == GameDef.OrStep.LAY_TOKEN && company.getNumberOfFreeBaseTokens() == 0) { + log.debug("OR skips " + step + ": No freeBaseTokens"); continue; } @@ -714,6 +715,7 @@ public class OperatingRound extends Round implements Observer { if (!company.canRunTrains()) { // No trains, then the revenue is zero. + log.debug("OR skips " + step + ": Cannot run trains"); executeSetRevenueAndDividend ( new SetDividend (0, false, new int[] {SetDividend.NO_TRAIN})); // TODO: This probably does not handle share selling correctly @@ -723,6 +725,7 @@ public class OperatingRound extends Round implements Observer { if (step == GameDef.OrStep.PAYOUT) { // This step is now obsolete + log.debug("OR skips " + step + ": Always skipped"); continue; } @@ -767,7 +770,10 @@ public class OperatingRound extends Round implements Observer { } - if (!gameSpecificNextStep (step)) continue; + if (!gameSpecificNextStep (step)) { + log.debug("OR skips " + step + ": Not game specific"); + continue; + } // No reason found to skip this step break; @@ -808,10 +814,10 @@ public class OperatingRound extends Round implements Observer { * 3.1. NOOPS *=======================================*/ - public void skip() { + public void skip(NullAction action) { log.debug("Skip step " + stepObject.value()); // TODO: Check if this is ok - // FIXME: changeStack.start(true); + ChangeStack.start(this, action); nextStep(); } @@ -2742,7 +2748,7 @@ public class OperatingRound extends Round implements Observer { operatingCompany.value().buyTrain(train, price); - if (oldOwner == ipo.getTrainsModel()) { + if (oldOwner == ipo.getParent()) { train.getCertType().addToBoughtFromIPO(); trainManager.setAnyTrainBought(true); // Clone the train if infinitely available @@ -2751,7 +2757,7 @@ public class OperatingRound extends Round implements Observer { } } - if (oldOwner instanceof Bank) { + if (oldOwner instanceof BankPortfolio) { trainsBoughtThisTurn.add(train.getCertType()); } diff --git a/src/rails/game/action/BuyCertificate.java b/src/rails/game/action/BuyCertificate.java index 4401351..a6f400c 100644 --- a/src/rails/game/action/BuyCertificate.java +++ b/src/rails/game/action/BuyCertificate.java @@ -7,9 +7,6 @@ import rails.game.*; import rails.game.model.PortfolioModel; import rails.game.model.PortfolioOwner; -/** - * @author Erik Vos - */ public class BuyCertificate extends PossibleAction { // Server-side settings diff --git a/src/rails/game/action/BuyTrain.java b/src/rails/game/action/BuyTrain.java index a15a02f..518c32a 100644 --- a/src/rails/game/action/BuyTrain.java +++ b/src/rails/game/action/BuyTrain.java @@ -5,6 +5,8 @@ import java.io.ObjectInputStream; import java.util.HashSet; import java.util.Set; +import com.google.common.base.Objects; + import rails.game.CompanyManager; import rails.game.Currency; import rails.game.GameManager; @@ -218,7 +220,7 @@ public class BuyTrain extends PossibleORAction { } b.append("train (").append(trainUniqueId).append(") from ").append(from.getId()); if (fixedCost > 0) { - b.append(" for ").append(Currency.format(train, fixedCost)); + b.append(" for ").append(Currency.format(company, fixedCost)); } else { b.append(" for any amount"); } @@ -229,14 +231,14 @@ public class BuyTrain extends PossibleORAction { b.append(forcedExchange ? " (forced exchange)" : " (exchange)"); } if (presidentMustAddCash) { - b.append(" must add cash ").append(Currency.format(train, presidentCashToAdd)); + b.append(" must add cash ").append(Currency.format(company, presidentCashToAdd)); } else if (presidentMayAddCash) { b.append(" may add cash up to ").append( - Currency.format(train, presidentCashToAdd)); + Currency.format(company, presidentCashToAdd)); } if (acted) { - b.append(" - paid: ").append(Currency.format(train, pricePaid)); - if (addedCash > 0) b.append(" pres.cash added: "+Currency.format(train, addedCash)); + b.append(" - paid: ").append(Currency.format(company, pricePaid)); + if (addedCash > 0) b.append(" pres.cash added: "+Currency.fo |
From: Stefan F. <ste...@us...> - 2012-09-02 06:47:37
|
junit/rails/game/state/ArrayListMultimapStateTest.java | 4 junit/rails/game/state/ArrayListStateTest.java | 3 junit/rails/game/state/BlockingChangeSetTest.java | 71 - junit/rails/game/state/ChangeStackTest.java | 142 +- junit/rails/game/state/GameChangeSetTest.java | 68 - junit/rails/game/state/HashMultimapStateTest.java | 4 junit/rails/game/state/HashSetStateTest.java | 4 junit/rails/game/state/ModelTest.java | 6 junit/rails/game/state/ObservableTest.java | 2 junit/rails/game/state/ObserverTest.java | 6 junit/rails/game/state/PortfolioHolderImpl.java | 17 junit/rails/game/state/PortfolioHolderTest.java | 51 junit/rails/game/state/PortfolioManagerTest.java | 4 junit/rails/game/state/PortfolioMapTest.java | 6 junit/rails/game/state/PortfolioSetTest.java | 2 junit/rails/game/state/StateImpl.java | 2 junit/rails/game/state/StateTest.java | 4 junit/rails/game/state/StateTestUtils.java | 28 junit/rails/game/state/StringStateTest.java | 9 src/rails/algorithms/NetworkCompanyGraph.java | 2 src/rails/algorithms/NetworkEdge.java | 2 src/rails/algorithms/NetworkGraphBuilder.java | 2 src/rails/algorithms/NetworkIterator.java | 2 src/rails/algorithms/NetworkTrain.java | 2 src/rails/algorithms/NetworkVertex.java | 2 src/rails/algorithms/RevenueAdapter.java | 2 src/rails/algorithms/RevenueBonus.java | 2 src/rails/algorithms/RevenueBonusTemplate.java | 4 src/rails/algorithms/RevenueCalculator.java | 2 src/rails/algorithms/RevenueManager.java | 13 src/rails/algorithms/RevenueTrainRun.java | 2 src/rails/common/DisplayBuffer.java | 2 src/rails/common/GuiHints.java | 10 src/rails/common/LocalText.java | 2 src/rails/common/ResourceLoader.java | 564 ----------- src/rails/common/parser/ComponentManager.java | 35 src/rails/common/parser/Config.java | 277 ++--- src/rails/common/parser/ConfigItem.java | 2 src/rails/common/parser/Configurable.java | 37 src/rails/common/parser/Configure.java | 63 + src/rails/common/parser/GameFileParser.java | 6 src/rails/common/parser/GameInfoParser.java | 15 src/rails/common/parser/Tag.java | 6 src/rails/common/parser/XMLParser.java | 17 src/rails/game/ActionChangeSet.java | 31 src/rails/game/Bank.java | 86 - src/rails/game/BankPortfolio.java | 8 src/rails/game/BaseToken.java | 12 src/rails/game/BonusToken.java | 10 src/rails/game/Certificate.java | 4 src/rails/game/Company.java | 244 +--- src/rails/game/CompanyManager.java | 12 src/rails/game/CompanyType.java | 10 src/rails/game/Currency.java | 95 + src/rails/game/GameManager.java | 82 - src/rails/game/MapHex.java | 12 src/rails/game/MapManager.java | 11 src/rails/game/Money.java | 54 + src/rails/game/MoneyOwner.java | 12 src/rails/game/OperatingRound.java | 265 ++--- src/rails/game/Phase.java | 4 src/rails/game/PhaseManager.java | 10 src/rails/game/Player.java | 26 src/rails/game/PlayerManager.java | 17 src/rails/game/PrivateCompany.java | 103 +- src/rails/game/PublicCertificate.java | 41 src/rails/game/PublicCompany.java | 207 ++-- src/rails/game/RailsAbstractItem.java | 24 src/rails/game/RailsItem.java | 38 src/rails/game/RailsManager.java | 18 src/rails/game/RailsRoot.java | 27 src/rails/game/ReportBuffer.java | 9 src/rails/game/Round.java | 52 - src/rails/game/ShareSellingRound.java | 10 src/rails/game/StartItem.java | 41 src/rails/game/StartPacket.java | 12 src/rails/game/StartRound.java | 14 src/rails/game/StartRound_1830.java | 15 src/rails/game/StartRound_1835.java | 5 src/rails/game/Station.java | 2 src/rails/game/StockMarket.java | 134 -- src/rails/game/StockRound.java | 128 +- src/rails/game/StockSpace.java | 53 - src/rails/game/StockSpaceType.java | 12 src/rails/game/Stop.java | 5 src/rails/game/TileManager.java | 21 src/rails/game/Token.java | 17 src/rails/game/Train.java | 61 - src/rails/game/TrainCertificateType.java | 112 -- src/rails/game/TrainManager.java | 35 src/rails/game/TrainType.java | 5 src/rails/game/TreasuryShareRound.java | 43 src/rails/game/action/BuyCertificate.java | 3 src/rails/game/action/BuyTrain.java | 21 src/rails/game/action/PossibleAction.java | 5 src/rails/game/action/PossibleActions.java | 2 src/rails/game/action/SellShares.java | 2 src/rails/game/action/SetDividend.java | 8 src/rails/game/action/StartCompany.java | 4 src/rails/game/correct/CashCorrectionAction.java | 5 src/rails/game/correct/CashCorrectionManager.java | 27 src/rails/game/correct/CorrectionManager.java | 8 src/rails/game/correct/CorrectionManagerI.java | 19 src/rails/game/correct/CorrectionType.java | 6 src/rails/game/correct/MapCorrectionManager.java | 2 src/rails/game/model/BaseTokensModel.java | 2 src/rails/game/model/BonusModel.java | 17 src/rails/game/model/CalculatedMoneyModel.java | 8 src/rails/game/model/CashMoneyModel.java | 62 - src/rails/game/model/CashOwner.java | 11 src/rails/game/model/CertificateCountModel.java | 2 src/rails/game/model/CertificatesModel.java | 106 -- src/rails/game/model/CountingMoneyModel.java | 58 + src/rails/game/model/MoneyModel.java | 49 src/rails/game/model/PortfolioModel.java | 156 +-- src/rails/game/model/PortfolioOwner.java | 4 src/rails/game/model/PresidentModel.java | 2 src/rails/game/model/PriceModel.java | 11 src/rails/game/model/PrivatesModel.java | 15 src/rails/game/model/ShareModel.java | 6 src/rails/game/model/TrainsModel.java | 32 src/rails/game/model/WalletMoneyModel.java | 48 src/rails/game/special/ExchangeForShare.java | 16 src/rails/game/special/LocatedBonus.java | 27 src/rails/game/special/SellBonusToken.java | 20 src/rails/game/special/SpecialProperty.java | 72 + src/rails/game/special/SpecialRight.java | 40 src/rails/game/special/SpecialTileLay.java | 31 src/rails/game/special/SpecialTokenLay.java | 21 src/rails/game/special/SpecialTrainBuy.java | 13 src/rails/game/specific/_1825/PublicCompany_1825.java | 4 src/rails/game/specific/_1825/StartRound_1825.java | 3 src/rails/game/specific/_1835/FoldIntoPrussian.java | 4 src/rails/game/specific/_1835/GameManager_1835.java | 32 src/rails/game/specific/_1835/OperatingRound_1835.java | 19 src/rails/game/specific/_1835/PrussianFormationRound.java | 22 src/rails/game/specific/_1835/StockRound_1835.java | 4 src/rails/game/specific/_1851/BirminghamTileModifier.java | 2 src/rails/game/specific/_1851/StartRound_1851.java | 3 src/rails/game/specific/_1856/CGRFormationRound.java | 57 - src/rails/game/specific/_1856/GameManager_1856.java | 4 src/rails/game/specific/_1856/OperatingRound_1856.java | 30 src/rails/game/specific/_1856/PublicCompany_1856.java | 3 src/rails/game/specific/_1856/PublicCompany_CGR.java | 6 src/rails/game/specific/_1856/StockRound_1856.java | 18 src/rails/game/specific/_1880/Investor_1880.java | 4 src/rails/game/specific/_1880/StartRound_1880.java | 14 src/rails/game/specific/_1889/OperatingRound_1889.java | 5 src/rails/game/specific/_18AL/NameTrains.java | 23 src/rails/game/specific/_18AL/NameableTrain.java | 6 src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java | 2 src/rails/game/specific/_18AL/NamedTrainToken.java | 39 src/rails/game/specific/_18AL/OperatingRound_18AL.java | 7 src/rails/game/specific/_18EU/FinalMinorExchangeRound.java | 11 src/rails/game/specific/_18EU/GameManager_18EU.java | 8 src/rails/game/specific/_18EU/OffBoardRevenueModifier.java | 2 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 4 src/rails/game/specific/_18EU/StartRound_18EU.java | 17 src/rails/game/specific/_18EU/StockRound_18EU.java | 97 - src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java | 4 src/rails/game/specific/_18TN/PublicCompany_18TN.java | 4 src/rails/game/state/AbstractItem.java | 6 src/rails/game/state/ArrayListMultimapState.java | 2 src/rails/game/state/ArrayListState.java | 2 src/rails/game/state/BooleanState.java | 2 src/rails/game/state/Change.java | 2 src/rails/game/state/ChangeAction.java | 9 src/rails/game/state/ChangeSet.java | 35 src/rails/game/state/ChangeStack.java | 189 +-- src/rails/game/state/Configurable.java | 38 src/rails/game/state/Configure.java | 62 - src/rails/game/state/Countable.java | 20 src/rails/game/state/CountableItem.java | 47 src/rails/game/state/GenericState.java | 2 src/rails/game/state/HashMapState.java | 2 src/rails/game/state/HashMultimapState.java | 2 src/rails/game/state/HashSetState.java | 2 src/rails/game/state/IntegerState.java | 2 src/rails/game/state/Item.java | 5 src/rails/game/state/Manager.java | 4 src/rails/game/state/Model.java | 2 src/rails/game/state/Observable.java | 13 src/rails/game/state/Ownable.java | 8 src/rails/game/state/OwnableItem.java | 31 src/rails/game/state/Owner.java | 4 src/rails/game/state/Portfolio.java | 34 src/rails/game/state/PortfolioChange.java | 39 src/rails/game/state/PortfolioHolder.java | 16 src/rails/game/state/PortfolioManager.java | 7 src/rails/game/state/PortfolioMap.java | 47 src/rails/game/state/PortfolioSet.java | 29 src/rails/game/state/Root.java | 17 src/rails/game/state/StateManager.java | 12 src/rails/game/state/StringState.java | 6 src/rails/game/state/TileMove.java | 2 src/rails/game/state/UnknownOwner.java | 2 src/rails/game/state/Wallet.java | 103 -- src/rails/game/state/WalletBag.java | 46 src/rails/game/state/WalletChange.java | 39 src/rails/game/state/WalletManager.java | 87 + src/rails/game/state/WalletSet.java | 61 + src/rails/ui/swing/AutoLoadPoller.java | 2 src/rails/ui/swing/AutoSaveLoadDialog.java | 2 src/rails/ui/swing/GameSetupWindow.java | 2 src/rails/ui/swing/GameStatus.java | 25 src/rails/ui/swing/GameUIManager.java | 8 src/rails/ui/swing/GridPanel.java | 52 - src/rails/ui/swing/ImageLoader.java | 11 src/rails/ui/swing/MapPanel.java | 2 src/rails/ui/swing/ORPanel.java | 7 src/rails/ui/swing/ORUIManager.java | 37 src/rails/ui/swing/ORWindow.java | 2 src/rails/ui/swing/RemainingTilesWindow.java | 2 src/rails/ui/swing/ReportWindow.java | 2 src/rails/ui/swing/ReportWindowDynamic.java | 5 src/rails/ui/swing/StartRoundWindow.java | 37 src/rails/ui/swing/StatusWindow.java | 6 src/rails/ui/swing/UpgradesPanel.java | 2 src/rails/ui/swing/WindowSettings.java | 2 src/rails/ui/swing/elements/CheckBoxDialog.java | 2 src/rails/ui/swing/elements/ConfirmationDialog.java | 2 src/rails/ui/swing/elements/Field.java | 19 src/rails/ui/swing/elements/GUIStockSpace.java | 2 src/rails/ui/swing/elements/MessageDialog.java | 2 src/rails/ui/swing/elements/RadioButtonDialog.java | 2 src/rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java | 4 src/rails/ui/swing/gamespecific/_18AL/NameTrainsDialog.java | 4 src/rails/ui/swing/hexmap/GUIHex.java | 7 src/rails/ui/swing/hexmap/GUITile.java | 2 src/rails/ui/swing/hexmap/HexMap.java | 2 src/rails/ui/swing/hexmap/HexMapImage.java | 2 src/rails/util/GameFileIO.java | 2 src/rails/util/SequenceUtil.java | 21 src/rails/util/Util.java | 16 src/test/GameTestServlet.java | 12 src/test/TestGame.java | 2 src/tools/ListAndFixSavedFiles.java | 2 src/tools/MakeGameTileSets.java | 12 238 files changed, 2935 insertions(+), 3580 deletions(-) New commits: commit 19882bd18f40d7eed10889df287b9cefdc7e7bb2 Author: Stefan Frey <ste...@we...> Date: Sun Sep 2 08:46:23 2012 +0200 fixed presidency swap problem diff --git a/src/rails/game/model/PortfolioModel.java b/src/rails/game/model/PortfolioModel.java index f7a1dcf..5789893 100644 --- a/src/rails/game/model/PortfolioModel.java +++ b/src/rails/game/model/PortfolioModel.java @@ -252,38 +252,38 @@ public class PortfolioModel extends Model { * @param company The company whose Presidency is handed over. * @param other The new President's portfolio. * @return The common certificates returned. + * + * TODO: Rewrite the method replacing PortfolioModel with Owner */ public List<PublicCertificate> swapPresidentCertificate( PublicCompany company, PortfolioModel other) { // FIXME: Rewrite this parrt -// List<PublicCertificate> swapped = new ArrayList<PublicCertificate>(); -// PublicCertificate swapCert; -// -// // Find the President's certificate -// PublicCertificate cert = this.findCertificate(company, true); -// if (cert == null) return null; -// int shares = cert.getShares(); -// -// // Check if counterparty has enough single certificates -// if (other.ownsCertificates(company, 1, false) >= shares) { -// for (int i = 0; i < shares; i++) { -// swapCert = other.findCertificate(company, 1, false); -// certificates.getPortfolio().moveInto(swapCert); -// swapped.add(swapCert); -// -// } -// } else if (other.ownsCertificates(company, shares, false) >= 1) { -// swapCert = other.findCertificate(company, 2, false); -// certificates.getPortfolio().moveInto(swapCert); -// swapped.add(swapCert); -// } else { -// return null; -// } -// certificates.getPortfolio().moveInto(cert); -// -// return swapped; - return null; + List<PublicCertificate> swapped = new ArrayList<PublicCertificate>(); + PublicCertificate swapCert; + + // Find the President's certificate + PublicCertificate cert = this.findCertificate(company, true); + if (cert == null) return null; + int shares = cert.getShares(); + + // Check if counterparty has enough single certificates + if (other.ownsCertificates(company, 1, false) >= shares) { + for (int i = 0; i < shares; i++) { + swapCert = other.findCertificate(company, 1, false); + swapCert.moveTo(getParent()); + swapped.add(swapCert); + } + } else if (other.ownsCertificates(company, shares, false) >= 1) { + swapCert = other.findCertificate(company, 2, false); + swapCert.moveTo(getParent()); + swapped.add(swapCert); + } else { + return null; + } + cert.moveTo(other.getParent()); + + return swapped; } public void discardTrain(Train train) { diff --git a/src/rails/ui/swing/elements/Field.java b/src/rails/ui/swing/elements/Field.java index 38a85a4..eac6099 100644 --- a/src/rails/ui/swing/elements/Field.java +++ b/src/rails/ui/swing/elements/Field.java @@ -98,7 +98,7 @@ public class Field extends JLabel implements Observer { setBackground((Color)vu.getValue(key)); normalBgColour = getBackground(); setForeground (Util.isDark(normalBgColour) ? Color.WHITE : Color.BLACK); - } + } } } */ commit 993af5ea4a44a80d5df8858c0f947941040a5c78 Author: Stefan Frey <ste...@we...> Date: Sun Sep 2 07:23:36 2012 +0200 fixed logger method call in many classes diff --git a/src/rails/algorithms/NetworkCompanyGraph.java b/src/rails/algorithms/NetworkCompanyGraph.java index f8361ba..26c0c93 100644 --- a/src/rails/algorithms/NetworkCompanyGraph.java +++ b/src/rails/algorithms/NetworkCompanyGraph.java @@ -27,7 +27,7 @@ import rails.game.PublicCompany; */ public class NetworkCompanyGraph { protected static Logger log = - LoggerFactory.getLogger(NetworkCompanyGraph.class.getPackage().getName()); + LoggerFactory.getLogger(NetworkCompanyGraph.class); private final NetworkGraphBuilder graphBuilder; private final PublicCompany company; diff --git a/src/rails/algorithms/NetworkEdge.java b/src/rails/algorithms/NetworkEdge.java index 3e88613..2716b7d 100644 --- a/src/rails/algorithms/NetworkEdge.java +++ b/src/rails/algorithms/NetworkEdge.java @@ -17,7 +17,7 @@ import rails.ui.swing.hexmap.HexMap; public final class NetworkEdge implements Comparable<NetworkEdge> { protected static Logger log = - LoggerFactory.getLogger(NetworkEdge.class.getPackage().getName()); + LoggerFactory.getLogger(NetworkEdge.class); private final NetworkVertex source; diff --git a/src/rails/algorithms/NetworkGraphBuilder.java b/src/rails/algorithms/NetworkGraphBuilder.java index 9a98563..6b5af76 100644 --- a/src/rails/algorithms/NetworkGraphBuilder.java +++ b/src/rails/algorithms/NetworkGraphBuilder.java @@ -40,7 +40,7 @@ import rails.game.state.Owner; public final class NetworkGraphBuilder implements Iterable<NetworkVertex> { protected static Logger log = - LoggerFactory.getLogger(NetworkGraphBuilder.class.getPackage().getName()); + LoggerFactory.getLogger(NetworkGraphBuilder.class); private final SimpleGraph<NetworkVertex, NetworkEdge> mapGraph; diff --git a/src/rails/algorithms/NetworkIterator.java b/src/rails/algorithms/NetworkIterator.java index 80f8dfb..7512338 100644 --- a/src/rails/algorithms/NetworkIterator.java +++ b/src/rails/algorithms/NetworkIterator.java @@ -37,7 +37,7 @@ public class NetworkIterator extends private final Graph<NetworkVertex, NetworkEdge> graph; protected static Logger log = - LoggerFactory.getLogger(NetworkIterator.class.getPackage().getName()); + LoggerFactory.getLogger(NetworkIterator.class); public NetworkIterator(Graph<NetworkVertex, NetworkEdge> graph, diff --git a/src/rails/algorithms/NetworkTrain.java b/src/rails/algorithms/NetworkTrain.java index 1858122..a243e0e 100644 --- a/src/rails/algorithms/NetworkTrain.java +++ b/src/rails/algorithms/NetworkTrain.java @@ -10,7 +10,7 @@ import rails.game.TrainType; public final class NetworkTrain implements Comparable<NetworkTrain>{ protected static Logger log = - LoggerFactory.getLogger(NetworkTrain.class.getPackage().getName()); + LoggerFactory.getLogger(NetworkTrain.class); private int majors; private int minors; diff --git a/src/rails/algorithms/NetworkVertex.java b/src/rails/algorithms/NetworkVertex.java index 7c81b76..b2d9aca 100644 --- a/src/rails/algorithms/NetworkVertex.java +++ b/src/rails/algorithms/NetworkVertex.java @@ -15,7 +15,7 @@ import rails.ui.swing.hexmap.*; public final class NetworkVertex implements Comparable<NetworkVertex> { protected static Logger log = - LoggerFactory.getLogger(NetworkVertex.class.getPackage().getName()); + LoggerFactory.getLogger(NetworkVertex.class); public static enum VertexType { STATION, diff --git a/src/rails/algorithms/RevenueAdapter.java b/src/rails/algorithms/RevenueAdapter.java index bf39b5c..2702796 100644 --- a/src/rails/algorithms/RevenueAdapter.java +++ b/src/rails/algorithms/RevenueAdapter.java @@ -37,7 +37,7 @@ import rails.ui.swing.hexmap.HexMap; public final class RevenueAdapter implements Runnable { protected static Logger log = - LoggerFactory.getLogger(RevenueAdapter.class.getPackage().getName()); + LoggerFactory.getLogger(RevenueAdapter.class); // define VertexVisitSet public class VertexVisit { diff --git a/src/rails/algorithms/RevenueBonus.java b/src/rails/algorithms/RevenueBonus.java index dbe5738..de0f8b7 100644 --- a/src/rails/algorithms/RevenueBonus.java +++ b/src/rails/algorithms/RevenueBonus.java @@ -16,7 +16,7 @@ import rails.game.TrainType; public final class RevenueBonus { protected static Logger log = - LoggerFactory.getLogger(RevenueBonus.class.getPackage().getName()); + LoggerFactory.getLogger(RevenueBonus.class); // bonus values private final int value; diff --git a/src/rails/algorithms/RevenueBonusTemplate.java b/src/rails/algorithms/RevenueBonusTemplate.java index 7f67552..b021e8d 100644 --- a/src/rails/algorithms/RevenueBonusTemplate.java +++ b/src/rails/algorithms/RevenueBonusTemplate.java @@ -24,7 +24,7 @@ import rails.game.TrainType; public final class RevenueBonusTemplate implements Configurable { protected static Logger log = - LoggerFactory.getLogger(RevenueBonusTemplate.class.getPackage().getName()); + LoggerFactory.getLogger(RevenueBonusTemplate.class); // bonus value private int value; diff --git a/src/rails/algorithms/RevenueCalculator.java b/src/rails/algorithms/RevenueCalculator.java index 274ea33..649c577 100644 --- a/src/rails/algorithms/RevenueCalculator.java +++ b/src/rails/algorithms/RevenueCalculator.java @@ -99,7 +99,7 @@ abstract class RevenueCalculator { } protected static Logger log = - LoggerFactory.getLogger(RevenueCalculator.class.getPackage().getName()); + LoggerFactory.getLogger(RevenueCalculator.class); public RevenueCalculator (RevenueAdapter revenueAdapter, int nbVertexes, int nbEdges, diff --git a/src/rails/algorithms/RevenueManager.java b/src/rails/algorithms/RevenueManager.java index c01f29f..886c40c 100644 --- a/src/rails/algorithms/RevenueManager.java +++ b/src/rails/algorithms/RevenueManager.java @@ -25,7 +25,7 @@ import rails.game.state.ArrayListState; public final class RevenueManager extends RailsManager implements Configurable { protected static Logger log = - LoggerFactory.getLogger(RevenueManager.class.getPackage().getName()); + LoggerFactory.getLogger(RevenueManager.class); private final HashSet<Configurable> configurableModifiers = new HashSet<Configurable>(); diff --git a/src/rails/algorithms/RevenueTrainRun.java b/src/rails/algorithms/RevenueTrainRun.java index 37c03c7..b87522e 100644 --- a/src/rails/algorithms/RevenueTrainRun.java +++ b/src/rails/algorithms/RevenueTrainRun.java @@ -27,7 +27,7 @@ public class RevenueTrainRun implements Comparable<RevenueTrainRun> { private static final int PRETTY_PRINT_INDENT = 10; protected static Logger log = - LoggerFactory.getLogger(RevenueTrainRun.class.getPackage().getName()); + LoggerFactory.getLogger(RevenueTrainRun.class); // definitions private RevenueAdapter revenueAdapter; diff --git a/src/rails/common/DisplayBuffer.java b/src/rails/common/DisplayBuffer.java index d68bef3..5eb90c7 100644 --- a/src/rails/common/DisplayBuffer.java +++ b/src/rails/common/DisplayBuffer.java @@ -22,7 +22,7 @@ public final class DisplayBuffer { protected static List<String> initialQueue = new ArrayList<String>(); protected static Logger log = - LoggerFactory.getLogger(DisplayBuffer.class.getPackage().getName()); + LoggerFactory.getLogger(DisplayBuffer.class); public DisplayBuffer() { if (!initialQueue.isEmpty()) { diff --git a/src/rails/common/LocalText.java b/src/rails/common/LocalText.java index 89e183a..551d906 100644 --- a/src/rails/common/LocalText.java +++ b/src/rails/common/LocalText.java @@ -28,7 +28,7 @@ public class LocalText extends ResourceBundle { protected static ResourceBundle localisedText; protected static Logger log = - LoggerFactory.getLogger(LocalText.class.getPackage().getName()); + LoggerFactory.getLogger(LocalText.class); public static String getText(String key) { return getText(key, (Object[]) null); diff --git a/src/rails/common/parser/Config.java b/src/rails/common/parser/Config.java index 9c5fe78..a713414 100644 --- a/src/rails/common/parser/Config.java +++ b/src/rails/common/parser/Config.java @@ -364,7 +364,7 @@ public final class Config { System.out.println("log4j.configuration = " + log4jSelection); // delayed setting of logger - log = LoggerFactory.getLogger(Config.class.getPackage().getName()); + log = LoggerFactory.getLogger(Config.class); // define settings for testing legacyConfigFile = false; @@ -390,7 +390,7 @@ public final class Config { System.out.println("log4j.configuration = " + log4jSelection); // delayed setting of logger - log = LoggerFactory.getLogger(Config.class.getPackage().getName()); + log = LoggerFactory.getLogger(Config.class); /* * Check if the profile has been set from the command line to do this is diff --git a/src/rails/common/parser/ConfigItem.java b/src/rails/common/parser/ConfigItem.java index 11c43e0..2ac323a 100644 --- a/src/rails/common/parser/ConfigItem.java +++ b/src/rails/common/parser/ConfigItem.java @@ -16,7 +16,7 @@ import rails.util.Util; public final class ConfigItem { protected static Logger log = - LoggerFactory.getLogger(ConfigItem.class.getPackage().getName()); + LoggerFactory.getLogger(ConfigItem.class); /** * Defines possible types (Java classes used as types in ConfigItem below diff --git a/src/rails/common/parser/Tag.java b/src/rails/common/parser/Tag.java index dc0be88..bf096e3 100644 --- a/src/rails/common/parser/Tag.java +++ b/src/rails/common/parser/Tag.java @@ -35,7 +35,7 @@ public class Tag { private Map<String, String> gameOptions = null; protected static Logger log = - LoggerFactory.getLogger(Tag.class.getPackage().getName()); + LoggerFactory.getLogger(Tag.class); public Tag(Element element) { this.element = element; diff --git a/src/rails/game/Bank.java b/src/rails/game/Bank.java index 3e9e511..2bb285a 100644 --- a/src/rails/game/Bank.java +++ b/src/rails/game/Bank.java @@ -46,7 +46,7 @@ public class Bank extends RailsManager implements MoneyOwner, Configurable { private final BooleanState broken = BooleanState.create(this, "broken"); protected static Logger log = - LoggerFactory.getLogger(Bank.class.getPackage().getName()); + LoggerFactory.getLogger(Bank.class); /** * Used by Configure (via reflection) only diff --git a/src/rails/game/CompanyManager.java b/src/rails/game/CompanyManager.java index 2d78059..04cf829 100644 --- a/src/rails/game/CompanyManager.java +++ b/src/rails/game/CompanyManager.java @@ -57,7 +57,7 @@ public class CompanyManager extends RailsManager implements Configurable { private int numberOfPublicCompanies = 0; protected static Logger log = - LoggerFactory.getLogger(CompanyManager.class.getPackage().getName()); + LoggerFactory.getLogger(CompanyManager.class); protected GameManager gameManager; diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index d1ffe1b..eea5f55 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -215,7 +215,7 @@ public class GameManager extends RailsManager implements Configurable, Owner { protected Map<String, Integer> storageIds = new HashMap<String, Integer>(); protected static Logger log = - LoggerFactory.getLogger(GameManager.class.getPackage().getName()); + LoggerFactory.getLogger(GameManager.class); public GameManager(RailsRoot parent, String id) { super(parent, id); diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 4e6dd37..b1e2908 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -177,7 +177,7 @@ StationHolder { protected Score scoreType = null; protected static Logger log = - LoggerFactory.getLogger(MapHex.class.getPackage().getName()); + LoggerFactory.getLogger(MapHex.class); private MapHex(MapManager parent, String id) { super(parent, id); diff --git a/src/rails/game/MapManager.java b/src/rails/game/MapManager.java index 4a48da4..19a312b 100644 --- a/src/rails/game/MapManager.java +++ b/src/rails/game/MapManager.java @@ -61,7 +61,7 @@ public class MapManager extends RailsManager implements Configurable { protected Map<Type,Score> scoreTypeDefaults = new HashMap<Type, Score>(); protected static Logger log = - LoggerFactory.getLogger(MapManager.class.getPackage().getName()); + LoggerFactory.getLogger(MapManager.class); /** * Used by Configure (via reflection) only diff --git a/src/rails/game/Phase.java b/src/rails/game/Phase.java index a05ceb6..e45bf0c 100644 --- a/src/rails/game/Phase.java +++ b/src/rails/game/Phase.java @@ -85,7 +85,7 @@ public class Phase implements Configurable { protected Map<String, String> parameters = null; protected static Logger log = - LoggerFactory.getLogger(Phase.class.getPackage().getName()); + LoggerFactory.getLogger(Phase.class); public Phase(int index, String name, Phase previousPhase) { this.index = index; diff --git a/src/rails/game/PhaseManager.java b/src/rails/game/PhaseManager.java index 8d31399..8a5d242 100644 --- a/src/rails/game/PhaseManager.java +++ b/src/rails/game/PhaseManager.java @@ -24,7 +24,7 @@ public class PhaseManager extends RailsManager implements Configurable { protected GameManager gameManager; protected static Logger log = - LoggerFactory.getLogger(PhaseManager.class.getPackage().getName()); + LoggerFactory.getLogger(PhaseManager.class); /** diff --git a/src/rails/game/PublicCertificate.java b/src/rails/game/PublicCertificate.java index efe0af4..c359797 100644 --- a/src/rails/game/PublicCertificate.java +++ b/src/rails/game/PublicCertificate.java @@ -47,7 +47,7 @@ public class PublicCertificate extends OwnableItem<PublicCertificate> implements protected static Logger log = - LoggerFactory.getLogger(PublicCertificate.class.getPackage().getName()); + LoggerFactory.getLogger(PublicCertificate.class); // TODO: Rewrite constructors // TODO: Should every certificate have its own id and be registered with the parent? diff --git a/src/rails/game/RailsRoot.java b/src/rails/game/RailsRoot.java index a66abd8..1fe9e0d 100644 --- a/src/rails/game/RailsRoot.java +++ b/src/rails/game/RailsRoot.java @@ -39,7 +39,7 @@ public class RailsRoot extends Root implements RailsItem { protected Map<String, String> gameOptions; protected static Logger log = - LoggerFactory.getLogger(RailsRoot.class.getPackage().getName()); + LoggerFactory.getLogger(RailsRoot.class); public RailsRoot(String name, List<String> players, Map<String, String> options) { super(); diff --git a/src/rails/game/ReportBuffer.java b/src/rails/game/ReportBuffer.java index 0533cd3..dc63292 100644 --- a/src/rails/game/ReportBuffer.java +++ b/src/rails/game/ReportBuffer.java @@ -151,7 +151,7 @@ public final class ReportBuffer { } private static Logger log = - LoggerFactory.getLogger(ReportBuffer.class.getPackage().getName()); + LoggerFactory.getLogger(ReportBuffer.class); public ReportBuffer() { diff --git a/src/rails/game/Round.java b/src/rails/game/Round.java index 4225b34..0de6aa9 100644 --- a/src/rails/game/Round.java +++ b/src/rails/game/Round.java @@ -24,7 +24,7 @@ public abstract class Round extends RailsAbstractItem implements Creatable { protected GuiHints guiHints = null; protected static Logger log = - LoggerFactory.getLogger(Round.class.getPackage().getName()); + LoggerFactory.getLogger(Round.class); protected GameManager gameManager = null; protected CompanyManager companyManager = null; diff --git a/src/rails/game/StartItem.java b/src/rails/game/StartItem.java index f2242e4..1f4f38c 100644 --- a/src/rails/game/StartItem.java +++ b/src/rails/game/StartItem.java @@ -74,7 +74,7 @@ public class StartItem extends RailsAbstractItem { protected static Map<String, StartItem> startItemMap; protected static Logger log = - LoggerFactory.getLogger(StartItem.class.getPackage().getName()); + LoggerFactory.getLogger(StartItem.class); /** * The constructor, taking the properties of the "primary" (often teh only) diff --git a/src/rails/game/StartPacket.java b/src/rails/game/StartPacket.java index 6328096..4f24187 100644 --- a/src/rails/game/StartPacket.java +++ b/src/rails/game/StartPacket.java @@ -44,7 +44,7 @@ public class StartPacket extends RailsAbstractItem { public static final String DEFAULT_ID = "Initial"; protected static Logger log = - LoggerFactory.getLogger(StartPacket.class.getPackage().getName()); + LoggerFactory.getLogger(StartPacket.class); private StartPacket(RailsItem parent, String id, String roundClassName) { super(parent, Util.hasValue(id) ? id : DEFAULT_ID); diff --git a/src/rails/game/Station.java b/src/rails/game/Station.java index 58e220e..8c18504 100644 --- a/src/rails/game/Station.java +++ b/src/rails/game/Station.java @@ -48,7 +48,7 @@ public class Station { private static final List<String> validTypes = Arrays.asList(types); protected static Logger log = - LoggerFactory.getLogger(Station.class.getPackage().getName()); + LoggerFactory.getLogger(Station.class); /** Check validity of a Station type */ public static boolean isTypeValid(String type) { diff --git a/src/rails/game/Stop.java b/src/rails/game/Stop.java index efc1f87..4d3d985 100644 --- a/src/rails/game/Stop.java +++ b/src/rails/game/Stop.java @@ -41,7 +41,7 @@ public class Stop extends RailsAbstractItem implements Owner { private Score scoreType = null; protected static Logger log = - LoggerFactory.getLogger(Stop.class.getPackage().getName()); + LoggerFactory.getLogger(Stop.class); public enum RunTo { YES, diff --git a/src/rails/game/Token.java b/src/rails/game/Token.java index bac3fa9..6a64ad4 100644 --- a/src/rails/game/Token.java +++ b/src/rails/game/Token.java @@ -18,7 +18,7 @@ public abstract class Token<T extends Token<T>> extends OwnableItem<T> implement protected static String STORAGE_NAME = "Token"; protected static Logger log = - LoggerFactory.getLogger(Token.class.getPackage().getName()); + LoggerFactory.getLogger(Token.class); protected Token(RailsItem parent, String id, Class<T> clazz) { super(parent, id, clazz); diff --git a/src/rails/game/TrainCertificateType.java b/src/rails/game/TrainCertificateType.java index 8875efa..a0ab660 100644 --- a/src/rails/game/TrainCertificateType.java +++ b/src/rails/game/TrainCertificateType.java @@ -50,7 +50,7 @@ public class TrainCertificateType extends RailsAbstractItem implements Configura private final BooleanState rusted = BooleanState.create(this, "rusted"); protected static Logger log = - LoggerFactory.getLogger(TrainCertificateType.class.getPackage().getName()); + LoggerFactory.getLogger(TrainCertificateType.class); private TrainCertificateType (TrainManager parent, String id, int index) { super(parent, id); diff --git a/src/rails/game/TrainManager.java b/src/rails/game/TrainManager.java index 709fbfc..764d96c 100644 --- a/src/rails/game/TrainManager.java +++ b/src/rails/game/TrainManager.java @@ -75,7 +75,7 @@ public class TrainManager extends RailsManager implements Configurable { boolean trainPriceAtFaceValueIfDifferentPresidents = false; protected static Logger log = - LoggerFactory.getLogger(TrainManager.class.getPackage().getName()); + LoggerFactory.getLogger(TrainManager.class); /** * Used by Configure (via reflection) only diff --git a/src/rails/game/TrainType.java b/src/rails/game/TrainType.java index 183400d..c1a38cc 100644 --- a/src/rails/game/TrainType.java +++ b/src/rails/game/TrainType.java @@ -43,7 +43,7 @@ public class TrainType implements Cloneable { protected String initialPortfolio = "IPO"; protected static Logger log = - LoggerFactory.getLogger(TrainType.class.getPackage().getName()); + LoggerFactory.getLogger(TrainType.class); /** * @param real False for the default type, else real. The default type does diff --git a/src/rails/game/action/PossibleAction.java b/src/rails/game/action/PossibleAction.java index d4a8a69..86aea6c 100644 --- a/src/rails/game/action/PossibleAction.java +++ b/src/rails/game/action/PossibleAction.java @@ -32,7 +32,7 @@ public abstract class PossibleAction implements ChangeAction, Serializable { public static final long serialVersionUID = 3L; protected static Logger log = - LoggerFactory.getLogger(PossibleAction.class.getPackage().getName()); + LoggerFactory.getLogger(PossibleAction.class); /** * diff --git a/src/rails/game/action/PossibleActions.java b/src/rails/game/action/PossibleActions.java index 040b5b6..3196954 100644 --- a/src/rails/game/action/PossibleActions.java +++ b/src/rails/game/action/PossibleActions.java @@ -28,7 +28,7 @@ public class PossibleActions { private List<PossibleAction> possibleActions; protected static Logger log = - LoggerFactory.getLogger(PossibleActions.class.getPackage().getName()); + LoggerFactory.getLogger(PossibleActions.class); /** * This class can only be instantiated locally. diff --git a/src/rails/game/correct/CorrectionManager.java b/src/rails/game/correct/CorrectionManager.java index 28a8ffb..a213c74 100644 --- a/src/rails/game/correct/CorrectionManager.java +++ b/src/rails/game/correct/CorrectionManager.java @@ -19,7 +19,7 @@ public abstract class CorrectionManager extends RailsAbstractItem { private final BooleanState active = BooleanState.create(this, "active"); protected static Logger log = - LoggerFactory.getLogger(CorrectionManager.class.getPackage().getName()); + LoggerFactory.getLogger(CorrectionManager.class); protected CorrectionManager(GameManager parent, CorrectionType ct) { super(parent, ct.name()); diff --git a/src/rails/game/special/SpecialProperty.java b/src/rails/game/special/SpecialProperty.java index 28ba961..fc33981 100644 --- a/src/rails/game/special/SpecialProperty.java +++ b/src/rails/game/special/SpecialProperty.java @@ -69,7 +69,7 @@ public abstract class SpecialProperty extends OwnableItem<SpecialProperty> imple protected GameManager gameManager; protected static Logger log = - LoggerFactory.getLogger(SpecialProperty.class.getPackage().getName()); + LoggerFactory.getLogger(SpecialProperty.class); protected SpecialProperty(RailsItem parent, String id) { super(parent, convertId(id) , SpecialProperty.class); diff --git a/src/rails/game/specific/_1851/BirminghamTileModifier.java b/src/rails/game/specific/_1851/BirminghamTileModifier.java index 3b6a973..f0ee812 100644 --- a/src/rails/game/specific/_1851/BirminghamTileModifier.java +++ b/src/rails/game/specific/_1851/BirminghamTileModifier.java @@ -16,7 +16,7 @@ import rails.game.MapHex; public class BirminghamTileModifier implements NetworkGraphModifier { protected static Logger log = - LoggerFactory.getLogger(BirminghamTileModifier.class.getPackage().getName()); + LoggerFactory.getLogger(BirminghamTileModifier.class); public void modifyGraph(NetworkGraphBuilder graphBuilder) { diff --git a/src/rails/game/specific/_18EU/OffBoardRevenueModifier.java b/src/rails/game/specific/_18EU/OffBoardRevenueModifier.java index d651a94..d297269 100644 --- a/src/rails/game/specific/_18EU/OffBoardRevenueModifier.java +++ b/src/rails/game/specific/_18EU/OffBoardRevenueModifier.java @@ -18,7 +18,7 @@ import rails.game.Tile; public class OffBoardRevenueModifier implements RevenueStaticModifier { protected static Logger log = - LoggerFactory.getLogger(OffBoardRevenueModifier.class.getPackage().getName()); + LoggerFactory.getLogger(OffBoardRevenueModifier.class); public boolean modifyCalculator(RevenueAdapter revenueAdapter) { diff --git a/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java b/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java index feafa9d..484fb8e 100644 --- a/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java +++ b/src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java @@ -18,7 +18,7 @@ import rails.game.GameManager; public class RuhrRevenueModifier implements RevenueStaticModifier, Configurable { protected static Logger log = - LoggerFactory.getLogger(RuhrRevenueModifier.class.getPackage().getName()); + LoggerFactory.getLogger(RuhrRevenueModifier.class); private boolean doublesOnlyMajors; diff --git a/src/rails/game/state/ChangeStack.java b/src/rails/game/state/ChangeStack.java index 294ada0..cc804ef 100644 --- a/src/rails/game/state/ChangeStack.java +++ b/src/rails/game/state/ChangeStack.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; public class ChangeStack { protected static Logger log = - LoggerFactory.getLogger(ChangeStack.class.getPackage().getName()); + LoggerFactory.getLogger(ChangeStack.class); // static fields private final LinkedList<ChangeSet> undoStack = new LinkedList<ChangeSet>(); diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java index 958a018..ec20ebb 100644 --- a/src/rails/game/state/StateManager.java +++ b/src/rails/game/state/StateManager.java @@ -18,7 +18,7 @@ import com.google.common.collect.Maps; public final class StateManager extends Manager implements DelayedItem { protected static Logger log = - LoggerFactory.getLogger(StateManager.class.getPackage().getName()); + LoggerFactory.getLogger(StateManager.class); private final ChangeStack changeStack = ChangeStack.create(this); private final HashSetState<State> allStates = HashSetState.create(this, null); diff --git a/src/rails/game/state/TileMove.java b/src/rails/game/state/TileMove.java index dfec2e8..4c7fb40 100644 --- a/src/rails/game/state/TileMove.java +++ b/src/rails/game/state/TileMove.java @@ -22,7 +22,7 @@ import rails.game.*; public class TileMove { protected static Logger log = - LoggerFactory.getLogger(TileMove.class.getPackage().getName()); + LoggerFactory.getLogger(TileMove.class); MapHex hex; Tile oldTile; diff --git a/src/rails/ui/swing/AutoLoadPoller.java b/src/rails/ui/swing/AutoLoadPoller.java index b7331e8..c9719a4 100644 --- a/src/rails/ui/swing/AutoLoadPoller.java +++ b/src/rails/ui/swing/AutoLoadPoller.java @@ -29,7 +29,7 @@ public class AutoLoadPoller extends Thread { public static final int SUSPENDED = 2; protected static Logger log = - LoggerFactory.getLogger(AutoLoadPoller.class.getPackage().getName()); + LoggerFactory.getLogger(AutoLoadPoller.class); public AutoLoadPoller (GameUIManager guiMgr, String saveDirectory, String savePrefix, String ownPostfix, int status, int pollingInterval) { diff --git a/src/rails/ui/swing/AutoSaveLoadDialog.java b/src/rails/ui/swing/AutoSaveLoadDialog.java index 796c5be..1bcba2a 100644 --- a/src/rails/ui/swing/AutoSaveLoadDialog.java +++ b/src/rails/ui/swing/AutoSaveLoadDialog.java @@ -34,7 +34,7 @@ public class AutoSaveLoadDialog extends JDialog implements ActionListener { private static final int NUM_OPTIONS = 3; protected static Logger log = - LoggerFactory.getLogger(AutoSaveLoadDialog.class.getPackage().getName()); + LoggerFactory.getLogger(AutoSaveLoadDialog.class); public AutoSaveLoadDialog(DialogOwner owner, int oldStatus, int oldInterval) { super((Frame) null, "AutoSaveLoad settings", false); // Non-modal diff --git a/src/rails/ui/swing/GameSetupWindow.java b/src/rails/ui/swing/GameSetupWindow.java index 5a2642d..af5a406 100644 --- a/src/rails/ui/swing/GameSetupWindow.java +++ b/src/rails/ui/swing/GameSetupWindow.java @@ -60,7 +60,7 @@ public class GameSetupWindow extends JDialog implements ActionListener { static final int AI_PLAYER = 2; protected static Logger log = - LoggerFactory.getLogger(GameSetupWindow.class.getPackage().getName()); + LoggerFactory.getLogger(GameSetupWindow.class); public GameSetupWindow() { super(); diff --git a/src/rails/ui/swing/GameStatus.java b/src/rails/ui/swing/GameStatus.java index 3055092..26964f0 100644 --- a/src/rails/ui/swing/GameStatus.java +++ b/src/rails/ui/swing/GameStatus.java @@ -119,7 +119,7 @@ public class GameStatus extends GridPanel implements ActionListener { protected Map<Player, Integer> playerIndex = new HashMap<Player, Integer>(); protected static Logger log = - LoggerFactory.getLogger(GameStatus.class.getPackage().getName()); + LoggerFactory.getLogger(GameStatus.class); public GameStatus() { super(); diff --git a/src/rails/ui/swing/GameUIManager.java b/src/rails/ui/swing/GameUIManager.java index e4b5cb1..7eed9f8 100644 --- a/src/rails/ui/swing/GameUIManager.java +++ b/src/rails/ui/swing/GameUIManager.java @@ -96,7 +96,7 @@ public class GameUIManager implements DialogOwner { protected boolean previousResult; protected static Logger log = - LoggerFactory.getLogger(GameUIManager.class.getPackage().getName()); + LoggerFactory.getLogger(GameUIManager.class); public GameUIManager() { diff --git a/src/rails/ui/swing/GridPanel.java b/src/rails/ui/swing/GridPanel.java index 440d9c5..ef52b00 100644 --- a/src/rails/ui/swing/GridPanel.java +++ b/src/rails/ui/swing/GridPanel.java @@ -66,7 +66,7 @@ implements ActionListener, KeyListener { protected List<JMenuItem> menuItemsToReset = new ArrayList<JMenuItem>(); protected static Logger log = - LoggerFactory.getLogger(GridPanel.class.getPackage().getName()); + LoggerFactory.getLogger(GridPanel.class); public void redisplay() { diff --git a/src/rails/ui/swing/ImageLoader.java b/src/rails/ui/swing/ImageLoader.java index 073df92..b1229ee 100644 --- a/src/rails/ui/swing/ImageLoader.java +++ b/src/rails/ui/swing/ImageLoader.java @@ -40,7 +40,7 @@ public class ImageLoader { } private static Logger log = - LoggerFactory.getLogger(ImageLoader.class.getPackage().getName()); + LoggerFactory.getLogger(ImageLoader.class); static { if (Util.hasValue(tileRootDir) && !tileRootDir.endsWith("/")) { diff --git a/src/rails/ui/swing/MapPanel.java b/src/rails/ui/swing/MapPanel.java index d9601a1..0070906 100644 --- a/src/rails/ui/swing/MapPanel.java +++ b/src/rails/ui/swing/MapPanel.java @@ -32,7 +32,7 @@ public class MapPanel extends JPanel { private Dimension currentMapSize; protected static Logger log = - LoggerFactory.getLogger(MapPanel.class.getPackage().getName()); + LoggerFactory.getLogger(MapPanel.class); public MapPanel(GameUIManager gameUIManager) { this.gameUIManager = gameUIManager; diff --git a/src/rails/ui/swing/ORPanel.java b/src/rails/ui/swing/ORPanel.java index 706fe01..c898170 100644 --- a/src/rails/ui/swing/ORPanel.java +++ b/src/rails/ui/swing/ORPanel.java @@ -119,7 +119,7 @@ implements ActionListener, KeyListener, RevenueListener { private Thread revenueThread = null; protected static Logger log = - LoggerFactory.getLogger(ORPanel.class.getPackage().getName()); + LoggerFactory.getLogger(ORPanel.class); public ORPanel(ORWindow parent, ORUIManager orUIManager) { super(); diff --git a/src/rails/ui/swing/ORUIManager.java b/src/rails/ui/swing/ORUIManager.java index 700f02f..394e050 100644 --- a/src/rails/ui/swing/ORUIManager.java +++ b/src/rails/ui/swing/ORUIManager.java @@ -94,7 +94,7 @@ public class ORUIManager implements DialogOwner { "CorrectMap" }; protected static Logger log = - LoggerFactory.getLogger(ORUIManager.class.getPackage().getName()); + LoggerFactory.getLogger(ORUIManager.class); public ORUIManager() { diff --git a/src/rails/ui/swing/ORWindow.java b/src/rails/ui/swing/ORWindow.java index 11fa331..6d204c4 100644 --- a/src/rails/ui/swing/ORWindow.java +++ b/src/rails/ui/swing/ORWindow.java @@ -40,7 +40,7 @@ public class ORWindow extends JFrame implements ActionPerformer { List<LayToken> allowedTokenLays = new ArrayList<LayToken>(); protected static Logger log = - LoggerFactory.getLogger(ORWindow.class.getPackage().getName()); + LoggerFactory.getLogger(ORWindow.class); public ORWindow(GameUIManager gameUIManager) { super(); diff --git a/src/rails/ui/swing/RemainingTilesWindow.java b/src/rails/ui/swing/RemainingTilesWindow.java index 9a1bc2e..d5f1e8a 100644 --- a/src/rails/ui/swing/RemainingTilesWindow.java +++ b/src/rails/ui/swing/RemainingTilesWindow.java @@ -35,7 +35,7 @@ public class RemainingTilesWindow extends JFrame implements WindowListener, private final static int COLUMNS = 10; protected static Logger log = - LoggerFactory.getLogger(RemainingTilesWindow.class.getPackage().getName()); + LoggerFactory.getLogger(RemainingTilesWindow.class); public RemainingTilesWindow(ORWindow orWindow) { super(); diff --git a/src/rails/ui/swing/ReportWindow.java b/src/rails/ui/swing/ReportWindow.java index 67ff94d..23fd604 100644 --- a/src/rails/ui/swing/ReportWindow.java +++ b/src/rails/ui/swing/ReportWindow.java @@ -50,7 +50,7 @@ public class ReportWindow extends AbstractReportWindow implements ActionListener protected static final String FIND_PREV_CMD = "FindPrev"; protected static Logger log = - LoggerFactory.getLogger(ReportWindow.class.getPackage().getName()); + LoggerFactory.getLogger(ReportWindow.class); public ReportWindow(GameUIManager gameUIManager) { diff --git a/src/rails/ui/swing/ReportWindowDynamic.java b/src/rails/ui/swing/ReportWindowDynamic.java index c6c7916..fb3cbc6 100644 --- a/src/rails/ui/swing/ReportWindowDynamic.java +++ b/src/rails/ui/swing/ReportWindowDynamic.java @@ -44,7 +44,7 @@ public class ReportWindowDynamic extends AbstractReportWindow implements Action private boolean timeWarpMode; protected static Logger log = - LoggerFactory.getLogger(ReportWindowDynamic.class.getPackage().getName()); + LoggerFactory.getLogger(ReportWindowDynamic.class); public ReportWindowDynamic(GameUIManager gameUIManager) { super(gameUIManager); diff --git a/src/rails/ui/swing/StartRoundWindow.java b/src/rails/ui/swing/StartRoundWindow.java index 546c164..85d9135 100644 --- a/src/rails/ui/swing/StartRoundWindow.java +++ b/src/rails/ui/swing/StartRoundWindow.java @@ -105,7 +105,7 @@ public class StartRoundWindow extends JFrame implements ActionListener, // private boolean repacked = false; protected static Logger log = - LoggerFactory.getLogger(StartRoundWindow.class.getPackage().getName()); + LoggerFactory.getLogger(StartRoundWindow.class); public StartRoundWindow(StartRound round, GameUIManager parent) { super(); diff --git a/src/rails/ui/swing/StatusWindow.java b/src/rails/ui/swing/StatusWindow.java index 350501e..1ff698b 100644 --- a/src/rails/ui/swing/StatusWindow.java +++ b/src/rails/ui/swing/StatusWindow.java @@ -88,7 +88,7 @@ public class StatusWindow extends JFrame implements ActionListener, private ActionMenuItem undoItem, forcedUndoItem, redoItem, redoItem2; protected static Logger log = - LoggerFactory.getLogger(StatusWindow.class.getPackage().getName()); + LoggerFactory.getLogger(StatusWindow.class); // GraphicsConfiguration graphicsConfiguration; diff --git a/src/rails/ui/swing/UpgradesPanel.java b/src/rails/ui/swing/UpgradesPanel.java index 86086d2..f1bc258 100644 --- a/src/rails/ui/swing/UpgradesPanel.java +++ b/src/rails/ui/swing/UpgradesPanel.java @@ -49,7 +49,7 @@ public class UpgradesPanel extends Box implements MouseListener, ActionListener private HexMap hexMap; protected static Logger log = - LoggerFactory.getLogger(UpgradesPanel.class.getPackage().getName()); + LoggerFactory.getLogger(UpgradesPanel.class); public UpgradesPanel(ORUIManager orUIManager) { super(BoxLayout.Y_AXIS); diff --git a/src/rails/ui/swing/WindowSettings.java b/src/rails/ui/swing/WindowSettings.java index 821a8f7..40fd0e3 100644 --- a/src/rails/ui/swing/WindowSettings.java +++ b/src/rails/ui/swing/WindowSettings.java @@ -21,7 +21,7 @@ public class WindowSettings { private static final String settingsfilename = "settings_xxxx.rails_ini"; protected static Logger log = - LoggerFactory.getLogger(WindowSettings.class.getPackage().getName()); + LoggerFactory.getLogger(WindowSettings.class); public WindowSettings (String gameName) { String directory = System.getProperty("settings.directory"); diff --git a/src/rails/ui/swing/elements/CheckBoxDialog.java b/src/rails/ui/swing/elements/CheckBoxDialog.java index 8a625dd..bf66a43 100644 --- a/src/rails/ui/swing/elements/CheckBoxDialog.java +++ b/src/rails/ui/swing/elements/CheckBoxDialog.java @@ -34,7 +34,7 @@ public class CheckBoxDialog extends JDialog implements ActionListener { boolean hasCancelButton = false; protected static Logger log = - LoggerFactory.getLogger(CheckBoxDialog.class.getPackage().getName()); + LoggerFactory.getLogger(CheckBoxDialog.class); public CheckBoxDialog(DialogOwner owner, JFrame window, String title, String message, String[] options) { diff --git a/src/rails/ui/swing/elements/ConfirmationDialog.java b/src/rails/ui/swing/elements/ConfirmationDialog.java index ff3ac0f..f68b072 100644 --- a/src/rails/ui/swing/elements/ConfirmationDialog.java +++ b/src/rails/ui/swing/elements/ConfirmationDialog.java @@ -27,7 +27,7 @@ public class ConfirmationDialog extends JDialog implements ActionListener { boolean answer = false; protected static Logger log = - LoggerFactory.getLogger(ConfirmationDialog.class.getPackage().getName()); + LoggerFactory.getLogger(ConfirmationDialog.class); public ConfirmationDialog(DialogOwner owner, String title, String message, String okText, String cancelText) { diff --git a/src/rails/ui/swing/elements/GUIStockSpace.java b/src/rails/ui/swing/elements/GUIStockSpace.java index d1d0ab5..b26d0d3 100644 --- a/src/rails/ui/swing/elements/GUIStockSpace.java +++ b/src/rails/ui/swing/elements/GUIStockSpace.java @@ -41,7 +41,7 @@ public class GUIStockSpace extends JLayeredPane implements Observer { private static final int TOKEN_DIAMETER = 20; protected static Logger log = - LoggerFactory.getLogger(GUIStockSpace.class.getPackage().getName()); + LoggerFactory.getLogger(GUIStockSpace.class); public GUIStockSpace(int x, int y, StockSpace model) { diff --git a/src/rails/ui/swing/elements/MessageDialog.java b/src/rails/ui/swing/elements/MessageDialog.java index 047f4d0..97d5267 100644 --- a/src/rails/ui/swing/elements/MessageDialog.java +++ b/src/rails/ui/swing/elements/MessageDialog.java @@ -27,7 +27,7 @@ public class MessageDialog extends JDialog implements ActionListener { String message; protected static Logger log = - LoggerFactory.getLogger(MessageDialog.class.getPackage().getName()); + LoggerFactory.ge... [truncated message content] |
From: Erik V. <ev...@us...> - 2012-08-30 11:12:25
|
data/GamesList.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit f86acdf3e526052f22213c594e3e4e75efb3d107 Author: Erik Vos <eri...@xs...> Date: Thu Aug 30 13:11:36 2012 +0200 Sorted 1835 game options to make the Options list looks prettier. diff --git a/data/GamesList.xml b/data/GamesList.xml index 4f0d7d4..3690e9d 100644 --- a/data/GamesList.xml +++ b/data/GamesList.xml @@ -61,10 +61,10 @@ Known limitations: <Option name="RouteAwareness" values="Highlight,Deactivate" default="Highlight" /> <Option name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest" /> <Option name="UnlimitedTiles" values="No,Yellow Plain,Yes" default="No"/> - <Option name="NoMapMode" type="toggle" default="no" /> <Option name="BYFloatsAt" values="50%,20%" default="50%"/> <Option name="LDIncome" values="20M,30M" default="20M"/> <Option name="MinorsRequireFloatedBY" type="toggle" default="no"/> + <Option name="NoMapMode" type="toggle" default="no" /> <Players minimum="3" maximum="7"/> </Game> |
From: Stefan F. <ste...@us...> - 2012-08-22 12:15:49
|
src/rails/algorithms/NetworkCompanyGraph.java | 4 src/rails/algorithms/NetworkGraphBuilder.java | 4 src/rails/algorithms/RevenueBonusTemplate.java | 4 src/rails/algorithms/RevenueManager.java | 21 src/rails/common/parser/ComponentManager.java | 54 - src/rails/common/parser/ConfigurableComponent.java | 37 - src/rails/common/parser/GameFileParser.java | 5 src/rails/game/Bank.java | 23 src/rails/game/BaseToken.java | 10 src/rails/game/BonusToken.java | 14 src/rails/game/Company.java | 66 -- src/rails/game/CompanyManager.java | 11 src/rails/game/CompanyType.java | 9 src/rails/game/EndOfGameRound.java | 9 src/rails/game/GameManager.java | 66 -- src/rails/game/GameRoot.java | 306 ---------- src/rails/game/MapHex.java | 134 +--- src/rails/game/MapManager.java | 15 src/rails/game/OperatingRound.java | 8 src/rails/game/Phase.java | 4 src/rails/game/PhaseManager.java | 14 src/rails/game/Player.java | 20 src/rails/game/PlayerManager.java | 13 src/rails/game/PrivateCompany.java | 42 + src/rails/game/PublicCertificate.java | 46 - src/rails/game/PublicCompany.java | 60 -- src/rails/game/RailsItem.java | 44 + src/rails/game/RailsManager.java | 26 src/rails/game/RailsRoot.java | 310 +++++++++++ src/rails/game/ReportBuffer.java | 7 src/rails/game/Round.java | 22 src/rails/game/ShareSellingRound.java | 14 src/rails/game/StartItem.java | 23 src/rails/game/StartRound_1830.java | 11 src/rails/game/StartRound_1835.java | 11 src/rails/game/StockMarket.java | 22 src/rails/game/StockRound.java | 16 src/rails/game/StockSpace.java | 2 src/rails/game/Stop.java | 11 src/rails/game/TileManager.java | 14 src/rails/game/Token.java | 14 src/rails/game/Train.java | 25 src/rails/game/TrainCertificateType.java | 37 - src/rails/game/TrainManager.java | 21 src/rails/game/TrainType.java | 2 src/rails/game/TreasuryShareRound.java | 25 src/rails/game/action/LayBonusToken.java | 2 src/rails/game/correct/MapCorrectionManager.java | 12 src/rails/game/model/BaseTokensModel.java | 41 - src/rails/game/model/BonusModel.java | 2 src/rails/game/model/CertificateCountModel.java | 2 src/rails/game/model/CertificatesModel.java | 41 - src/rails/game/model/MoneyModel.java | 2 src/rails/game/model/PortfolioModel.java | 33 - src/rails/game/model/PresidentModel.java | 2 src/rails/game/model/PriceModel.java | 4 src/rails/game/model/PrivatesModel.java | 3 src/rails/game/model/ShareModel.java | 34 + src/rails/game/model/TrainsModel.java | 3 src/rails/game/special/ExchangeForShare.java | 22 src/rails/game/special/LocatedBonus.java | 21 src/rails/game/special/SellBonusToken.java | 22 src/rails/game/special/SpecialProperty.java | 40 - src/rails/game/special/SpecialRight.java | 27 src/rails/game/special/SpecialTileLay.java | 24 src/rails/game/special/SpecialTokenLay.java | 37 - src/rails/game/special/SpecialTrainBuy.java | 19 src/rails/game/specific/_1825/OperatingRound_1825.java | 11 src/rails/game/specific/_1825/StartRound_1825.java | 9 src/rails/game/specific/_1825/StockRound_1825.java | 11 src/rails/game/specific/_1835/GameManager_1835.java | 7 src/rails/game/specific/_1835/OperatingRound_1835.java | 11 src/rails/game/specific/_1835/PrussianFormationRound.java | 15 src/rails/game/specific/_1835/StockRound_1835.java | 11 src/rails/game/specific/_1851/StartRound_1851.java | 9 src/rails/game/specific/_1856/CGRFormationRound.java | 41 - src/rails/game/specific/_1856/GameManager_1856.java | 8 src/rails/game/specific/_1856/OperatingRound_1856.java | 7 src/rails/game/specific/_1856/ShareSellingRound_1856.java | 13 src/rails/game/specific/_1856/StockRound_1856.java | 15 src/rails/game/specific/_1880/StartRound_1880.java | 9 src/rails/game/specific/_1880/StockRound_1880.java | 11 src/rails/game/specific/_1889/OperatingRound_1889.java | 11 src/rails/game/specific/_18AL/NameTrains.java | 19 src/rails/game/specific/_18AL/NamedTrainRevenueModifier.java | 4 src/rails/game/specific/_18AL/NamedTrainToken.java | 6 src/rails/game/specific/_18AL/OperatingRound_18AL.java | 11 src/rails/game/specific/_18EU/GameManager_18EU.java | 13 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 9 src/rails/game/specific/_18EU/StartRound_18EU.java | 11 src/rails/game/specific/_18EU/StockRound_18EU.java | 12 src/rails/game/specific/_18GA/OperatingRound_18GA.java | 11 src/rails/game/specific/_18Kaas/RuhrRevenueModifier.java | 4 src/rails/game/specific/_18TN/OperatingRound_18TN.java | 7 src/rails/game/state/AbstractItem.java | 15 src/rails/game/state/ChangeStack.java | 4 src/rails/game/state/Configurable.java | 38 + src/rails/game/state/Configure.java | 62 ++ src/rails/game/state/Context.java | 26 src/rails/game/state/Creatable.java | 8 src/rails/game/state/GameRoot.java | 23 src/rails/game/state/Item.java | 2 src/rails/game/state/Manager.java | 10 src/rails/game/state/Observable.java | 19 src/rails/game/state/Ownable.java | 7 src/rails/game/state/OwnableItem.java | 10 src/rails/game/state/Portfolio.java | 56 + src/rails/game/state/Root.java | 19 src/rails/game/state/StateManager.java | 2 src/rails/ui/swing/GameSetupWindow.java | 8 src/rails/ui/swing/ORPanel.java | 4 src/rails/ui/swing/ORUIManager.java | 4 src/rails/ui/swing/UpgradesPanel.java | 6 src/rails/ui/swing/elements/Field.java | 1 src/rails/ui/swing/hexmap/GUIHex.java | 43 - src/rails/util/GameFileIO.java | 14 src/rails/util/RunGame.java | 6 src/test/TestGame.java | 4 src/test/TestGameBuilder.java | 6 119 files changed, 1393 insertions(+), 1359 deletions(-) New commits: commit 1d5a09d3d9b5da6dbdf1bf643f4362835529fba0 Author: Stefan Frey <ste...@we...> Date: Mon Aug 20 11:35:25 2012 +0200 Milestone: Startup of 1830 works Lots of small fixes Separate Portfolios for BaseToken and BonusToken Some refactoring of Round creation started diff --git a/src/rails/algorithms/NetworkCompanyGraph.java b/src/rails/algorithms/NetworkCompanyGraph.java index 0379db6..f8361ba 100644 --- a/src/rails/algorithms/NetworkCompanyGraph.java +++ b/src/rails/algorithms/NetworkCompanyGraph.java @@ -17,8 +17,8 @@ import org.jgrapht.graph.SimpleGraph; import org.jgrapht.graph.Subgraph; import rails.algorithms.RevenueAdapter.EdgeTravel; +import rails.game.BaseToken; import rails.game.PublicCompany; -import rails.game.Token; /** * This class stores and creates the various graphs @@ -115,7 +115,7 @@ public class NetworkCompanyGraph { public List<NetworkVertex> getCompanyBaseTokenVertexes(PublicCompany company) { List<NetworkVertex> vertexes = new ArrayList<NetworkVertex>(); - for (Token token:company.getLaidBaseTokens()){ + for (BaseToken token:company.getLaidBaseTokens()){ NetworkVertex vertex = graphBuilder.getVertex(token); if (vertex == null) continue; vertexes.add(vertex); diff --git a/src/rails/algorithms/NetworkGraphBuilder.java b/src/rails/algorithms/NetworkGraphBuilder.java index 3501905..9a98563 100644 --- a/src/rails/algorithms/NetworkGraphBuilder.java +++ b/src/rails/algorithms/NetworkGraphBuilder.java @@ -34,7 +34,6 @@ import rails.game.MapManager; import rails.game.PublicCompany; import rails.game.Station; import rails.game.Tile; -import rails.game.Token; import rails.game.Track; import rails.game.state.Owner; @@ -176,8 +175,7 @@ public final class NetworkGraphBuilder implements Iterable<NetworkVertex> { return mapVertexes.get(identVertex); } - public NetworkVertex getVertex(Token token) { - if (!(token instanceof BaseToken)) return null; + public NetworkVertex getVertex(BaseToken token) { Owner owner = token.getOwner(); // TODO: Check if this still works if (!(owner instanceof Stop)) return null; diff --git a/src/rails/algorithms/RevenueBonusTemplate.java b/src/rails/algorithms/RevenueBonusTemplate.java index 69b535f..2da0504 100644 --- a/src/rails/algorithms/RevenueBonusTemplate.java +++ b/src/rails/algorithms/RevenueBonusTemplate.java @@ -6,7 +6,6 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; @@ -15,13 +14,14 @@ import rails.game.Phase; import rails.game.PhaseManager; import rails.game.TrainManager; import rails.game.TrainType; +import rails.game.state.Configurable; /** * defines a template for a revenue bonus at creation time of rails objects * will be converted to a true RevenueBonus object during each revenue calculation * @author freystef */ -public final class RevenueBonusTemplate implements ConfigurableComponent { +public final class RevenueBonusTemplate implements Configurable { protected static Logger log = LoggerFactory.getLogger(RevenueBonusTemplate.class.getPackage().getName()); diff --git a/src/rails/algorithms/RevenueManager.java b/src/rails/algorithms/RevenueManager.java index 6c70b91..409102a 100644 --- a/src/rails/algorithms/RevenueManager.java +++ b/src/rails/algorithms/RevenueManager.java @@ -9,12 +9,12 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.GameManager; import rails.game.state.AbstractItem; import rails.game.state.ArrayListState; +import rails.game.state.Configurable; import rails.game.state.Item; /** @@ -23,12 +23,12 @@ import rails.game.state.Item; * The conversion of Rails elements is in the responsibility of the RevenueAdapter. * For each GameManager instance only one RevenueManager is created. */ -public final class RevenueManager extends AbstractItem implements ConfigurableComponent { +public final class RevenueManager extends AbstractItem implements Configurable { protected static Logger log = LoggerFactory.getLogger(RevenueManager.class.getPackage().getName()); - private final HashSet<ConfigurableComponent> configurableModifiers = new HashSet<ConfigurableComponent>(); + private final HashSet<Configurable> configurableModifiers = new HashSet<Configurable>(); private final ArrayListState<NetworkGraphModifier> graphModifiers = ArrayListState.create(this, "graphModifiers"); private final ArrayListState<RevenueStaticModifier> staticModifiers = ArrayListState.create(this, "staticModifiers"); @@ -38,14 +38,13 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo private final ArrayList<RevenueDynamicModifier> activeDynamicModifiers = new ArrayList<RevenueDynamicModifier>(); private RevenueDynamicModifier activeCalculator; - private RevenueManager(Item parent, String id) { + /** + * Used by Configure (via reflection) only + */ + public RevenueManager(Item parent, String id) { super(parent, id); } - public static RevenueManager create(Item parent, String id){ - return new RevenueManager(parent, id); - } - public void configureFromXML(Tag tag) throws ConfigurationException { // define modifiers @@ -88,8 +87,8 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo throw new ConfigurationException(LocalText.getText( "ClassIsNotAModifier", className)); } - if (isModifier && modifier instanceof ConfigurableComponent) { - configurableModifiers.add((ConfigurableComponent)modifier); + if (isModifier && modifier instanceof Configurable) { + configurableModifiers.add((Configurable)modifier); } } } @@ -98,7 +97,7 @@ public final class RevenueManager extends AbstractItem implements ConfigurableCo public void finishConfiguration(GameManager parent) throws ConfigurationException { - for (ConfigurableComponent modifier:configurableModifiers) { + for (Configurable modifier:configurableModifiers) { modifier.finishConfiguration(parent); } } diff --git a/src/rails/common/parser/ComponentManager.java b/src/rails/common/parser/ComponentManager.java index f2607e0..89b2561 100644 --- a/src/rails/common/parser/ComponentManager.java +++ b/src/rails/common/parser/ComponentManager.java @@ -1,34 +1,35 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/ComponentManager.java,v 1.19 2010/05/18 04:12:23 stefanfrey Exp $ */ package rails.common.parser; -import java.lang.reflect.Constructor; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rails.common.LocalText; +import rails.common.parser.ConfigurationException; +import rails.common.parser.Tag; import rails.common.parser.XMLTags; -import rails.game.state.GameRoot; +import rails.game.state.Configurable; +import rails.game.state.Configure; +import rails.game.state.Context; -/** - * ComponentManage - an implementation of ComponentManagerI, which handles the - * creation and configuration of rails.game components, and acts as a discovery - * point for other components to find them. - */ public class ComponentManager { + final static Logger log = LoggerFactory.getLogger(ComponentManager.class); + private String gameName; private List<Tag> componentTags; - protected Logger log = LoggerFactory.getLogger(ComponentManager.class.getPackage().getName()); protected List<String> directories = new ArrayList<String>(); - private Map<String, ConfigurableComponent> mComponentMap = - new HashMap<String, ConfigurableComponent>(); + private Map<String, Configurable> mComponentMap = + new HashMap<String, Configurable>(); - public ComponentManager(GameRoot root, String gameName, Tag tag, Map<String, String> gameOptions) + public ComponentManager(Context context, String gameName, Tag tag, Map<String, String> gameOptions) throws ConfigurationException { this.gameName = gameName; @@ -36,12 +37,12 @@ public class ComponentManager { for (Tag component : componentTags) { String compName = component.getAttributeAsString("name"); log.debug("Found component " + compName); - configureComponent(root, component); + configureComponent(context, component); component.setGameOptions(gameOptions); } } - private void configureComponent(GameRoot root, Tag componentTag) + private void configureComponent(Context context, Tag componentTag) throws ConfigurationException { // Extract the attributes of the Component @@ -64,24 +65,7 @@ public class ComponentManager { } // Now construct the component - ConfigurableComponent component; - try { - Class<? extends ConfigurableComponent> compClass; - compClass = - Class.forName(clazz).asSubclass( - ConfigurableComponent.class); - Constructor<? extends ConfigurableComponent> compCons = - compClass.getConstructor(new Class[0]); - component = compCons.newInstance(new Object[0]); - } catch (Exception ex) { - // There are MANY things that could go wrong here. - // They all just mean that the configuration and code - // do not combine to make a well-formed system. - // Debugging aided by chaining the caught exception. - throw new ConfigurationException(LocalText.getText( - "ComponentHasNoClass", clazz), ex); - - } + Configurable component = Configure.create(Configurable.class, clazz, context, name); // Configure the component, from a file, or the embedded XML. Tag configElement = componentTag; @@ -110,8 +94,8 @@ public class ComponentManager { * @param componentName the of the component sought. * @return the component sought, or null if it has not been configured. */ - public ConfigurableComponent findComponent(String componentName) throws ConfigurationException { - ConfigurableComponent comp = mComponentMap.get(componentName); + public Configurable findComponent(String componentName) throws ConfigurationException { + Configurable comp = mComponentMap.get(componentName); //FIXME: Revenue Manager is currently optional. if (comp == null && componentName != "RevenueManager") { diff --git a/src/rails/common/parser/ConfigurableComponent.java b/src/rails/common/parser/ConfigurableComponent.java deleted file mode 100644 index 02e67f1..0000000 --- a/src/rails/common/parser/ConfigurableComponent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/ConfigurableComponentI.java,v 1.7 2009/10/31 17:08:26 evos Exp $ */ -package rails.common.parser; - -import rails.game.GameManager; - -/** - * Interface for rails.game components which can be configured from an XML - * element. - */ -public interface ConfigurableComponent { - - /** - * Instructs the component to configure itself from the provided XML - * element. - * - * @param element the XML element containing the configuration - * @throws ConfigurationException - */ - void configureFromXML(Tag tag) throws ConfigurationException; - - /** - * This method is intended to be called for each configurable - * component, to perforn any initialisation activities that - * require any other components to be initialised first. - * This includes creating any required relationships to other - * configured components and objects. - * <p>This method should be called where necessary after all - * XML file parsing has completed, so that all objects that - * need to be related to do exist. - * @param parent The 'parent' configurable component is passed to allow - * the 'child' to access any other object without the need to resort to - * static calls where possible. - */ - void finishConfiguration (GameManager parent) - throws ConfigurationException; - -} diff --git a/src/rails/common/parser/GameFileParser.java b/src/rails/common/parser/GameFileParser.java index d59b9aa..eea0f0f 100644 --- a/src/rails/common/parser/GameFileParser.java +++ b/src/rails/common/parser/GameFileParser.java @@ -3,11 +3,10 @@ package rails.common.parser; import java.util.Map; import rails.algorithms.RevenueManager; -import rails.common.parser.ComponentManager; import rails.game.Bank; import rails.game.CompanyManager; import rails.game.GameManager; -import rails.game.GameRoot; +import rails.game.RailsRoot; import rails.game.MapManager; import rails.game.PhaseManager; import rails.game.PlayerManager; @@ -32,7 +31,7 @@ public class GameFileParser extends XMLParser { private final RevenueManager revenueManager; private final Bank bank; - public GameFileParser(GameRoot root, String name, Map<String, String> gameOptions) + public GameFileParser(RailsRoot root, String name, Map<String, String> gameOptions) throws ConfigurationException { directories.add("data/" + name); diff --git a/src/rails/game/Bank.java b/src/rails/game/Bank.java index 5646bff..4f479fd 100644 --- a/src/rails/game/Bank.java +++ b/src/rails/game/Bank.java @@ -7,17 +7,17 @@ import org.slf4j.LoggerFactory; import rails.common.LocalText; import rails.common.parser.Config; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.model.CashMoneyModel; import rails.game.model.CashOwner; import rails.game.state.AbstractItem; import rails.game.state.BooleanState; +import rails.game.state.Configurable; import rails.game.state.Item; import rails.util.*; -public class Bank extends AbstractItem implements CashOwner, ConfigurableComponent { +public class Bank extends AbstractItem implements CashOwner, Configurable { private static Bank instance = null; @@ -55,7 +55,10 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone protected static Logger log = LoggerFactory.getLogger(Bank.class.getPackage().getName()); - protected Bank(Item parent, String id) { + /** + * Used by Configure (via reflection) only + */ + public Bank(Item parent, String id) { super(parent, id); instance = this; @@ -65,12 +68,8 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone } } - public static Bank create(Item parent, String id) { - return new Bank(parent, id); - } - /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { @@ -116,10 +115,9 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone for (PublicCompany comp : companies) { for (PublicCertificate cert : comp.getCertificates()) { if (cert.isInitiallyAvailable()) { - // TODO: Make this shorter - ipo.getPortfolioModel().getShareModel(comp).getPortfolio().moveInto(cert); + cert.moveTo(ipo); } else { - unavailable.getPortfolioModel().getShareModel(comp).getPortfolio().moveInto(cert); + cert.moveTo(unavailable); } } } @@ -187,8 +185,7 @@ public class Bank extends AbstractItem implements CashOwner, ConfigurableCompone } public CashMoneyModel getCashModel() { - // TODO Auto-generated method stub - return null; + return cash; } } diff --git a/src/rails/game/BaseToken.java b/src/rails/game/BaseToken.java index d2ccde2..d1c5142 100644 --- a/src/rails/game/BaseToken.java +++ b/src/rails/game/BaseToken.java @@ -10,10 +10,10 @@ package rails.game; */ // FIXME: Check if PublicCompany is the parent of a token -public final class BaseToken extends Token { +public class BaseToken extends Token<BaseToken> { private BaseToken(PublicCompany parent, String id) { - super(parent, id); + super(parent, id, BaseToken.class); } public static BaseToken create(PublicCompany company) { @@ -34,11 +34,5 @@ public final class BaseToken extends Token { public String getId() { return getParent().getId(); } - - @Override - public String toString() { - return getId(); - } - } diff --git a/src/rails/game/BonusToken.java b/src/rails/game/BonusToken.java index a68a3d2..5341cf2 100644 --- a/src/rails/game/BonusToken.java +++ b/src/rails/game/BonusToken.java @@ -1,8 +1,9 @@ package rails.game; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; +import rails.game.state.Configurable; +import rails.game.state.Item; import rails.util.Util; /** @@ -12,8 +13,7 @@ import rails.util.Util; * which are intended for base tokens, but on some unoccupied part of a tile. */ -//FIXME: Check if PublicCompany is the parent of a token -public final class BonusToken extends Token implements Closeable, ConfigurableComponent { +public class BonusToken extends Token<BonusToken> implements Closeable, Configurable { private int value; private String name; @@ -21,13 +21,13 @@ public final class BonusToken extends Token implements Closeable, ConfigurableCo private Object removingObject = null; private PublicCompany user = null; - private BonusToken(PublicCompany parent, String id) { - super(parent, id); + private BonusToken(Item parent, String id) { + super(parent, id, BonusToken.class); } - public static BonusToken create(PublicCompany company) { + public static BonusToken create(Item parent) { String uniqueId = Token.createUniqueId(); - BonusToken token = new BonusToken(company, uniqueId); + BonusToken token = new BonusToken(parent, uniqueId); return token; } diff --git a/src/rails/game/Company.java b/src/rails/game/Company.java index 4815807..99ac8fe 100644 --- a/src/rails/game/Company.java +++ b/src/rails/game/Company.java @@ -7,18 +7,18 @@ import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableSet; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.special.SpecialProperty; import rails.game.state.BooleanState; import rails.game.state.AbstractItem; +import rails.game.state.Configurable; +import rails.game.state.Configure; import rails.game.state.Item; import rails.game.state.Owner; -import rails.game.state.PortfolioSet; import rails.util.Util; -public abstract class Company extends AbstractItem implements Owner, ConfigurableComponent, +public abstract class Company extends AbstractItem implements Owner, Configurable, Cloneable, Comparable<Company> { /** The name of the XML tag used to configure a company. */ @@ -52,10 +52,6 @@ Cloneable, Comparable<Company> { /** Closed state */ protected final BooleanState closedObject = BooleanState.create(this, "closed", false); - // Moved here from PrivayeCOmpany on behalf of 1835 - protected final PortfolioSet<SpecialProperty> specialProperties = - PortfolioSet.create(this, "specialProperties", SpecialProperty.class); - protected static Logger log = LoggerFactory.getLogger(Company.class.getPackage().getName()); @@ -81,42 +77,17 @@ Cloneable, Comparable<Company> { if (!Util.hasValue(className)) throw new ConfigurationException( "Missing class in private special property"); - SpecialProperty sp = null; - try { - sp = (SpecialProperty) Class.forName(className).newInstance(); - } catch (Exception e) { - log.error ("Cannot instantiate "+className, e); - System.exit(-1); - } + String uniqueId = SpecialProperty.createUniqueId(); + SpecialProperty sp = Configure.create(SpecialProperty.class, className, this, uniqueId); + sp.setOriginalCompany(this); sp.configureFromXML(spTag); - specialProperties.moveInto(sp); + sp.moveTo(this); parentInfoText += "<br>" + sp.getInfo(); } } } /** - * @return Set of all special properties we have. - */ - public ImmutableSet<SpecialProperty> getSpecialProperties() { - return specialProperties.items(); - } - - /** - * Do we have any special properties? - * - * @return Boolean - */ - public boolean hasSpecialProperties() { - return specialProperties != null && !specialProperties.isEmpty(); - } - - public boolean hasPortfolio() { - return true; - } - - - /** * * @return This company's number */ @@ -199,27 +170,11 @@ Cloneable, Comparable<Company> { value = i; } - // TODO: Check if this is still required, moved to subclasses -/* public Portfolio getHolder() { - return portfolio; - } -*/ - @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } - /** - * Stub method implemented to comply with HolderModel<Token>I interface. Always - * returns false. - * - * Use addToken(MapHex hex) method instead. - */ - public boolean addToken(Company company, int position) { - return false; - } - @Override public String toString() { return getTypeName() + ": " + getCompanyNumber() + ". " + getId() @@ -255,4 +210,11 @@ Cloneable, Comparable<Company> { } return b.toString(); } + + // Since 1835 required for both private and public companies + /** + * @return Set of all special properties we have. + */ + public abstract ImmutableSet<SpecialProperty> getSpecialProperties(); + } diff --git a/src/rails/game/CompanyManager.java b/src/rails/game/CompanyManager.java index 64c820a..70b173d 100644 --- a/src/rails/game/CompanyManager.java +++ b/src/rails/game/CompanyManager.java @@ -9,13 +9,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rails.common.LocalText; -import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; +import rails.game.state.Configurable; import rails.game.state.Item; -public class CompanyManager extends AbstractItem implements ConfigurableComponent { +public class CompanyManager extends AbstractItem implements Configurable { /** * This is the name by which the CompanyManager should be registered with @@ -63,7 +63,10 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen protected GameManager gameManager; - protected CompanyManager(Item parent, String id) { + /** + * Used by Configure (via reflection) only + */ + public CompanyManager(Item parent, String id) { super(parent, id); } @@ -75,7 +78,7 @@ public class CompanyManager extends AbstractItem implements ConfigurableComponen */ /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { diff --git a/src/rails/game/CompanyType.java b/src/rails/game/CompanyType.java index 8025848..96d86f1 100644 --- a/src/rails/game/CompanyType.java +++ b/src/rails/game/CompanyType.java @@ -7,6 +7,7 @@ import rails.common.LocalText; import rails.common.parser.ConfigurationException; import rails.common.parser.Tag; import rails.game.state.AbstractItem; +import rails.game.state.Configure; import rails.game.state.Item; /** @@ -58,7 +59,7 @@ public class CompanyType extends AbstractItem { } /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { //No longer needed. @@ -68,16 +69,16 @@ public class CompanyType extends AbstractItem { } - public Company createCompany(String name, Tag typeTag, Tag tag) + public Company createCompany(String id, Tag typeTag, Tag tag) throws ConfigurationException { Company newCompany = null; try { - newCompany = (Company) Class.forName(className).newInstance(); + newCompany = Configure.create(Company.class, className, this, id); } catch (Exception e) { throw new ConfigurationException(LocalText.getText( "ClassCannotBeInstantiated", className), e); } - // newCompany.init(this, name); + newCompany.initType(this); newCompany.configureFromXML(typeTag); newCompany.configureFromXML(tag); companies.add(newCompany); diff --git a/src/rails/game/EndOfGameRound.java b/src/rails/game/EndOfGameRound.java index aa4773d..8b5fd34 100644 --- a/src/rails/game/EndOfGameRound.java +++ b/src/rails/game/EndOfGameRound.java @@ -13,16 +13,15 @@ import rails.common.LocalText; public final class EndOfGameRound extends Round { - public EndOfGameRound(GameManager parent, String id) { + /** + * Constructed via Configure + */ + public EndOfGameRound(GameManager parent, String id) { super(parent, id); guiHints.setVisibilityHint(GuiDef.Panel.MAP, true); guiHints.setActivePanel(GuiDef.Panel.STATUS); } - public static EndOfGameRound create(GameManager parent, String id) { - return new EndOfGameRound(parent, id); - } - @Override public boolean setPossibleActions() { possibleActions.clear(); diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index b196d46..dd0e3e9 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -19,15 +19,11 @@ import rails.game.state.*; import rails.util.GameFileIO; import rails.util.Util; -/* - * FIXME: Removed NDC mechanism - */ - /** * This class manages the playing rounds by supervising all implementations of * Round. Currently everything is hardcoded à la 1830. */ -public class GameManager extends AbstractItem implements ConfigurableComponent, Owner { +public class GameManager extends Manager implements Configurable, Owner { /** Version ID of the Save file header, as written in save() */ private static final long saveFileHeaderVersionID = 3L; /** @@ -229,13 +225,10 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, protected static Logger log = LoggerFactory.getLogger(GameManager.class.getPackage().getName()); - // FIXME: This has to be rewritten - public GameManager() { - super(null, GM_NAME); // TODO: fix that + public GameManager(Item parent, String id) { + super(parent, id); gmName = GM_NAME; gmKey = GM_KEY; -// NDC.clear(); -// NDC.push (GM_KEY); gameManagerMap.put(GM_KEY, this); displayBuffer = new DisplayBuffer(); reportBuffer = new ReportBuffer(); @@ -618,7 +611,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, */ public static GameManager getInstance () { // return gameManagerMap.get(NDC.peek()); - return null; + return gameManagerMap.get(GM_KEY); } /* (non-Javadoc) @@ -692,20 +685,12 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, protected void startStartRound() { String startRoundClassName = startPacket.getRoundClassName(); - Class<? extends StartRound> startRoundClass = null; - try { - startRoundClass = Class.forName (startRoundClassName).asSubclass(StartRound.class); - } catch (Exception e) { - log.error("Cannot find class " - + startRoundClassName, e); - System.exit(1); - } - StartRound startRound = createRound (startRoundClass); - startRound.start (); + StartRound startRound = createRound(StartRound.class, startRoundClassName, "startRound"); + startRound.start(); } protected void startStockRound() { - StockRound sr = createRound (stockRoundClass); + StockRound sr = createRound(stockRoundClass, "SR_" + srNumber.value()); srNumber.add(1); sr.start(); } @@ -713,17 +698,16 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, protected void startOperatingRound(boolean operate) { log.debug("Operating round started with operate-flag=" + operate); - OperatingRound or = createRound(operatingRoundClass); + OperatingRound or = createRound(operatingRoundClass, "OR_" + absoluteORNumber.value()); if (operate) absoluteORNumber.add(1); or.start(); } - protected <T extends Round> T createRound (Class<T> roundClass) { - + // FIXME: We need an ID! + protected <T extends Round> T createRound (Class<T> roundClass, String roundClassName, String id) { T round = null; try { - Constructor<T> cons = roundClass.getConstructor(GameManager.class); - round = cons.newInstance(this); + round = Configure.create(roundClass, roundClassName, GameManager.class, this, id); } catch (Exception e) { log.error("Cannot instantiate class " + roundClass.getName(), e); @@ -732,18 +716,12 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, setRound (round); return round; } - - protected <T extends Round, U extends Round> - T createRound (Class<T> roundClass, U parentRound) { - - if (parentRound == null) { - return createRound (roundClass); - } - + + // FIXME: We need an ID! + protected <T extends Round> T createRound(Class<T> roundClass, String id) { T round = null; try { - Constructor<T> cons = roundClass.getConstructor(GameManager.class, Round.class); - round = cons.newInstance(this, parentRound); + round = Configure.create(roundClass, GameManager.class, this, id); } catch (Exception e) { log.error("Cannot instantiate class " + roundClass.getName(), e); @@ -801,20 +779,17 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, interruptedRound = getCurrentRound(); // check if other companies can be dumped - createRound (shareSellingRoundClass, interruptedRound) - .start(player, cashToRaise, cashNeedingCompany, + // FIXME: This ID will not work, as it will create duplication + createRound(shareSellingRoundClass, "ShareSellingRound").start( + interruptedRound, player, cashToRaise, cashNeedingCompany, !problemDumpOtherCompanies || forcedSellingCompanyDump); // the last parameter indicates if the dump of other companies is allowed, either this is explicit or // the action does not require that check } - /* (non-Javadoc) - * @see rails.game.GameManager#startTreasuryShareTradingRound(rails.game.OperatingRound, rails.game.PublicCompany) - */ public void startTreasuryShareTradingRound() { - interruptedRound = getCurrentRound(); - createRound (TreasuryShareRound.class, interruptedRound).start(); + createRound (TreasuryShareRound.class, "TreasuryShareRound").start(interruptedRound); } /* (non-Javadoc) @@ -1351,7 +1326,8 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, // activate gameReport for UI setGameOverReportedUI(false); - createRound(EndOfGameRound.class); + // FIXME: This will not work, as it will create duplicated IDs + createRound(EndOfGameRound.class, "EndOfGameRound"); } diff --git a/src/rails/game/GameRoot.java b/src/rails/game/GameRoot.java deleted file mode 100644 index d186dad..0000000 --- a/src/rails/game/GameRoot.java +++ /dev/null @@ -1,306 +0,0 @@ -package rails.game; - -import java.io.*; -import java.util.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import rails.algorithms.RevenueManager; -import rails.common.DisplayBuffer; -import rails.common.LocalText; -import rails.common.parser.*; -import rails.game.action.PossibleAction; -import rails.game.state.Root; -import rails.util.GameFileIO; - -public class GameRoot extends Root { - public static final String version = "1.5"; - - /** The component Manager */ - protected GameManager gameManager; - protected CompanyManager companyManager; - protected PlayerManager playerManager; - protected PhaseManager phaseManager; - protected TrainManager trainManager; - protected StockMarket stockMarket; - protected MapManager mapManager; - protected TileManager tileManager; - protected RevenueManager revenueManager; - protected Bank bank; - protected String name; - - protected List<String> directories = new ArrayList<String>(); - protected List<String> players; - - protected Map<String, String> gameOptions; - - protected static Logger log = - LoggerFactory.getLogger(GameRoot.class.getPackage().getName()); - - public GameRoot(String name, List<String> players, Map<String, String> options) { - super(); // initialize root - - this.name = name; - this.gameOptions = options; - - gameOptions.put(GameOption.NUMBER_OF_PLAYERS, - String.valueOf(players.size())); - - for (String playerName : players) { - log.debug("Player: " + playerName); - } - for (String optionName : gameOptions.keySet()) { - log.debug("Option: " + optionName + "=" - + gameOptions.get(optionName)); - } - - - this.players = players; - - log.info("========== Start of rails.game " + name + " =========="); - log.info("Rails version "+version); - ReportBuffer.add(LocalText.getText("GameIs", name)); - } - - public String start() { - - if (players.size() < playerManager.minPlayers - || players.size() > playerManager.maxPlayers) { - return name+" is not configured to be played with "+players.size()+" players\n" - + "Please enter a valid number of players, or add a <Players> entry to data/"+name+"/Game.xml"; - } - - gameManager.startGame(gameOptions); - return null; - } - - public boolean setup() { - GameFileParser gfp; - try{ - gfp = new GameFileParser(this, name, gameOptions); - } catch (Exception e) { - String message = - LocalText.getText("GameSetupFailed", GameFileParser.GAME_XML_FILE); - log.error(message, e); - System.out.println(e.getMessage()); - e.printStackTrace(); - DisplayBuffer.add(message + ":\n " + e.getMessage()); - return false; - } - - playerManager = gfp.getPlayerManager(); - companyManager = gfp.getCompanyManager(); - trainManager = gfp.getTrainManager(); - phaseManager = gfp.getPhaseManager(); - stockMarket = gfp.getStockMarket(); - mapManager = gfp.getMapManager(); - tileManager = gfp.getTileManager(); - revenueManager = gfp.getRevenueManager(); - bank = gfp.getBank(); - gameManager = gfp.getGameManager(); - - /* - * Initializations that involve relations between components can - * only be done after all XML has been processed. - */ - playerManager.setPlayers(players, bank); - gameManager.init(name, playerManager, companyManager, - phaseManager, trainManager, stockMarket, mapManager, - tileManager, revenueManager, bank); - - try { - companyManager.finishConfiguration(gameManager); - trainManager.finishConfiguration(gameManager); - phaseManager.finishConfiguration(gameManager); - tileManager.finishConfiguration(gameManager); - mapManager.finishConfiguration(gameManager); - bank.finishConfiguration(gameManager); - stockMarket.finishConfiguration(gameManager); - - if (revenueManager != null) - revenueManager.finishConfiguration(gameManager); - } catch (ConfigurationException e) { - log.error(e.getMessage()); - System.out.println(e.getMessage()); - e.printStackTrace(); - DisplayBuffer.add(e.getMessage()); - return false; - } - - return true; - } - - - public static GameRoot load(String filepath) { - - // use GameLoader object to load game - GameFileIO gameLoader = new GameFileIO(); - gameLoader.loadGameData(filepath); - try{ - gameLoader.initGame(); - gameLoader.loadActionsAndComments(); - } catch (ConfigurationException e) { - log.error("Load failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - try{ - gameLoader.replayGame(); - } catch (Exception e) { - log.error("Replay failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - - return gameLoader.getGame(); - } - - @SuppressWarnings("unchecked") - public static GameRoot load_old(String filepath) { - - GameRoot game = null; - - log.debug("Loading game from file " + filepath); - String filename = filepath.replaceAll(".*[/\\\\]", ""); - - /*--- Remember to keep GameManager.reload() in sync with this code! ---*/ - try { - ObjectInputStream ois = - new ObjectInputStream(new FileInputStream( - new File(filepath))); - - // New in 1.0.7: Rails version & save date/time. - // Allow for older saved file versions. - Object object = ois.readObject(); - if (object instanceof String) { - log.info("Reading Rails "+(String)object+" saved file "+filename); - object = ois.readObject(); - } else { - log.info("Reading Rails (pre-1.0.7) saved file "+filename); - } - if (object instanceof String) { - log.info("File was saved at "+(String)object); - object = ois.readObject(); - } - - long versionID = (Long) object; - log.debug("Saved versionID="+versionID+" (object="+object+")"); - long saveFileVersionID = GameManager.saveFileVersionID; - if (versionID != saveFileVersionID) { - throw new Exception("Save version " + versionID - + " is incompatible with current version " - + saveFileVersionID); - } - String name = (String) ois.readObject(); - log.debug("Saved game="+name); - Map<String, String> selectedGameOptions = - (Map<String, String>) ois.readObject(); - List<String> playerNames = (List<String>) ois.readObject(); - - game = new GameRoot(name, playerNames, selectedGameOptions); - - if (!game.setup()) { - throw new ConfigurationException("Error in setting up " + name); - } - - String startError = game.start(); - if (startError != null) { - DisplayBuffer.add(startError); - return null; - } - GameManager gameManager = game.getGameManager(); - - log.debug("Starting to execute loaded actions"); - - gameManager.setReloading(true); - - Object actionObject = null; - int actionIndex = 0; - - while (true) { // Single-pass loop. - try { - actionObject = ois.readObject(); - } catch (EOFException e) { - // Allow saved file at start of game (with no actions). - break; - } - if (actionObject instanceof List) { - // Old-style: one List of PossibleActions - List<PossibleAction> executedActions = - (List<PossibleAction>) actionObject; - for (PossibleAction action : executedActions) { - ++actionIndex; - try { - if (!gameManager.processOnReload(action)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted")); - break; - } - } catch (Exception e) { - log.error("Action "+actionIndex+" '"+action+"' reload exception", e); - throw new Exception ("Reload exception", e); - } - } - } else if (actionObject instanceof PossibleAction) { - // New style: separate PossibleActionsObjects, since Rails 1.3.1 - while (actionObject instanceof PossibleAction) { - ++actionIndex; - try { - if (!gameManager.processOnReload((PossibleAction)actionObject)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted")); - break; - } - } catch (Exception e) { - log.error("Action "+actionIndex+" '"+((PossibleAction)actionObject).toString() - +"' reload exception", e); - throw new Exception ("Reload exception", e); - } - try { - actionObject = ois.readObject(); - } catch (EOFException e) { - break; - } - } - } - break; - } - - // load user comments (is the last - if (actionObject instanceof SortedMap) { - ReportBuffer.setCommentItems((SortedMap<Integer, String>) actionObject); - log.debug("Found sorted map"); - } else { - try { - object = ois.readObject(); - if (object instanceof SortedMap) { - ReportBuffer.setCommentItems((SortedMap<Integer, String>) object); - } - } catch (IOException e) { - // continue without comments, if any IOException occurs - // sometimes not only the EOF Exception is raised - // but also the java.io.StreamCorruptedException: invalid type code - } - } - - ois.close(); - ois = null; - - gameManager.setReloading(false); - gameManager.finishLoading(); - return game; - - } catch (Exception e) { - log.error("Load failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - - return null; - } - - /*----- Getters -----*/ - - public GameManager getGameManager() { - return gameManager; - } - -} diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 17e3c65..b20fa42 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -7,7 +7,10 @@ import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; import rails.algorithms.RevenueBonusTemplate; import rails.common.LocalText; @@ -22,9 +25,9 @@ import rails.game.model.CashMoneyModel; import rails.game.model.PortfolioModel; import rails.game.state.BooleanState; +import rails.game.state.Configurable; import rails.game.state.Observer; import rails.game.state.Owner; -import rails.game.state.Portfolio; import rails.game.state.PortfolioSet; import rails.game.state.AbstractItem; import rails.util.*; @@ -58,7 +61,7 @@ import rails.util.*; */ // FIXME: MapHex was previous a model -public class MapHex extends AbstractItem implements Owner, ConfigurableComponent, +public class MapHex extends AbstractItem implements Owner, Configurable, StationHolder { private static final String[] ewOrNames = @@ -126,8 +129,10 @@ StationHolder { protected List<PublicCompany> destinations; /** Tokens that are not bound to a Station (City), such as Bonus tokens */ - protected final PortfolioSet<Token> offStationTokens = PortfolioSet.create(this, - "offStationTokens", Token.class); + protected final PortfolioSet<BonusToken> bonusTokens = PortfolioSet.create(this, "bonusTokens", BonusToken.class); + + protected final PortfolioSet<BaseToken> offStationTokens = PortfolioSet.create(this, + "offStationTokens", BaseToken.class); /** Storage of revenueBonus that are bound to the hex */ protected List<RevenueBonusTemplate> revenueBonuses = null; @@ -181,14 +186,15 @@ StationHolder { } public static MapHex create(MapManager parent, Tag tag) throws ConfigurationException { - // TODO: Rewrite the creation process of MapHex - MapHex hex = new MapHex(parent, null); + // name serves as id + String id = tag.getAttributeAsString("name"); + MapHex hex = new MapHex(parent, id); hex.configureFromXML(tag); return hex; } /** - * @see rails.common.parser.ConfigurableComponent#configureFromXML(org.w3c.dom.Element) + * @see rails.game.state.Configurable#configureFromXML(org.w3c.dom.Element) */ public void configureFromXML(Tag tag) throws ConfigurationException { Pattern namePattern = Pattern.compile("(\\D+?)(-?\\d+)"); @@ -802,51 +808,40 @@ StationHolder { } // Move the tokens - Map<Token, Portfolio<Token>> tokenDestinations = - new HashMap<Token, Portfolio<Token>>(); - + Map<BaseToken, Owner> tokenDestinations = Maps.newHashMap(); for (Stop oldCity : stops) { newCity = oldToNewCities.get(oldCity); if (newCity != null) { - oldtoken: for (Token token : oldCity.getTokens()) { - if (token instanceof BaseToken) { - // Check if the new city already has such a token - PublicCompany company = - ((BaseToken) token).getParent(); - for (Token token2 : newCity.getTokens()) { - if (token2 instanceof BaseToken - && company == ((BaseToken) token2).getOwner()) { - // No duplicate tokens in one city, so move to free tokens - tokenDestinations.put(token, company.getBaseTokensModel().getFreeTokens()); - log.debug("Duplicate token " - + token.getUniqueId() - + " moved from " - + oldCity.getId() + " to " - + company.getId()); - ReportBuffer.add(LocalText.getText( - "DuplicateTokenRemoved", - company.getId(), - getId() )); - continue oldtoken; - } + oldtoken: for (BaseToken token : oldCity.getBaseTokens()) { + // Check if the new city already has such a token + PublicCompany company = token.getParent(); + for (BaseToken token2 : newCity.getBaseTokens()) { + if (company == token2.getOwner()) { + // No duplicate tokens in one city, so move to free tokens + tokenDestinations.put(token, company); + log.debug("Duplicate token " + + token.getUniqueId() + + " moved from " + + oldCity.getId() + " to " + + company.getId()); + ReportBuffer.add(LocalText.getText( + "DuplicateTokenRemoved", + company.getId(), + getId() )); + continue oldtoken; } } - tokenDestinations.put(token, newCity.getTokens()); + tokenDestinations.put(token, newCity); log.debug("Token " + token.getUniqueId() + " moved from " + oldCity.getId() + " to " + newCity.getId()); } - if (!tokenDestinations.isEmpty()) { - for (Token token : tokenDestinations.keySet()) { - tokenDestinations.get(token).moveInto(token); - } } - } else { - log.debug("No new city!?"); - } - } - + // TODO: Move that after the for-loop, check if this still works + for (BaseToken token : tokenDestinations.keySet()) { + token.moveTo(tokenDestinations.get(token)); + } } // TODO: Check as the code below was not reachable @@ -920,7 +915,7 @@ StationHolder { ... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-08-19 20:21:51
|
junit/rails/game/state/ActionChangeSetTest.java | 82 ----- junit/rails/game/state/AutoChangeSetTest.java | 68 ---- junit/rails/game/state/BlockingChangeSetTest.java | 71 +++++ junit/rails/game/state/BooleanStateTest.java | 4 junit/rails/game/state/ChangeStackTest.java | 66 ++-- junit/rails/game/state/GameChangeSetTest.java | 68 ++++ junit/rails/game/state/GenericStateTest.java | 4 junit/rails/game/state/HashMapStateTest.java | 12 junit/rails/game/state/IntegerStateTest.java | 2 junit/rails/game/state/StateTestUtils.java | 2 junit/rails/game/state/StringStateTest.java | 8 src/rails/common/parser/ComponentManager.java | 8 src/rails/common/parser/GameFileParser.java | 71 ++--- src/rails/game/ActionChangeSet.java | 31 ++ src/rails/game/Game.java | 297 --------------------- src/rails/game/GameRoot.java | 306 ++++++++++++++++++++++ src/rails/game/PlayerManager.java | 4 src/rails/game/state/AbstractItem.java | 10 src/rails/game/state/ActionChangeSet.java | 36 -- src/rails/game/state/AutoChangeSet.java | 26 - src/rails/game/state/ChangeSet.java | 93 ++++-- src/rails/game/state/ChangeStack.java | 171 ++++++------ src/rails/game/state/Context.java | 23 - src/rails/game/state/GameRoot.java | 23 + src/rails/game/state/Item.java | 2 src/rails/game/state/Manager.java | 10 src/rails/game/state/Observable.java | 10 src/rails/game/state/Root.java | 7 src/rails/game/state/StateManager.java | 7 src/rails/ui/swing/GameSetupWindow.java | 8 src/rails/util/GameFileIO.java | 14 - src/rails/util/RunGame.java | 6 src/test/TestGame.java | 4 src/test/TestGameBuilder.java | 6 34 files changed, 771 insertions(+), 789 deletions(-) New commits: commit 0485c9f83aa5a2a1e32be447657e15020f15c088 Author: Stefan Frey <ste...@we...> Date: Tue Jul 31 19:14:04 2012 +0200 Added StateManagerTest and ModelTest Refactored StateManager topological sorting Refactored ChangeSets Started Rewriting Managers etc. diff --git a/junit/rails/game/state/ActionChangeSetTest.java b/junit/rails/game/state/ActionChangeSetTest.java deleted file mode 100644 index dd388ec..0000000 --- a/junit/rails/game/state/ActionChangeSetTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package rails.game.state; - -import static org.fest.assertions.api.Assertions.assertThat; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -import org.junit.*; -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 ActionChangeSetTest { - - private final static String STATE_ID = "State"; - - private Root root; - private BooleanState state; - @Mock Model model; - private ChangeStack changeStack; - @Mock Player player; - @Mock PossibleAction action; - private ActionChangeSet changeSet; - - - @Before - public void setUp() { - root = Root.create(); - state = BooleanState.create(root, STATE_ID); - state.addModel(model); - changeStack = root.getStateManager().getChangeStack(); - changeSet = changeStack.startActionChangeSet(player, action); - } - - @Test - public void testActionChangeSet() { - assertNotNull(changeSet); - } - - @Test - public void testGetPlayer() { - assertSame(player, changeSet.getPlayer()); - } - - @Test - public void testGetAction() { - assertSame(action, changeSet.getAction()); - } - - @Test - public void testAddChange() { - assertTrue(changeSet.isEmpty()); - state.set(true); - assertFalse(changeSet.isEmpty()); - verify(model).update(); - } - - @Test - public void testClose() { - assertFalse(changeSet.isClosed()); - state.set(true); - changeSet.close(); - assertTrue(changeSet.isClosed()); - assertThat(changeSet.getStates()).contains(state); - } - - @Test - public void testUnAndReexecute() { - assertFalse(state.value()); - state.set(true); - assertTrue(state.value()); - changeSet.close(); - changeSet.unexecute(); - assertFalse(state.value()); - changeSet.reexecute(); - assertTrue(state.value()); - } - -} diff --git a/junit/rails/game/state/AutoChangeSetTest.java b/junit/rails/game/state/AutoChangeSetTest.java deleted file mode 100644 index 83aee84..0000000 --- a/junit/rails/game/state/AutoChangeSetTest.java +++ /dev/null @@ -1,68 +0,0 @@ -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 AutoChangeSetTest { - - private final static String STATE_ID = "State"; - - private Root root; - private BooleanState state; - @Mock Model model; - private ChangeStack changeStack; - private AutoChangeSet changeSet; - - - @Before - public void setUp() { - root = Root.create(); - state = BooleanState.create(root, STATE_ID); - state.addModel(model); - changeStack = root.getStateManager().getChangeStack(); - changeSet = changeStack.closeCurrentChangeSet(); - } - - @Test - public void testAutoChangeSet() { - assertNotNull(changeSet); - } - - @Test - public void testAddChange() { - assertTrue(changeSet.isEmpty()); - state.set(true); - assertFalse(changeSet.isEmpty()); - verify(model).update(); - } - - @Test - public void testClose() { - assertFalse(changeSet.isClosed()); - state.set(true); - changeSet.close(); - assertTrue(changeSet.isClosed()); - assertThat(changeSet.getStates()).contains(state); - } - - @Test - public void testUnAndReexecute() { - assertFalse(state.value()); - state.set(true); - assertTrue(state.value()); - changeSet.close(); - changeSet.unexecute(); - assertFalse(state.value()); - changeSet.reexecute(); - assertTrue(state.value()); - } -} diff --git a/junit/rails/game/state/BlockingChangeSetTest.java b/junit/rails/game/state/BlockingChangeSetTest.java new file mode 100644 index 0000000..4c7bc51 --- /dev/null +++ b/junit/rails/game/state/BlockingChangeSetTest.java @@ -0,0 +1,71 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.junit.*; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import rails.game.state.BooleanState; +import rails.game.state.ChangeStack; +import rails.game.state.Model; +import rails.game.state.Root; + +@RunWith(MockitoJUnitRunner.class) +public class BlockingChangeSetTest { + + private final static String STATE_ID = "State"; + + private Root root; + private BooleanState state; + @Mock Model model; + private ChangeStack changeStack; + private ChangeSet changeSet; + + @Before + public void setUp() { + root = Root.create(); + state = BooleanState.create(root, STATE_ID); + state.addModel(model); + changeStack = root.getStateManager().getChangeStack(); + changeSet = changeStack.startChangeSet(new ChangeSet(true, false)); + } + + @Test + public void testActionChangeSet() { + assertNotNull(changeSet); + } + + @Test + public void testAddChange() { + assertTrue(changeSet.isEmpty()); + state.set(true); + assertFalse(changeSet.isEmpty()); + verify(model).update(); + } + + @Test + public void testClose() { + assertFalse(changeSet.isClosed()); + state.set(true); + changeSet.close(); + assertTrue(changeSet.isClosed()); + assertThat(changeSet.getObservableStates()).contains(state); + } + + @Test + public void testUnAndReexecute() { + assertFalse(state.value()); + state.set(true); + assertTrue(state.value()); + changeSet.close(); + changeSet.unexecute(); + assertFalse(state.value()); + changeSet.reexecute(); + assertTrue(state.value()); + } + +} diff --git a/junit/rails/game/state/BooleanStateTest.java b/junit/rails/game/state/BooleanStateTest.java index d531aa8..7eb25ed 100644 --- a/junit/rails/game/state/BooleanStateTest.java +++ b/junit/rails/game/state/BooleanStateTest.java @@ -43,7 +43,7 @@ public class BooleanStateTest { stateDefault.set(false); stateInit.set(true); StateTestUtils.close(root); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).doesNotContain(stateDefault, stateInit); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).doesNotContain(stateDefault, stateInit); } @Test @@ -52,7 +52,7 @@ public class BooleanStateTest { stateDefault.set(true); assertTrue(stateDefault.value()); StateTestUtils.close(root); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).contains(stateDefault); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).contains(stateDefault); StateTestUtils.undo(root); assertFalse(stateDefault.value()); StateTestUtils.redo(root); diff --git a/junit/rails/game/state/ChangeStackTest.java b/junit/rails/game/state/ChangeStackTest.java index 3b24122..fbd2663 100644 --- a/junit/rails/game/state/ChangeStackTest.java +++ b/junit/rails/game/state/ChangeStackTest.java @@ -1,17 +1,14 @@ package rails.game.state; -import static org.junit.Assert.*; +import static org.fest.assertions.api.Fail.failBecauseExceptionWasNotThrown; import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; 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 { @@ -21,24 +18,26 @@ public class ChangeStackTest { 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; + private ChangeSet auto_1, auto_2, auto_3; + private ChangeSet action_1, action_2, action_3; + private ChangeSet startActionChangeSet() { + return changeStack.startChangeSet(new ChangeSet(true, false)); + } + @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_1 = changeStack.getCurrentChangeSet(); + action_1 = startActionChangeSet(); auto_2 = changeStack.closeCurrentChangeSet(); state.set(true); auto_3 = changeStack.closeCurrentChangeSet(); - action_2 = changeStack.startActionChangeSet(player, action); + action_2 = startActionChangeSet(); state.set(false); - action_3 = changeStack.startActionChangeSet(player, action); + action_3 = startActionChangeSet(); } @Test @@ -61,28 +60,33 @@ public class ChangeStackTest { public void testUndo() { assertFalse(state.value()); // undo action 3 - assertTrue(changeStack.undo()); + changeStack.undo(); assertEquals(4, changeStack.sizeUndoStack()); assertSame(action_2, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertFalse(state.value()); // undo action 2 - assertTrue(changeStack.undo()); + changeStack.undo(); assertEquals(3, changeStack.sizeUndoStack()); assertSame(auto_2, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertTrue(state.value()); // undo auto_2 and action 1 - assertTrue(changeStack.undo()); + changeStack.undo(); assertEquals(1, changeStack.sizeUndoStack()); assertSame(auto_1, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertFalse(state.value()); - // undo should not do anything now - assertFalse(changeStack.undo()); + // undo should fail now + try{ + changeStack.undo(); + failBecauseExceptionWasNotThrown(IllegalStateException.class); + } catch (Exception e){ + assertThat(e).isInstanceOf(IllegalStateException.class); + } assertEquals(1, changeStack.sizeUndoStack()); assertSame(auto_1, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertFalse(state.value()); } @@ -92,30 +96,30 @@ public class ChangeStackTest { changeStack.undo(); changeStack.undo(); changeStack.undo(); - // the state unitl now was checked in testUndo + // the state until now was checked in testUndo // now redo action_1 and auto_2 - assertTrue(changeStack.redo()); + changeStack.redo(); assertEquals(3, changeStack.sizeUndoStack()); assertSame(auto_2, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertTrue(state.value()); // redo action_2 - assertTrue(changeStack.redo()); + changeStack.redo(); assertEquals(4, changeStack.sizeUndoStack()); assertSame(action_2, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertFalse(state.value()); // redo action_3 - assertTrue(changeStack.redo()); + changeStack.redo(); assertEquals(5, changeStack.sizeUndoStack()); assertSame(action_3, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertFalse(state.value()); // then it should do anything - assertFalse(changeStack.redo()); + changeStack.redo(); assertEquals(5, changeStack.sizeUndoStack()); assertSame(action_3, changeStack.getLastClosedChangeSet()); - assertThat(changeStack.getCurrentChangeSet()).isInstanceOf(AutoChangeSet.class); + assertFalse(changeStack.getCurrentChangeSet().isBlocking()); assertFalse(state.value()); } diff --git a/junit/rails/game/state/GameChangeSetTest.java b/junit/rails/game/state/GameChangeSetTest.java new file mode 100644 index 0000000..5ed9c31 --- /dev/null +++ b/junit/rails/game/state/GameChangeSetTest.java @@ -0,0 +1,68 @@ +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 GameChangeSetTest { + + private final static String STATE_ID = "State"; + + private Root root; + private BooleanState state; + @Mock Model model; + private ChangeStack changeStack; + private ChangeSet changeSet; + + + @Before + public void setUp() { + root = Root.create(); + state = BooleanState.create(root, STATE_ID); + state.addModel(model); + changeStack = root.getStateManager().getChangeStack(); + changeSet = changeStack.closeCurrentChangeSet(); + } + + @Test + public void testAutoChangeSet() { + assertNotNull(changeSet); + } + + @Test + public void testAddChange() { + assertTrue(changeSet.isEmpty()); + state.set(true); + assertFalse(changeSet.isEmpty()); + verify(model).update(); + } + + @Test + public void testClose() { + assertFalse(changeSet.isClosed()); + state.set(true); + changeSet.close(); + assertTrue(changeSet.isClosed()); + assertThat(changeSet.getObservableStates()).contains(state); + } + + @Test + public void testUnAndReexecute() { + assertFalse(state.value()); + state.set(true); + assertTrue(state.value()); + changeSet.close(); + changeSet.unexecute(); + assertFalse(state.value()); + changeSet.reexecute(); + assertTrue(state.value()); + } +} diff --git a/junit/rails/game/state/GenericStateTest.java b/junit/rails/game/state/GenericStateTest.java index 4222edc..ccfbe49 100644 --- a/junit/rails/game/state/GenericStateTest.java +++ b/junit/rails/game/state/GenericStateTest.java @@ -53,7 +53,7 @@ public class GenericStateTest { stateDefault.set(null); stateInit.set(item); StateTestUtils.close(root); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).doesNotContain(stateDefault, stateInit); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).doesNotContain(stateDefault, stateInit); } @Test @@ -68,7 +68,7 @@ public class GenericStateTest { StateTestUtils.close(root); // remark: stateInit is an internal (isObservable = false) - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).contains(stateDefault); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).contains(stateDefault); StateTestUtils.undo(root); assertNull(stateDefault.value()); diff --git a/junit/rails/game/state/HashMapStateTest.java b/junit/rails/game/state/HashMapStateTest.java index beff08e..31ceae5 100644 --- a/junit/rails/game/state/HashMapStateTest.java +++ b/junit/rails/game/state/HashMapStateTest.java @@ -20,6 +20,7 @@ public class HashMapStateTest { private final static String INIT_ID = "Init"; private final static String FIRST_ITEM_ID = "FirstItem"; + private final static String NEW_FIRST_ITEM_ID = "NewFirstItem"; private final static String SECOND_ITEM_ID = "SecondItem"; private final static String THIRD_ITEM_ID = "ThirdItem"; @@ -29,24 +30,25 @@ public class HashMapStateTest { private HashMapState<String, Item> stateInit; private Map<String, Item> initMap, testMap; - private Item firstItem, secondItem, thirdItem; + private Item firstItem, newFirstItem, secondItem, thirdItem; @Before public void setUp() { root = StateTestUtils.setUpRoot(); - firstItem = AbstractItemImpl.create(root, FIRST_ITEM_ID); + newFirstItem = AbstractItemImpl.create(root, NEW_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 + initMap = ImmutableMap.of(FIRST_ITEM_ID, firstItem); + stateInit = HashMapState.create(root, INIT_ID, initMap); + testMap = Maps.newHashMap(); - testMap.put(FIRST_ITEM_ID, firstItem); - initMap = ImmutableMap.copyOf(testMap); - stateInit = HashMapState.create(root, INIT_ID, testMap); + testMap.put(FIRST_ITEM_ID, newFirstItem); testMap.put(SECOND_ITEM_ID, secondItem); } diff --git a/junit/rails/game/state/IntegerStateTest.java b/junit/rails/game/state/IntegerStateTest.java index 31b26f8..c8a2c83 100644 --- a/junit/rails/game/state/IntegerStateTest.java +++ b/junit/rails/game/state/IntegerStateTest.java @@ -57,7 +57,7 @@ public class IntegerStateTest { stateDefault.set(0); stateInit.set((INIT)); StateTestUtils.close(root); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).doesNotContain(stateDefault, stateInit); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).doesNotContain(stateDefault, stateInit); } @Test diff --git a/junit/rails/game/state/StateTestUtils.java b/junit/rails/game/state/StateTestUtils.java index b9b580c..dd2b7f2 100644 --- a/junit/rails/game/state/StateTestUtils.java +++ b/junit/rails/game/state/StateTestUtils.java @@ -20,7 +20,7 @@ class StateTestUtils { } public static void startActionChangeSet(Root root) { - root.getStateManager().getChangeStack().startActionChangeSet(player, action); + root.getStateManager().getChangeStack().startChangeSet(new ChangeSet(true, false)); } public static void close(Root root) { diff --git a/junit/rails/game/state/StringStateTest.java b/junit/rails/game/state/StringStateTest.java index c302033..d76799c 100644 --- a/junit/rails/game/state/StringStateTest.java +++ b/junit/rails/game/state/StringStateTest.java @@ -63,14 +63,14 @@ public class StringStateTest { stateDefault.set(""); stateInit.set(null); StateTestUtils.close(root); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).doesNotContain(stateDefault); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).contains(stateInit); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).doesNotContain(stateDefault); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).contains(stateInit); stateDefault.set(null); stateInit.set(null); StateTestUtils.close(root); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).contains(stateDefault); - assertThat(StateTestUtils.getLastClosedChangeSet(root).getStates()).doesNotContain(stateInit); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).contains(stateDefault); + assertThat(StateTestUtils.getLastClosedChangeSet(root).getObservableStates()).doesNotContain(stateInit); } @Test diff --git a/src/rails/common/parser/ComponentManager.java b/src/rails/common/parser/ComponentManager.java index daa7f30..f2607e0 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.GameRoot; /** * 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(GameRoot root, String gameName, Tag tag, Map<String, String> gameOptions) throws ConfigurationException { this.gameName = gameName; @@ -36,12 +36,12 @@ public class ComponentManager { for (Tag component : componentTags) { String compName = component.getAttributeAsString("name"); log.debug("Found component " + compName); - configureComponent(context, component); + configureComponent(root, component); component.setGameOptions(gameOptions); } } - private void configureComponent(Context context, Tag componentTag) + private void configureComponent(GameRoot root, 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 c1b6fd5..d59b9aa 100644 --- a/src/rails/common/parser/GameFileParser.java +++ b/src/rails/common/parser/GameFileParser.java @@ -3,66 +3,55 @@ package rails.common.parser; import java.util.Map; import rails.algorithms.RevenueManager; -import rails.common.DisplayBuffer; -import rails.common.LocalText; import rails.common.parser.ComponentManager; import rails.game.Bank; import rails.game.CompanyManager; import rails.game.GameManager; +import rails.game.GameRoot; import rails.game.MapManager; import rails.game.PhaseManager; import rails.game.PlayerManager; import rails.game.StockMarket; import rails.game.TileManager; import rails.game.TrainManager; -import rails.game.state.Root; public class GameFileParser extends XMLParser { - private static String GAME_XML_FILE = "Game.xml"; + public static final String GAME_XML_FILE = "Game.xml"; private Tag componentManagerTag; - private ComponentManager componentManager; - private GameManager gameManager; - private CompanyManager companyManager; - private PlayerManager playerManager; - private PhaseManager phaseManager; - private TrainManager trainManager; - private StockMarket stockMarket; - private MapManager mapManager; - private TileManager tileManager; - private RevenueManager revenueManager; - private Bank bank; + private final ComponentManager componentManager; + private final GameManager gameManager; + private final CompanyManager companyManager; + private final PlayerManager playerManager; + private final PhaseManager phaseManager; + private final TrainManager trainManager; + private final StockMarket stockMarket; + private final MapManager mapManager; + private final TileManager tileManager; + private final RevenueManager revenueManager; + private final Bank bank; - public GameFileParser(Root context, String name, Map<String, String> gameOptions) { + public GameFileParser(GameRoot root, String name, Map<String, String> gameOptions) + throws ConfigurationException { directories.add("data/" + name); - try { - componentManagerTag = Tag.findTopTagInFile(GAME_XML_FILE, directories, XMLTags.COMPONENT_MANAGER_ELEMENT_ID); - componentManagerTag.setGameOptions(gameOptions); - - //XXX: Ultimately calls everyone's configureFromXML() methods. - componentManager = new ComponentManager(context, name, componentManagerTag, gameOptions); - - playerManager = (PlayerManager) componentManager.findComponent("PlayerManager"); - bank = (Bank) componentManager.findComponent("Bank"); - companyManager = (CompanyManager) componentManager.findComponent(CompanyManager.COMPONENT_NAME); - stockMarket = (StockMarket) componentManager.findComponent(StockMarket.COMPONENT_NAME); - gameManager = (GameManager) componentManager.findComponent("GameManager"); - phaseManager = (PhaseManager) componentManager.findComponent("PhaseManager"); - trainManager = (TrainManager) componentManager.findComponent("TrainManager"); - mapManager = (MapManager) componentManager.findComponent("Map"); - tileManager = (TileManager) componentManager.findComponent("TileManager"); - revenueManager = (RevenueManager) componentManager.findComponent("RevenueManager"); - } catch (Exception e) { - String message = - LocalText.getText("GameSetupFailed", GAME_XML_FILE); - log.error(message, e); - System.out.println(e.getMessage()); - e.printStackTrace(); - DisplayBuffer.add(message + ":\n " + e.getMessage()); - } + componentManagerTag = Tag.findTopTagInFile(GAME_XML_FILE, directories, XMLTags.COMPONENT_MANAGER_ELEMENT_ID); + componentManagerTag.setGameOptions(gameOptions); + + componentManager = new ComponentManager(root, name, componentManagerTag, gameOptions); + + playerManager = (PlayerManager) componentManager.findComponent("PlayerManager"); + bank = (Bank) componentManager.findComponent("Bank"); + companyManager = (CompanyManager) componentManager.findComponent(CompanyManager.COMPONENT_NAME); + stockMarket = (StockMarket) componentManager.findComponent(StockMarket.COMPONENT_NAME); + gameManager = (GameManager) componentManager.findComponent("GameManager"); + phaseManager = (PhaseManager) componentManager.findComponent("PhaseManager"); + trainManager = (TrainManager) componentManager.findComponent("TrainManager"); + mapManager = (MapManager) componentManager.findComponent("Map"); + tileManager = (TileManager) componentManager.findComponent("TileManager"); + revenueManager = (RevenueManager) componentManager.findComponent("RevenueManager"); } /** diff --git a/src/rails/game/ActionChangeSet.java b/src/rails/game/ActionChangeSet.java new file mode 100644 index 0000000..549e841 --- /dev/null +++ b/src/rails/game/ActionChangeSet.java @@ -0,0 +1,31 @@ +package rails.game; + +import rails.game.action.PossibleAction; +import rails.game.state.ChangeSet; + +class ActionChangeSet extends ChangeSet { + + // static fields + private final Player player; + private final PossibleAction action; + + ActionChangeSet(Player player, PossibleAction action) { + // it is blocking, but never intitial + super(true, false); + this.player = player; + this.action = action; + } + + Player getPlayer() { + return player; + } + + PossibleAction getAction() { + return action; + } + + @Override + public String toString() { + return "ActionChangeSet for player " + player + " and action " + action; + } +} diff --git a/src/rails/game/Game.java b/src/rails/game/Game.java deleted file mode 100644 index 3140cb0..0000000 --- a/src/rails/game/Game.java +++ /dev/null @@ -1,297 +0,0 @@ -package rails.game; - -import java.io.*; -import java.util.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import rails.algorithms.RevenueManager; -import rails.common.DisplayBuffer; -import rails.common.LocalText; -import rails.common.parser.*; -import rails.game.action.PossibleAction; -import rails.game.state.Root; -import rails.util.GameFileIO; - -public class Game { - public static final String version = "1.5"; - - /** The component Manager */ - protected GameManager gameManager; - protected CompanyManager companyManager; - protected PlayerManager playerManager; - protected PhaseManager phaseManager; - protected TrainManager trainManager; - protected StockMarket stockMarket; - protected MapManager mapManager; - protected TileManager tileManager; - protected RevenueManager revenueManager; - protected Bank bank; - protected String name; - - protected List<String> directories = new ArrayList<String>(); - protected List<String> players; - - protected Map<String, String> gameOptions; - - protected static Logger log = - LoggerFactory.getLogger(Game.class.getPackage().getName()); - - // The new Game entry point - public Game(String name, List<String> players, Map<String, String> options) { - - this.name = name; - this.gameOptions = options; - - gameOptions.put(GameOption.NUMBER_OF_PLAYERS, - String.valueOf(players.size())); - - for (String playerName : players) { - log.debug("Player: " + playerName); - } - for (String optionName : gameOptions.keySet()) { - log.debug("Option: " + optionName + "=" - + gameOptions.get(optionName)); - } - - - this.players = players; - - log.info("========== Start of rails.game " + name + " =========="); - log.info("Rails version "+version); - ReportBuffer.add(LocalText.getText("GameIs", name)); - } - - public String start() { - - if (players.size() < playerManager.minPlayers - || players.size() > playerManager.maxPlayers) { - return name+" is not configured to be played with "+players.size()+" players\n" - + "Please enter a valid number of players, or add a <Players> entry to data/"+name+"/Game.xml"; - } - - gameManager.startGame(gameOptions); - return null; - } - - public boolean setup() { - // first define root GameContext to be able to define states - Root root = Root.create(); - - GameFileParser gfp = new GameFileParser(root, name, gameOptions); - playerManager = gfp.getPlayerManager(); - companyManager = gfp.getCompanyManager(); - trainManager = gfp.getTrainManager(); - phaseManager = gfp.getPhaseManager(); - stockMarket = gfp.getStockMarket(); - mapManager = gfp.getMapManager(); - tileManager = gfp.getTileManager(); - revenueManager = gfp.getRevenueManager(); - bank = gfp.getBank(); - gameManager = gfp.getGameManager(); - - /* - * Initializations that involve relations between components can - * only be done after all XML has been processed. - */ - playerManager.setPlayers(players, bank); - gameManager.init(name, playerManager, companyManager, - phaseManager, trainManager, stockMarket, mapManager, - tileManager, revenueManager, bank); - - try { - companyManager.finishConfiguration(gameManager); - trainManager.finishConfiguration(gameManager); - phaseManager.finishConfiguration(gameManager); - tileManager.finishConfiguration(gameManager); - mapManager.finishConfiguration(gameManager); - bank.finishConfiguration(gameManager); - stockMarket.finishConfiguration(gameManager); - - if (revenueManager != null) - revenueManager.finishConfiguration(gameManager); - } catch (ConfigurationException e) { - log.error(e.getMessage()); - System.out.println(e.getMessage()); - e.printStackTrace(); - DisplayBuffer.add(e.getMessage()); - return false; - } - - return true; - } - - - public static Game load(String filepath) { - - // use GameLoader object to load game - GameFileIO gameLoader = new GameFileIO(); - gameLoader.loadGameData(filepath); - try{ - gameLoader.initGame(); - gameLoader.loadActionsAndComments(); - } catch (ConfigurationException e) { - log.error("Load failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - try{ - gameLoader.replayGame(); - } catch (Exception e) { - log.error("Replay failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - - return gameLoader.getGame(); - } - - @SuppressWarnings("unchecked") - public static Game load_old(String filepath) { - - Game game = null; - - log.debug("Loading game from file " + filepath); - String filename = filepath.replaceAll(".*[/\\\\]", ""); - - /*--- Remember to keep GameManager.reload() in sync with this code! ---*/ - try { - ObjectInputStream ois = - new ObjectInputStream(new FileInputStream( - new File(filepath))); - - // New in 1.0.7: Rails version & save date/time. - // Allow for older saved file versions. - Object object = ois.readObject(); - if (object instanceof String) { - log.info("Reading Rails "+(String)object+" saved file "+filename); - object = ois.readObject(); - } else { - log.info("Reading Rails (pre-1.0.7) saved file "+filename); - } - if (object instanceof String) { - log.info("File was saved at "+(String)object); - object = ois.readObject(); - } - - long versionID = (Long) object; - log.debug("Saved versionID="+versionID+" (object="+object+")"); - long saveFileVersionID = GameManager.saveFileVersionID; - if (versionID != saveFileVersionID) { - throw new Exception("Save version " + versionID - + " is incompatible with current version " - + saveFileVersionID); - } - String name = (String) ois.readObject(); - log.debug("Saved game="+name); - Map<String, String> selectedGameOptions = - (Map<String, String>) ois.readObject(); - List<String> playerNames = (List<String>) ois.readObject(); - - game = new Game(name, playerNames, selectedGameOptions); - - if (!game.setup()) { - throw new ConfigurationException("Error in setting up " + name); - } - - String startError = game.start(); - if (startError != null) { - DisplayBuffer.add(startError); - return null; - } - GameManager gameManager = game.getGameManager(); - - log.debug("Starting to execute loaded actions"); - - gameManager.setReloading(true); - - Object actionObject = null; - int actionIndex = 0; - - while (true) { // Single-pass loop. - try { - actionObject = ois.readObject(); - } catch (EOFException e) { - // Allow saved file at start of game (with no actions). - break; - } - if (actionObject instanceof List) { - // Old-style: one List of PossibleActions - List<PossibleAction> executedActions = - (List<PossibleAction>) actionObject; - for (PossibleAction action : executedActions) { - ++actionIndex; - try { - if (!gameManager.processOnReload(action)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted")); - break; - } - } catch (Exception e) { - log.error("Action "+actionIndex+" '"+action+"' reload exception", e); - throw new Exception ("Reload exception", e); - } - } - } else if (actionObject instanceof PossibleAction) { - // New style: separate PossibleActionsObjects, since Rails 1.3.1 - while (actionObject instanceof PossibleAction) { - ++actionIndex; - try { - if (!gameManager.processOnReload((PossibleAction)actionObject)) { - log.error ("Load interrupted"); - DisplayBuffer.add(LocalText.getText("LoadInterrupted")); - break; - } - } catch (Exception e) { - log.error("Action "+actionIndex+" '"+((PossibleAction)actionObject).toString() - +"' reload exception", e); - throw new Exception ("Reload exception", e); - } - try { - actionObject = ois.readObject(); - } catch (EOFException e) { - break; - } - } - } - break; - } - - // load user comments (is the last - if (actionObject instanceof SortedMap) { - ReportBuffer.setCommentItems((SortedMap<Integer, String>) actionObject); - log.debug("Found sorted map"); - } else { - try { - object = ois.readObject(); - if (object instanceof SortedMap) { - ReportBuffer.setCommentItems((SortedMap<Integer, String>) object); - } - } catch (IOException e) { - // continue without comments, if any IOException occurs - // sometimes not only the EOF Exception is raised - // but also the java.io.StreamCorruptedException: invalid type code - } - } - - ois.close(); - ois = null; - - gameManager.setReloading(false); - gameManager.finishLoading(); - return game; - - } catch (Exception e) { - log.error("Load failed", e); - DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); - } - - return null; - } - - /*----- Getters -----*/ - - public GameManager getGameManager() { - return gameManager; - } - -} diff --git a/src/rails/game/GameRoot.java b/src/rails/game/GameRoot.java new file mode 100644 index 0000000..d186dad --- /dev/null +++ b/src/rails/game/GameRoot.java @@ -0,0 +1,306 @@ +package rails.game; + +import java.io.*; +import java.util.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import rails.algorithms.RevenueManager; +import rails.common.DisplayBuffer; +import rails.common.LocalText; +import rails.common.parser.*; +import rails.game.action.PossibleAction; +import rails.game.state.Root; +import rails.util.GameFileIO; + +public class GameRoot extends Root { + public static final String version = "1.5"; + + /** The component Manager */ + protected GameManager gameManager; + protected CompanyManager companyManager; + protected PlayerManager playerManager; + protected PhaseManager phaseManager; + protected TrainManager trainManager; + protected StockMarket stockMarket; + protected MapManager mapManager; + protected TileManager tileManager; + protected RevenueManager revenueManager; + protected Bank bank; + protected String name; + + protected List<String> directories = new ArrayList<String>(); + protected List<String> players; + + protected Map<String, String> gameOptions; + + protected static Logger log = + LoggerFactory.getLogger(GameRoot.class.getPackage().getName()); + + public GameRoot(String name, List<String> players, Map<String, String> options) { + super(); // initialize root + + this.name = name; + this.gameOptions = options; + + gameOptions.put(GameOption.NUMBER_OF_PLAYERS, + String.valueOf(players.size())); + + for (String playerName : players) { + log.debug("Player: " + playerName); + } + for (String optionName : gameOptions.keySet()) { + log.debug("Option: " + optionName + "=" + + gameOptions.get(optionName)); + } + + + this.players = players; + + log.info("========== Start of rails.game " + name + " =========="); + log.info("Rails version "+version); + ReportBuffer.add(LocalText.getText("GameIs", name)); + } + + public String start() { + + if (players.size() < playerManager.minPlayers + || players.size() > playerManager.maxPlayers) { + return name+" is not configured to be played with "+players.size()+" players\n" + + "Please enter a valid number of players, or add a <Players> entry to data/"+name+"/Game.xml"; + } + + gameManager.startGame(gameOptions); + return null; + } + + public boolean setup() { + GameFileParser gfp; + try{ + gfp = new GameFileParser(this, name, gameOptions); + } catch (Exception e) { + String message = + LocalText.getText("GameSetupFailed", GameFileParser.GAME_XML_FILE); + log.error(message, e); + System.out.println(e.getMessage()); + e.printStackTrace(); + DisplayBuffer.add(message + ":\n " + e.getMessage()); + return false; + } + + playerManager = gfp.getPlayerManager(); + companyManager = gfp.getCompanyManager(); + trainManager = gfp.getTrainManager(); + phaseManager = gfp.getPhaseManager(); + stockMarket = gfp.getStockMarket(); + mapManager = gfp.getMapManager(); + tileManager = gfp.getTileManager(); + revenueManager = gfp.getRevenueManager(); + bank = gfp.getBank(); + gameManager = gfp.getGameManager(); + + /* + * Initializations that involve relations between components can + * only be done after all XML has been processed. + */ + playerManager.setPlayers(players, bank); + gameManager.init(name, playerManager, companyManager, + phaseManager, trainManager, stockMarket, mapManager, + tileManager, revenueManager, bank); + + try { + companyManager.finishConfiguration(gameManager); + trainManager.finishConfiguration(gameManager); + phaseManager.finishConfiguration(gameManager); + tileManager.finishConfiguration(gameManager); + mapManager.finishConfiguration(gameManager); + bank.finishConfiguration(gameManager); + stockMarket.finishConfiguration(gameManager); + + if (revenueManager != null) + revenueManager.finishConfiguration(gameManager); + } catch (ConfigurationException e) { + log.error(e.getMessage()); + System.out.println(e.getMessage()); + e.printStackTrace(); + DisplayBuffer.add(e.getMessage()); + return false; + } + + return true; + } + + + public static GameRoot load(String filepath) { + + // use GameLoader object to load game + GameFileIO gameLoader = new GameFileIO(); + gameLoader.loadGameData(filepath); + try{ + gameLoader.initGame(); + gameLoader.loadActionsAndComments(); + } catch (ConfigurationException e) { + log.error("Load failed", e); + DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); + } + try{ + gameLoader.replayGame(); + } catch (Exception e) { + log.error("Replay failed", e); + DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); + } + + return gameLoader.getGame(); + } + + @SuppressWarnings("unchecked") + public static GameRoot load_old(String filepath) { + + GameRoot game = null; + + log.debug("Loading game from file " + filepath); + String filename = filepath.replaceAll(".*[/\\\\]", ""); + + /*--- Remember to keep GameManager.reload() in sync with this code! ---*/ + try { + ObjectInputStream ois = + new ObjectInputStream(new FileInputStream( + new File(filepath))); + + // New in 1.0.7: Rails version & save date/time. + // Allow for older saved file versions. + Object object = ois.readObject(); + if (object instanceof String) { + log.info("Reading Rails "+(String)object+" saved file "+filename); + object = ois.readObject(); + } else { + log.info("Reading Rails (pre-1.0.7) saved file "+filename); + } + if (object instanceof String) { + log.info("File was saved at "+(String)object); + object = ois.readObject(); + } + + long versionID = (Long) object; + log.debug("Saved versionID="+versionID+" (object="+object+")"); + long saveFileVersionID = GameManager.saveFileVersionID; + if (versionID != saveFileVersionID) { + throw new Exception("Save version " + versionID + + " is incompatible with current version " + + saveFileVersionID); + } + String name = (String) ois.readObject(); + log.debug("Saved game="+name); + Map<String, String> selectedGameOptions = + (Map<String, String>) ois.readObject(); + List<String> playerNames = (List<String>) ois.readObject(); + + game = new GameRoot(name, playerNames, selectedGameOptions); + + if (!game.setup()) { + throw new ConfigurationException("Error in setting up " + name); + } + + String startError = game.start(); + if (startError != null) { + DisplayBuffer.add(startError); + return null; + } + GameManager gameManager = game.getGameManager(); + + log.debug("Starting to execute loaded actions"); + + gameManager.setReloading(true); + + Object actionObject = null; + int actionIndex = 0; + + while (true) { // Single-pass loop. + try { + actionObject = ois.readObject(); + } catch (EOFException e) { + // Allow saved file at start of game (with no actions). + break; + } + if (actionObject instanceof List) { + // Old-style: one List of PossibleActions + List<PossibleAction> executedActions = + (List<PossibleAction>) actionObject; + for (PossibleAction action : executedActions) { + ++actionIndex; + try { + if (!gameManager.processOnReload(action)) { + log.error ("Load interrupted"); + DisplayBuffer.add(LocalText.getText("LoadInterrupted")); + break; + } + } catch (Exception e) { + log.error("Action "+actionIndex+" '"+action+"' reload exception", e); + throw new Exception ("Reload exception", e); + } + } + } else if (actionObject instanceof PossibleAction) { + // New style: separate PossibleActionsObjects, since Rails 1.3.1 + while (actionObject instanceof PossibleAction) { + ++actionIndex; + try { + if (!gameManager.processOnReload((PossibleAction)actionObject)) { + log.error ("Load interrupted"); + DisplayBuffer.add(LocalText.getText("LoadInterrupted")); + break; + } + } catch (Exception e) { + log.error("Action "+actionIndex+" '"+((PossibleAction)actionObject).toString() + +"' reload exception", e); + throw new Exception ("Reload exception", e); + } + try { + actionObject = ois.readObject(); + } catch (EOFException e) { + break; + } + } + } + break; + } + + // load user comments (is the last + if (actionObject instanceof SortedMap) { + ReportBuffer.setCommentItems((SortedMap<Integer, String>) actionObject); + log.debug("Found sorted map"); + } else { + try { + object = ois.readObject(); + if (object instanceof SortedMap) { + ReportBuffer.setCommentItems((SortedMap<Integer, String>) object); + } + } catch (IOException e) { + // continue without comments, if any IOException occurs + // sometimes not only the EOF Exception is raised + // but also the java.io.StreamCorruptedException: invalid type code + } + } + + ois.close(); + ois = null; + + gameManager.setReloading(false); + gameManager.finishLoading(); + return game; + + } catch (Exception e) { + log.error("Load failed", e); + DisplayBuffer.add(LocalText.getText("LoadFailed", e.getMessage())); + } + + return null; + } + + /*----- Getters -----*/ + + public GameManager getGameManager() { + return gameManager; + } + +} diff --git a/src/rails/game/PlayerManager.java b/src/rails/game/PlayerManager.java index d7afb7c..879ee2f 100644 --- a/src/rails/game/PlayerManager.java +++ b/src/rails/game/PlayerManager.java @@ -7,10 +7,10 @@ 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; import rails.game.state.Item; +import rails.game.state.Manager; -public class PlayerManager extends AbstractItem implements ConfigurableComponent { +public class PlayerManager extends Manager implements ConfigurableComponent { private int numberOfPlayers; private List<Player> players; diff --git a/src/rails/game/state/AbstractItem.java b/src/rails/game/state/AbstractItem.java index 916fa27..da11b21 100644 --- a/src/rails/game/state/AbstractItem.java +++ b/src/rails/game/state/AbstractItem.java @@ -9,7 +9,7 @@ public abstract class AbstractItem implements Item { private final String id; private final Item parent; - private final Context context; + private final GameRoot context; protected AbstractItem(Item parent, String id){ checkNotNull(parent, "Parent cannot be null"); @@ -20,8 +20,8 @@ public abstract class AbstractItem implements Item { this.parent = parent; this.id = id; - if (parent instanceof Context) { - context = (Context)parent; + if (parent instanceof GameRoot) { + context = (GameRoot)parent; } else { // recursive definition context = parent.getContext(); @@ -39,7 +39,7 @@ public abstract class AbstractItem implements Item { return parent; } - public Context getContext() { + public GameRoot getContext() { return context; } @@ -49,7 +49,7 @@ public abstract class AbstractItem implements Item { } public String getURI() { - if (parent instanceof Context) { + if (parent instanceof GameRoot) { return id; } else { // recursive definition diff --git a/src/rails/game/state/ActionChangeSet.java b/src/rails/game/state/ActionChangeSet.java deleted file mode 100644 index fb05a96..0000000 --- a/src/rails/game/state/ActionChangeSet.java +++ /dev/null @@ -1,36 +0,0 @@ -package rails.game.state; - -import rails.game.Player; -import rails.game.action.PossibleAction; - -class ActionChangeSet extends ChangeSet { - - private final Player player; - - private final PossibleAction action; - - ActionChangeSet(Player player, PossibleAction action) { - this.player = player; - this.action = action; - } - - Player getPlayer() { - return player; - } - - PossibleAction getAction() { - return action; - } - - boolean isTerminal() { - return false; - } - - - @Override - public String toString() { - return "ActionChangeSet for player " + player + " and action " + action; - } - - -} diff --git a/src/rails/game/state/AutoChangeSet.java b/src/rails/game/state/AutoChangeSet.java deleted file mode 100644 index c69abb7..0000000 --- a/src/rails/game/state/AutoChangeSet.java +++ /dev/null @@ -1,26 +0,0 @@ -package rails.game.state; - -/** - * AutoChangeSets are ChangeSets that belong to no action directly - */ -class AutoChangeSet extends ChangeSet { - - private final boolean terminal; - - /** - * @param terminal implies that this is the terminal of the stack - */ - AutoChangeSet(boolean terminal) { - this.terminal = terminal; - } - - boolean isTerminal() { - return terminal; - } - - @Override - public String toString() { - return "AutoChangeSet"; - } - -} diff --git a/src/rails/game/state/ChangeSet.java b/src/rails/game/state/ChangeSet.java index 5c4d0c3..2c28504 100644 --- a/src/rails/game/state/ChangeSet.java +++ b/src/rails/game/state/ChangeSet.java @@ -1,6 +1,7 @@ package rails.game.state; -import java.util.ArrayList; +import static com.google.common.base.Preconditions.checkState; + import java.util.List; import org.slf4j.Logger; @@ -11,71 +12,91 @@ import com.google.common.collect.Lists; /** * A ChangeSet object represents the collection of all changes - * that belong to the same action. + * that belong to the same activity. * - * This can be either a player action (ActionChangeSet) or a game induced automatic - * (AutoChangeSet) action. + * In general activities can be + * - User triggered: Thus they belong to an action of a player. + * - Game triggered: Changes that are mainly triggered by an automated game action (e.g. a scoring phase, end of turn + * or round activities) * * ChangeSet objects are stored in the ChangeStack. - * - * @author freystef */ -abstract class ChangeSet { +public class ChangeSet { protected static Logger log = LoggerFactory.getLogger(ChangeSet.class.getPackage().getName()); - private final List<Change> changes = new ArrayList<Change>(); + // static fields + private final List<Change> changes = Lists.newArrayList(); + private final boolean blocking; + private final boolean initial; + // dynamic fields private boolean closed = false; - private ImmutableSet<State> states = null; - - // constructor - protected ChangeSet() {}; + protected ChangeSet(boolean blocking, boolean initial) { + this.blocking = blocking; + this.initial = initial; + }; /** - * adds change to the ChangeSet and executes the change - * @param change + * adds change to the ChangeSet and executes the change (i... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-07-31 17:14:59
|
junit/rails/game/state/ModelImpl.java | 22 ++- junit/rails/game/state/ModelTest.java | 40 +++++ junit/rails/game/state/StateImpl.java | 6 junit/rails/game/state/StateManagerTest.java | 186 +++++++++++++++++++++++++++ junit/rails/game/state/StateTest.java | 8 - junit/rails/game/state/StateTestUtils.java | 4 src/rails/game/state/StateManager.java | 167 +++++++----------------- 7 files changed, 305 insertions(+), 128 deletions(-) New commits: commit f4f887ca0517fe84536f6840c01efd5125093426 Author: Stefan Frey <ste...@we...> Date: Tue Jul 31 19:14:04 2012 +0200 Added StateManagerTest and ModelTest Refactored StateManager topological sorting diff --git a/junit/rails/game/state/ModelImpl.java b/junit/rails/game/state/ModelImpl.java index e029de0..886f2e3 100644 --- a/junit/rails/game/state/ModelImpl.java +++ b/junit/rails/game/state/ModelImpl.java @@ -3,15 +3,27 @@ package rails.game.state; //An implementation only for testing class ModelImpl extends Model { - private final String text; + private final StringState text = StringState.create(this, "text"); - ModelImpl(Item parent, String id, String text) { + private ModelImpl(Item parent, String id, String text) { super(parent, id); - this.text = text; + this.text.set(text); } - @Override - public String toString() { + static ModelImpl create(Item parent, String id, String text) { + return new ModelImpl(parent, id, text); + } + + void changeText(String text) { + this.text.set(text); + } + + State getState() { return text; } + + @Override + public String cachedText() { + return text.value(); + } } diff --git a/junit/rails/game/state/ModelTest.java b/junit/rails/game/state/ModelTest.java new file mode 100644 index 0000000..ae16b1b --- /dev/null +++ b/junit/rails/game/state/ModelTest.java @@ -0,0 +1,40 @@ +package rails.game.state; + +import static org.mockito.Mockito.*; +import static org.junit.Assert.*; + +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 ModelTest { + + private static final String MODEL_ID = "Model"; + private static final String MODEL_TEXT_INIT = "Init"; + private static final String MODEL_TEXT_CHANGE = "Change"; + + private Root root; + private ModelImpl model; + @Mock private Observer observer; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + model = ModelImpl.create(root, MODEL_ID, MODEL_TEXT_INIT); + StateTestUtils.startActionChangeSet(root); + model.addObserver(observer); + } + + @Test + public void testModel() { + assertEquals(MODEL_TEXT_INIT, model.observerText()); + model.changeText(MODEL_TEXT_CHANGE); + StateTestUtils.close(root); + assertEquals(MODEL_TEXT_CHANGE, model.observerText()); + verify(observer).update(MODEL_TEXT_CHANGE); + } + +} diff --git a/junit/rails/game/state/StateImpl.java b/junit/rails/game/state/StateImpl.java index 4d4e732..95cae54 100644 --- a/junit/rails/game/state/StateImpl.java +++ b/junit/rails/game/state/StateImpl.java @@ -5,11 +5,15 @@ class StateImpl extends State { private final String text; - StateImpl(Item parent, String id, String text) { + private StateImpl(Item parent, String id, String text) { super(parent, id); this.text = text; } + static StateImpl create(Item parent, String id, String text) { + return new StateImpl(parent, id, text); + } + @Override public String observerText() { return text; diff --git a/junit/rails/game/state/StateManagerTest.java b/junit/rails/game/state/StateManagerTest.java new file mode 100644 index 0000000..9816a5d --- /dev/null +++ b/junit/rails/game/state/StateManagerTest.java @@ -0,0 +1,186 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.fest.assertions.api.Assertions.failBecauseExceptionWasNotThrown; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; + +@RunWith(MockitoJUnitRunner.class) +public class StateManagerTest { + + private final static List<String> ID = + ImmutableList.of("A1" , "A2" , "A3", "B1", "B2", "C1", "C2", "C3", "D", "E", "F"); + + private Root root; + private StateManager sm; + + @Mock private State state; + @Mock private Observer observer; + @Mock private Model model; + private ModelImpl m_A1, m_A2, m_A3, m_B1, m_B2, m_C1, m_C2, m_C3, m_D, m_E, m_F; + @Mock private Observer o_A1, o_A2, o_A3, o_B1, o_B2, o_C1, o_C2, o_C3; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + sm = root.getStateManager(); + + // initialize the models + m_A1 = ModelImpl.create(root, ID.get(0), ID.get(0)); + m_A2 = ModelImpl.create(root, ID.get(1), ID.get(1)); + m_A3 = ModelImpl.create(root, ID.get(2), ID.get(2)); + m_B1 = ModelImpl.create(root, ID.get(3), ID.get(3)); + m_B2 = ModelImpl.create(root, ID.get(4), ID.get(4)); + m_C1 = ModelImpl.create(root, ID.get(5), ID.get(5)); + m_C2 = ModelImpl.create(root, ID.get(6), ID.get(6)); + m_C3 = ModelImpl.create(root, ID.get(7), ID.get(7)); + m_D = ModelImpl.create(root, ID.get(8), ID.get(8)); + m_E = ModelImpl.create(root, ID.get(9), ID.get(9)); + m_F = ModelImpl.create(root, ID.get(10), ID.get(10)); + + // define connections + m_A1.addModel(m_B1); + m_A1.addModel(m_B2); + m_A1.addModel(m_C2); + m_A2.addModel(m_B2); + m_A3.addModel(m_C3); + m_B1.addModel(m_C1); + m_B2.addModel(m_C2); + + // D is special that it depends on the state in A3 directly + m_A3.getState().addModel(m_D); + m_D.addModel(m_A3); + + // E and F form a cycle + m_E.addModel(m_F); + m_F.addModel(m_E); + + // observers + m_A1.addObserver(o_A1); + m_A2.addObserver(o_A2); + m_A3.addObserver(o_A3); + m_B1.addObserver(o_B1); + m_B2.addObserver(o_B2); + m_C1.addObserver(o_C1); + m_C2.addObserver(o_C2); + m_C3.addObserver(o_C3); + } + + @Test + public void testRegisterState() { + sm.registerState(state); + assertThat(sm.getAllStates()).contains(state); + sm.deRegisterState(state); + assertThat(sm.getAllStates()).doesNotContain(state); + } + + @Test + public void testAddObserver() { + sm.addObserver(observer, state); + assertThat(sm.getObservers(state)).contains(observer); + sm.removeObserver(observer, state); + assertThat(sm.getObservers(state)).doesNotContain(observer); + } + + @Test + public void testAddModel() { + sm.addModel(model, state); + assertThat(sm.getModels(state)).contains(model); + sm.removeModel(model, state); + assertThat(sm.getModels(state)).doesNotContain(model); + } + + private void checkOrderings(List<Model> updates) { + for (Model m:updates) { + for (Model dep_m: m.getModels()) { + assertThat(updates.indexOf(dep_m)).isGreaterThan(updates.indexOf(m)); + } + } + } + + + private void assertObservables(List<? extends Model> expected, Set<ModelImpl> updated) { + // get all embedded states that are included + Set<State> states = Sets.newHashSet(); + for (ModelImpl m:updated) { + states.add(m.getState()); + } + // get all observables that are updated + List<Model> toUpdate = sm.getModelsToUpdate(states); + // check that all non-states observables are the updated models and the expected models + assertThat(toUpdate).containsAll(expected); + // ... and does not have duplicates + assertThat(toUpdate).doesNotHaveDuplicates(); + // ... and has the same size + assertEquals(expected.size(), toUpdate.size()); + // and check ordering + checkOrderings(toUpdate); + } + + @Test + public void testObservablesToUpdate() { + // nothing <= nothing + assertObservables(ImmutableList.<Model>of(),ImmutableSet.<ModelImpl>of()); + // A1, B1, B2, C1, C2 <= A1 + assertObservables(ImmutableList.of(m_A1, m_B1, m_B2, m_C1, m_C2),ImmutableSet.of(m_A1)); + // A2, B2, C2 <= A2 + assertObservables(ImmutableList.of(m_A2, m_B2, m_C2),ImmutableSet.of(m_A2)); + // A3, C3 <= A3 + assertObservables(ImmutableList.of(m_A3, m_C3, m_D),ImmutableSet.of(m_A3)); + // B1, C1 <= B1 + assertObservables(ImmutableList.of(m_B1, m_C1),ImmutableSet.of(m_B1)); + // B2, C2 <= B2 + assertObservables(ImmutableList.of(m_B2, m_C2),ImmutableSet.of(m_B2)); + // C1, C2 <= C1, C2 + assertObservables(ImmutableList.of(m_C1, m_C2),ImmutableSet.of(m_C1, m_C2)); + // Combinations: + // A1, A2, B1, B2, C1, C2 <= A1, A2 + assertObservables(ImmutableList.of(m_A1, m_A2, m_B1, m_B2, m_C1, m_C2),ImmutableSet.of(m_A1, m_A2)); + // A1, A2, A3, B1, B2, C1, C2, C3 <= A1, A2, A3 + assertObservables(ImmutableList.of(m_A1, m_A2, m_A3, m_B1, m_B2, m_C1, m_C2, m_C3, m_D),ImmutableSet.of(m_A1, m_A2, m_A3)); + // A2, B1, B2, C1, C2 <= A2, B1 + assertObservables(ImmutableList.of(m_A2, m_B1, m_B2, m_C1, m_C2),ImmutableSet.of(m_A2, m_B1)); + + try{ + assertObservables(ImmutableList.<Model>of(), ImmutableSet.of(m_E)); + failBecauseExceptionWasNotThrown(IllegalStateException.class); + } catch (Exception e) { + assertThat(e).isInstanceOf(IllegalStateException.class); + } + } + + @Test + public void testUpdateObservers() { + sm.updateObservers(ImmutableSet.of(m_A1.getState())); + verify(o_A1).update(ID.get(0)); + verify(o_B1).update(ID.get(3)); + verify(o_B2).update(ID.get(4)); + verify(o_C1).update(ID.get(5)); + verify(o_C2).update(ID.get(6)); + verifyZeroInteractions(o_A2, o_A3, o_C3); + } + + @Test + public void testGetChangeStack() { + assertNotNull(sm.getChangeStack()); + } + + @Test + public void testGetPortfolioManager() { + assertNotNull(sm.getPortfolioManager()); + } + +} diff --git a/junit/rails/game/state/StateTest.java b/junit/rails/game/state/StateTest.java index dcc2bef..0b2dc1d 100644 --- a/junit/rails/game/state/StateTest.java +++ b/junit/rails/game/state/StateTest.java @@ -21,10 +21,10 @@ public class StateTest { @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); + state = StateImpl.create(root, STATE_ID, null); + model = ModelImpl.create(root, MODEL_ID, null); + state_model = StateImpl.create(model, STATE_ID, null); + state_wo_id = StateImpl.create(model, null, STATE_TEXT); } @Test diff --git a/junit/rails/game/state/StateTestUtils.java b/junit/rails/game/state/StateTestUtils.java index b47b9ac..b9b580c 100644 --- a/junit/rails/game/state/StateTestUtils.java +++ b/junit/rails/game/state/StateTestUtils.java @@ -40,6 +40,10 @@ class StateTestUtils { root.getStateManager().getChangeStack().redo(); } + public static ChangeSet getCurrentChangeSet(Root root) { + return root.getStateManager().getChangeStack().getCurrentChangeSet(); + } + public static ChangeSet getLastClosedChangeSet(Root root) { return root.getStateManager().getChangeStack().getLastClosedChangeSet(); diff --git a/src/rails/game/state/StateManager.java b/src/rails/game/state/StateManager.java index 26b9187..0b95760 100644 --- a/src/rails/game/state/StateManager.java +++ b/src/rails/game/state/StateManager.java @@ -2,15 +2,20 @@ package rails.game.state; import static com.google.common.base.Preconditions.checkArgument; -import java.util.List; +import java.util.Collection; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; @@ -39,30 +44,21 @@ public final class StateManager extends Manager implements DelayedItem { return new StateManager(parent, id); } /** - * Register states - * Remark: Portfolios and Wallets get added from their respective managers automatically + * Register states (usually done automatically at state creation) */ 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); -// } } /** - * De-Register states - * Remark: Portfolios and Wallets are removed from their respective managers automatically + * De-Register states */ 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); -// } - return true; + return allStates.remove(state); + } + + ImmutableSet<State> getAllStates() { + return allStates.view(); } /** @@ -84,6 +80,8 @@ public final class StateManager extends Manager implements DelayedItem { /** * Adds the combination of model to observable + * @param Model the model that tracks the observable + * @param Observable the observable to monitor */ void addModel(Model model, Observable observable) { models.put(observable, model); @@ -96,128 +94,61 @@ public final class StateManager extends Manager implements DelayedItem { 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 * - * It uses a topological sort algorithm (Kahn 1962) + * It uses a topological sort based on DFS * - * @param states Set of states - * @return sorted list of all observables (states and models) + * @param states that have changed + * @return sorted list of all models to be updated */ - List<Observable> getSortedObservables(Set<State> states) { - - // 1: define all models - Set<Model> models = getModels(states); - - // 2: define graph - Multimap<Model, Observable> edges = HashMultimap.create(); - - // 2a: add edges that start from states - for (State s:states) { - for (Model m:s.getModels()) { - edges.put(m, s); - } - } - - // 2b: add edges that start from models - for (Model m1:models) { - for (Model m2:m1.getModels()) { - edges.put(m2, m1); - } - } - - // 3: run topological sort - List<Observable> sortedList = Lists.newArrayList(); - List<Observable> startNodes = Lists.newArrayList(); - startNodes.addAll(states); - - while (!startNodes.isEmpty()) { - // remove node n - Observable n = startNodes.remove(0); - // insert node into sortedList - sortedList.add(n); - for (Model m:n.getModels()) { - edges.remove(m, n); - // check if m is now a start node - if (!edges.containsKey(m)) { - startNodes.add(m); - } - } - } + private static enum Color {WHITE, GREY, BLACK} + ImmutableList<Model> getModelsToUpdate(Collection<State> states) { + // Topological sort + // Initialize (we do not use WHITE explicitly, but implicit) + Map<Observable, Color> colors = Maps.newHashMap(); + LinkedList<Model> topoList = Lists.newLinkedList(); - // if graph is not empty => cyclical graph - if (!edges.isEmpty()) { - log.debug("StateManager: Cyclical graph detected in State/Model relations."); - // add remaining models to the end - sortedList.addAll(edges.keySet()); + // For all states + for (State s: states) { + topoSort(s, colors, topoList); } - - return sortedList; + log.debug("Observables to Update = " + topoList.toString()); + return ImmutableList.copyOf(topoList); } - /** - * @param states Set of states - * @return all observers to be updated from states (either directly or via Models) - */ - private Set<Observer> getObservers(Set<State> states){ - - Set<Observer> observers = Sets.newHashSet(); - - // all direct observers - for (State s:states){ - observers.addAll(s.getObservers()); - } - - // all indirect observers - for (Model m:getModels(states)){ - observers.addAll(m.getObservers()); + private void topoSort(Observable v, Map<Observable, Color> colors, LinkedList<Model> topoList) { + colors.put(v, Color.GREY); + for (Model m:v.getModels()) { + if (!colors.containsKey(m)) { + topoSort(m, colors, topoList); + } else if (colors.get(m) == Color.GREY) { + throw new IllegalStateException("Graph of Observables contains Cycle"); + } } - - return observers; + colors.put(v, Color.BLACK); + if (v instanceof Model) topoList.addFirst((Model)v); } + void updateObservers(Set<State> states) { - for (Observable observable:getSortedObservables(states)) { - for (Observer observer:observable.getObservers()) { - observer.update(observable.observerText()); + // all direct observers + for (State s:states){ + for (Observer o:s.getObservers()) { + o.update(s.observerText()); } } - } - - /** - * @param states Set of states - * @return all models to be updated from states - */ - Set<Model> getModels(Set<State> states) { - - Set<Model> allModels = Sets.newHashSet(); - - // add all models updated from states directly - for (State s:states) { - allModels.addAll(s.getModels()); - } - // then add models called indirectly - ImmutableSet<Model> checkModels = ImmutableSet.copyOf(allModels); - Set<Model> newModels = Sets.newHashSet(); - while (!checkModels.isEmpty()) { - for (Model m1:checkModels) { - for (Model m2:m1.getModels()) { - if (!allModels.contains(m2)) { - allModels.add(m2); - newModels.add(m2); - } - } + // all indirect observers + for (Model m:getModelsToUpdate(states)) { + for (Observer o:m.getObservers()) { + o.update(m.observerText()); } - checkModels = ImmutableSet.copyOf(newModels); - newModels.clear(); } - return allModels; } - // void registerReceiver(Triggerable receiver, State toState) { // } |
From: Stefan F. <ste...@us...> - 2012-07-27 05:08:23
|
junit/rails/game/state/OwnableItemImpl.java | 2 junit/rails/game/state/PortfolioHolderImpl.java | 17 + junit/rails/game/state/PortfolioHolderTest.java | 51 +++ junit/rails/game/state/PortfolioListTest.java | 114 -------- junit/rails/game/state/PortfolioManagerTest.java | 6 junit/rails/game/state/PortfolioMapTest.java | 148 +++++++++++ junit/rails/game/state/PortfolioSetTest.java | 122 +++++++++ junit/rails/game/state/TypeOwnableItemImpl.java | 19 + src/rails/game/Company.java | 12 src/rails/game/GameManager.java | 2 src/rails/game/MapHex.java | 12 src/rails/game/OperatingRound.java | 8 src/rails/game/PublicCertificate.java | 8 src/rails/game/PublicCompany.java | 10 src/rails/game/Stop.java | 8 src/rails/game/Train.java | 5 src/rails/game/TrainManager.java | 6 src/rails/game/action/BuyTrain.java | 23 - src/rails/game/action/DiscardTrain.java | 26 - src/rails/game/model/BaseTokensModel.java | 14 - src/rails/game/model/CertificatesModel.java | 10 src/rails/game/model/PortfolioModel.java | 27 +- src/rails/game/model/PrivatesModel.java | 4 src/rails/game/model/TrainsModel.java | 9 src/rails/game/specific/_1835/OperatingRound_1835.java | 8 src/rails/game/specific/_1835/PrussianFormationRound.java | 16 - src/rails/game/specific/_1856/CGRFormationRound.java | 8 src/rails/game/specific/_1856/OperatingRound_1856.java | 4 src/rails/game/specific/_1856/PublicCompany_1856.java | 4 src/rails/game/specific/_1889/OperatingRound_1889.java | 8 src/rails/game/specific/_18AL/AssignNamedTrains.java | 2 src/rails/game/specific/_18AL/OperatingRound_18AL.java | 3 src/rails/game/specific/_18EU/OperatingRound_18EU.java | 3 src/rails/game/specific/_18TN/OperatingRound_18TN.java | 4 src/rails/game/state/HashMapState.java | 34 +- src/rails/game/state/Portfolio.java | 5 src/rails/game/state/PortfolioList.java | 72 ----- src/rails/game/state/PortfolioManager.java | 6 src/rails/game/state/PortfolioMap.java | 57 ++-- src/rails/game/state/PortfolioSet.java | 77 +++++ src/rails/game/state/Typable.java | 12 src/rails/ui/swing/GameUIManager.java | 9 src/rails/ui/swing/ORUIManager.java | 13 src/rails/ui/swing/gamespecific/_1835/StatusWindow_1835.java | 4 src/rails/ui/swing/gamespecific/_18EU/StatusWindow_18EU.java | 10 src/rails/ui/swing/hexmap/GUIHex.java | 14 - 46 files changed, 670 insertions(+), 366 deletions(-) New commits: commit 778be678fa5313cc552b4b801f4ead17b1991a21 Author: Stefan Frey <ste...@we...> Date: Fri Jul 27 07:07:39 2012 +0200 added PortfolioHolderTest diff --git a/junit/rails/game/state/PortfolioHolderImpl.java b/junit/rails/game/state/PortfolioHolderImpl.java new file mode 100644 index 0000000..4a7cb1a --- /dev/null +++ b/junit/rails/game/state/PortfolioHolderImpl.java @@ -0,0 +1,17 @@ +package rails.game.state; + +class PortfolioHolderImpl extends AbstractItem implements PortfolioHolder { + + private PortfolioHolderImpl(Owner parent, String id) { + super (parent, id); + } + + static PortfolioHolderImpl create(Owner parent, String id) { + return new PortfolioHolderImpl(parent, id); + } + + public Owner getParent() { + return (Owner)super.getParent(); + } +} + diff --git a/junit/rails/game/state/PortfolioHolderTest.java b/junit/rails/game/state/PortfolioHolderTest.java new file mode 100644 index 0000000..8f1fec5 --- /dev/null +++ b/junit/rails/game/state/PortfolioHolderTest.java @@ -0,0 +1,51 @@ +package rails.game.state; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +public class PortfolioHolderTest { + + private final static String PORTFOLIO_MAP_ID = "PortfolioMap"; + private final static String PORTFOLIO_SET_ID = "PortfolioSet"; + private final static String OWNER_ID = "Owner"; + private final static String HOLDER_ID = "Holder"; + + private final static String ITEM_ID = "Item"; + private final static String TYPE_ID = "Type"; + + private Root root; + private Owner owner; + private PortfolioHolder holder; + private TypeOwnableItemImpl item; + + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + owner = OwnerImpl.create(root, OWNER_ID); + holder = PortfolioHolderImpl.create(owner, HOLDER_ID); + + item = TypeOwnableItemImpl.create(root, ITEM_ID, TYPE_ID); + StateTestUtils.startActionChangeSet(root); + } + + @Test + public void testPortfolioMap() { + PortfolioMap<String, TypeOwnableItemImpl> portfolio = + PortfolioMap.create(holder, PORTFOLIO_MAP_ID , TypeOwnableItemImpl.class); + item.moveTo(owner); + assertTrue(portfolio.containsItem(item)); + assertSame(owner, item.getOwner()); + } + + @Test + public void testPortfolioSet() { + PortfolioSet<TypeOwnableItemImpl> portfolio = + PortfolioSet.create(holder, PORTFOLIO_SET_ID , TypeOwnableItemImpl.class); + item.moveTo(owner); + assertTrue(portfolio.containsItem(item)); + assertSame(owner, item.getOwner()); + } +} diff --git a/src/rails/game/state/HashMapState.java b/src/rails/game/state/HashMapState.java index b14a845..4fe22db 100644 --- a/src/rails/game/state/HashMapState.java +++ b/src/rails/game/state/HashMapState.java @@ -160,23 +160,23 @@ public final class HashMapState<K,V> extends State { return ImmutableList.copyOf(map.values()); } - public String getData() { - - if (map == null) return ""; - - StringBuilder buf = new StringBuilder("<html>"); - for (K name : map.keySet()) { - if (buf.length() > 6) buf.append("<br>"); - buf.append(name.toString()); - Object value = map.get(name); - if (value != null && rails.util.Util.hasValue(value.toString())) buf.append("=").append(value.toString()); - } - if (buf.length() > 6) { - buf.append("</html>"); - } - return buf.toString(); - - } +// public String getData() { +// +// if (map == null) return ""; +// +// StringBuilder buf = new StringBuilder("<html>"); +// for (K name : map.keySet()) { +// if (buf.length() > 6) buf.append("<br>"); +// buf.append(name.toString()); +// Object value = map.get(name); +// if (value != null && rails.util.Util.hasValue(value.toString())) buf.append("=").append(value.toString()); +// } +// if (buf.length() > 6) { +// buf.append("</html>"); +// } +// return buf.toString(); +// +// } @Override public String observerText() { commit 90a08542c1f46895322f86f440dc2b16209841d3 Author: Stefan Frey <ste...@we...> Date: Thu Jul 26 15:13:31 2012 +0200 refactored PortfolioMap and added Tests, introduced Typable interface diff --git a/junit/rails/game/state/OwnableItemImpl.java b/junit/rails/game/state/OwnableItemImpl.java index ca1d844..c095d66 100644 --- a/junit/rails/game/state/OwnableItemImpl.java +++ b/junit/rails/game/state/OwnableItemImpl.java @@ -5,7 +5,7 @@ package rails.game.state; */ class OwnableItemImpl extends OwnableItem<Ownable> { - private OwnableItemImpl(Item parent, String id) { + protected OwnableItemImpl(Item parent, String id) { super(parent, id, Ownable.class); } diff --git a/junit/rails/game/state/PortfolioListTest.java b/junit/rails/game/state/PortfolioListTest.java deleted file mode 100644 index b7c676f..0000000 --- a/junit/rails/game/state/PortfolioListTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package rails.game.state; - -import static org.fest.assertions.api.Assertions.assertThat; -import static org.junit.Assert.*; - -import java.util.Iterator; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; - -import com.google.common.collect.Sets; - -public class PortfolioListTest { - - private final static String PORTFOLIO_A_ID = "PortfolioA"; - private final static String PORTFOLIO_B_ID = "PortfolioB"; - private final static String OWNER_A_ID = "OwnerA"; - private final static String OWNER_B_ID = "OwnerB"; - private final static String ITEM_ID = "Item"; - private final static String ANOTHER_ITEM_ID = "AnotherItem"; - - private Root root; - private PortfolioList<Ownable> portfolioA; - private PortfolioList<Ownable> portfolioB; - private Owner ownerA; - private Owner ownerB; - private Ownable item; - private Ownable anotherItem; - - @Before - public void setUp() { - root = StateTestUtils.setUpRoot(); - ownerA = OwnerImpl.create(root, OWNER_A_ID); - ownerB = OwnerImpl.create(root, OWNER_B_ID); - portfolioA = PortfolioList.create(ownerA, PORTFOLIO_A_ID , Ownable.class); - portfolioB = PortfolioList.create(ownerB, PORTFOLIO_B_ID , Ownable.class); - item = OwnableItemImpl.create(root, ITEM_ID); - anotherItem = OwnableItemImpl.create(root, ANOTHER_ITEM_ID); - portfolioA.moveInto(item); - StateTestUtils.startActionChangeSet(root); - } - - // helper function to check the initial state after undo - // includes redo, so after returning the state should be unchanged - private void assertInitialStateAfterUndo() { - StateTestUtils.closeAndUndo(root); - assertTrue(portfolioA.containsItem(item)); - assertSame(ownerA, item.getOwner()); - StateTestUtils.redo(root); - } - - @Test - public void testMoveInto() { - // move item to B - item.moveTo(ownerB); - assertTrue(portfolioB.containsItem(item)); - assertSame(ownerB, item.getOwner()); - - // undo check - assertInitialStateAfterUndo(); - - // redo check - assertTrue(portfolioB.containsItem(item)); - assertSame(ownerB, item.getOwner()); - } - - @Test - public void testContainsItem() { - assertTrue(portfolioA.containsItem(item)); - assertFalse(portfolioB.containsItem(item)); - } - - @Test - public void testItems() { - assertThat(portfolioA.items()).containsOnly(item); - anotherItem.moveTo(ownerA); - assertThat(portfolioA.items()).containsOnly(item, anotherItem); - } - - @Test - public void testSize() { - assertEquals(1, portfolioA.size()); - assertEquals(0, portfolioB.size()); - anotherItem.moveTo(ownerA); - assertEquals(2, portfolioA.size()); - item.moveTo(ownerB); - assertEquals(1, portfolioA.size()); - assertEquals(1, portfolioB.size()); - } - - @Test - public void testIsEmpty() { - assertFalse(portfolioA.isEmpty()); - assertTrue(portfolioB.isEmpty()); - } - - @Test - public void testIterator() { - anotherItem.moveTo(ownerA); - - // no order is defined, so store them - Set<Ownable> iterated = Sets.newHashSet(); - - Iterator<Ownable> it = portfolioA.iterator(); - iterated.add(it.next()); - iterated.add(it.next()); - - assertThat(iterated).containsOnly(item, anotherItem); - // iterator is finished - assertFalse(it.hasNext()); - } - -} diff --git a/junit/rails/game/state/PortfolioManagerTest.java b/junit/rails/game/state/PortfolioManagerTest.java index 2a9e52d..7a4a889 100644 --- a/junit/rails/game/state/PortfolioManagerTest.java +++ b/junit/rails/game/state/PortfolioManagerTest.java @@ -15,7 +15,7 @@ public class PortfolioManagerTest { private Root root; private PortfolioManager pm; - private PortfolioList<Ownable> portfolioA, portfolioB; + private PortfolioSet<Ownable> portfolioA, portfolioB; private Owner ownerA, ownerB, ownerC; @Before @@ -25,8 +25,8 @@ public class PortfolioManagerTest { ownerA = OwnerImpl.create(root, OWNER_A_ID); ownerB = OwnerImpl.create(root, OWNER_B_ID); ownerC = OwnerImpl.create(root, OWNER_C_ID); - portfolioA = PortfolioList.create(ownerA, PORTFOLIO_A_ID , Ownable.class); - portfolioB = PortfolioList.create(ownerB, PORTFOLIO_B_ID , Ownable.class); + portfolioA = PortfolioSet.create(ownerA, PORTFOLIO_A_ID , Ownable.class); + portfolioB = PortfolioSet.create(ownerB, PORTFOLIO_B_ID , Ownable.class); StateTestUtils.startActionChangeSet(root); } diff --git a/junit/rails/game/state/PortfolioMapTest.java b/junit/rails/game/state/PortfolioMapTest.java new file mode 100644 index 0000000..40bcf8f --- /dev/null +++ b/junit/rails/game/state/PortfolioMapTest.java @@ -0,0 +1,148 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import java.util.Iterator; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; + +public class PortfolioMapTest { + + private final static String PORTFOLIO_MAP_ID = "PortfolioMap"; + private final static String PORTFOLIO_SET_ID = "PortfolioSet"; + private final static String OWNER_MAP_ID = "OwnerMap"; + private final static String OWNER_SET_ID = "OwnerSet"; + private final static String ITEM_ID = "Item"; + private final static String ANOTHER_ITEM_ID = "AnotherItem"; + private final static String TYPE_ID = "Type"; + private final static String ANOTHER_TYPE_ID = "AnotherType"; + + private Root root; + private PortfolioMap<String, TypeOwnableItemImpl> portfolioMap; + private PortfolioSet<TypeOwnableItemImpl> portfolioSet; + private Owner ownerMap; + private Owner ownerSet; + private TypeOwnableItemImpl item; + private TypeOwnableItemImpl anotherItem; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + ownerMap = OwnerImpl.create(root, OWNER_MAP_ID); + ownerSet = OwnerImpl.create(root, OWNER_SET_ID); + portfolioMap = PortfolioMap.create(ownerMap, PORTFOLIO_MAP_ID , TypeOwnableItemImpl.class); + portfolioSet = PortfolioSet.create(ownerSet, PORTFOLIO_SET_ID , TypeOwnableItemImpl.class); + item = TypeOwnableItemImpl.create(root, ITEM_ID, TYPE_ID); + anotherItem = TypeOwnableItemImpl.create(root, ANOTHER_ITEM_ID, ANOTHER_TYPE_ID); + portfolioSet.moveInto(item); + StateTestUtils.startActionChangeSet(root); + } + + // helper function to check the initial state after undo + // includes redo, so after returning the state should be unchanged + private void assertInitialStateAfterUndo() { + StateTestUtils.closeAndUndo(root); + assertTrue(portfolioSet.containsItem(item)); + assertSame(ownerSet, item.getOwner()); + StateTestUtils.redo(root); + } + + @Test + public void testMoveInto() { + portfolioMap.moveInto(item); + assertSame(ownerMap, item.getOwner()); + assertTrue(portfolioMap.containsItem(item)); + assertFalse(portfolioSet.containsItem(item)); + // check undo + assertInitialStateAfterUndo(); + // and redo + assertTrue(portfolioMap.containsItem(item)); + } + + @Test + public void testContainsItem() { + assertFalse(portfolioMap.containsItem(item)); + item.moveTo(ownerMap); + assertTrue(portfolioMap.containsItem(item)); + } + + @Test + public void testItems() { + assertThat(portfolioMap.items()).isEmpty(); + item.moveTo(ownerMap); + assertThat(portfolioMap.items()).containsOnly(item); + anotherItem.moveTo(ownerMap); + assertThat(portfolioMap.items()).containsOnly(item, anotherItem); + } + + @Test + public void testSize() { + assertEquals(0, portfolioMap.size()); + item.moveTo(ownerMap); + assertEquals(1, portfolioMap.size()); + anotherItem.moveTo(ownerMap); + assertEquals(2, portfolioMap.size()); + } + + @Test + public void testIsEmpty() { + assertTrue(portfolioMap.isEmpty()); + item.moveTo(ownerMap); + assertFalse(portfolioMap.isEmpty()); + } + + @Test + public void testContainsKey() { + assertFalse(portfolioMap.containsKey(TYPE_ID)); + item.moveTo(ownerMap); + assertTrue(portfolioMap.containsKey(TYPE_ID)); + item.moveTo(ownerSet); + assertFalse(portfolioMap.containsKey(TYPE_ID)); + } + + @Test + public void testGetItems() { + assertThat(portfolioMap.getItems(TYPE_ID)).isEmpty(); + item.moveTo(ownerMap); + assertThat(portfolioMap.getItems(TYPE_ID)).containsOnly(item); + } + + @Test + public void testView() { + item.moveTo(ownerMap); + SetMultimap<String, TypeOwnableItemImpl> view = portfolioMap.view(); + assertTrue(view.containsValue(item)); + // still holds true after removing item + item.moveTo(ownerSet); + assertTrue(view.containsValue(item)); + assertFalse(portfolioMap.containsItem(item)); + } + + @Test + public void testIterator() { + item.moveTo(ownerMap); + anotherItem.moveTo(ownerMap); + + // no order is defined, so store them + Set<Ownable> iterated = Sets.newHashSet(); + + + Iterator<TypeOwnableItemImpl> it = portfolioMap.iterator(); + // and it still works even after removing items + item.moveTo(ownerSet); + + iterated.add(it.next()); + iterated.add(it.next()); + + assertThat(iterated).containsOnly(item, anotherItem); + // iterator is finished + assertFalse(it.hasNext()); + } + +} diff --git a/junit/rails/game/state/PortfolioSetTest.java b/junit/rails/game/state/PortfolioSetTest.java new file mode 100644 index 0000000..9954576 --- /dev/null +++ b/junit/rails/game/state/PortfolioSetTest.java @@ -0,0 +1,122 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import java.util.Iterator; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.Sets; + +public class PortfolioSetTest { + + private final static String PORTFOLIO_A_ID = "PortfolioA"; + private final static String PORTFOLIO_B_ID = "PortfolioB"; + private final static String OWNER_A_ID = "OwnerA"; + private final static String OWNER_B_ID = "OwnerB"; + private final static String ITEM_ID = "Item"; + private final static String ANOTHER_ITEM_ID = "AnotherItem"; + + private Root root; + private PortfolioSet<Ownable> portfolioA; + private PortfolioSet<Ownable> portfolioB; + private Owner ownerA; + private Owner ownerB; + private Ownable item; + private Ownable anotherItem; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + ownerA = OwnerImpl.create(root, OWNER_A_ID); + ownerB = OwnerImpl.create(root, OWNER_B_ID); + portfolioA = PortfolioSet.create(ownerA, PORTFOLIO_A_ID , Ownable.class); + portfolioB = PortfolioSet.create(ownerB, PORTFOLIO_B_ID , Ownable.class); + item = OwnableItemImpl.create(root, ITEM_ID); + anotherItem = OwnableItemImpl.create(root, ANOTHER_ITEM_ID); + portfolioA.moveInto(item); + StateTestUtils.startActionChangeSet(root); + } + + // helper function to check the initial state after undo + // includes redo, so after returning the state should be unchanged + private void assertInitialStateAfterUndo() { + StateTestUtils.closeAndUndo(root); + assertTrue(portfolioA.containsItem(item)); + assertSame(ownerA, item.getOwner()); + StateTestUtils.redo(root); + } + + @Test + public void testMoveInto() { + // move item to B + item.moveTo(ownerB); + assertTrue(portfolioB.containsItem(item)); + assertSame(ownerB, item.getOwner()); + + // undo check + assertInitialStateAfterUndo(); + + // redo check + assertTrue(portfolioB.containsItem(item)); + assertSame(ownerB, item.getOwner()); + } + + @Test + public void testContainsItem() { + assertTrue(portfolioA.containsItem(item)); + assertFalse(portfolioB.containsItem(item)); + } + + @Test + public void testItems() { + assertThat(portfolioA.items()).containsOnly(item); + anotherItem.moveTo(ownerA); + Set<Ownable> items = portfolioA.items(); + assertThat(items).containsOnly(item, anotherItem); + // and the view is unchanged after changing the portfolio + anotherItem.moveTo(ownerB); + assertTrue(items.contains(anotherItem)); + assertFalse(portfolioA.containsItem(anotherItem)); + } + + @Test + public void testSize() { + assertEquals(1, portfolioA.size()); + assertEquals(0, portfolioB.size()); + anotherItem.moveTo(ownerA); + assertEquals(2, portfolioA.size()); + item.moveTo(ownerB); + assertEquals(1, portfolioA.size()); + assertEquals(1, portfolioB.size()); + } + + @Test + public void testIsEmpty() { + assertFalse(portfolioA.isEmpty()); + assertTrue(portfolioB.isEmpty()); + } + + @Test + public void testIterator() { + anotherItem.moveTo(ownerA); + + // no order is defined, so store them + Set<Ownable> iterated = Sets.newHashSet(); + + Iterator<Ownable> it = portfolioA.iterator(); + // and it still works even after removing items + anotherItem.moveTo(ownerB); + + iterated.add(it.next()); + iterated.add(it.next()); + + assertThat(iterated).containsOnly(item, anotherItem); + // iterator is finished + assertFalse(it.hasNext()); + } + +} diff --git a/junit/rails/game/state/TypeOwnableItemImpl.java b/junit/rails/game/state/TypeOwnableItemImpl.java new file mode 100644 index 0000000..7ba4b7d --- /dev/null +++ b/junit/rails/game/state/TypeOwnableItemImpl.java @@ -0,0 +1,19 @@ +package rails.game.state; + +// Implementation of a typed OwnableItem +class TypeOwnableItemImpl extends OwnableItem<TypeOwnableItemImpl> implements Typable<String> { + private final String type; + + private TypeOwnableItemImpl(Item parent, String id, String type) { + super(parent, id, TypeOwnableItemImpl.class); + this.type = type; + } + + static TypeOwnableItemImpl create(Item parent, String id, String type) { + return new TypeOwnableItemImpl(parent, id, type); + } + + public String getType() { + return type; + } +} diff --git a/src/rails/game/Company.java b/src/rails/game/Company.java index 4d5ad04..4815807 100644 --- a/src/rails/game/Company.java +++ b/src/rails/game/Company.java @@ -5,7 +5,7 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import rails.common.parser.ConfigurableComponent; import rails.common.parser.ConfigurationException; @@ -15,7 +15,7 @@ import rails.game.state.BooleanState; import rails.game.state.AbstractItem; import rails.game.state.Item; import rails.game.state.Owner; -import rails.game.state.PortfolioList; +import rails.game.state.PortfolioSet; import rails.util.Util; public abstract class Company extends AbstractItem implements Owner, ConfigurableComponent, @@ -53,8 +53,8 @@ Cloneable, Comparable<Company> { protected final BooleanState closedObject = BooleanState.create(this, "closed", false); // Moved here from PrivayeCOmpany on behalf of 1835 - protected final PortfolioList<SpecialProperty> specialProperties = - PortfolioList.create(this, "specialProperties", SpecialProperty.class); + protected final PortfolioSet<SpecialProperty> specialProperties = + PortfolioSet.create(this, "specialProperties", SpecialProperty.class); protected static Logger log = LoggerFactory.getLogger(Company.class.getPackage().getName()); @@ -96,9 +96,9 @@ Cloneable, Comparable<Company> { } /** - * @return ArrayList of all special properties we have. + * @return Set of all special properties we have. */ - public ImmutableList<SpecialProperty> getSpecialProperties() { + public ImmutableSet<SpecialProperty> getSpecialProperties() { return specialProperties.items(); } diff --git a/src/rails/game/GameManager.java b/src/rails/game/GameManager.java index 5f9d4f0..b196d46 100644 --- a/src/rails/game/GameManager.java +++ b/src/rails/game/GameManager.java @@ -1703,7 +1703,7 @@ public class GameManager extends AbstractItem implements ConfigurableComponent, public boolean addSpecialProperty(SpecialProperty property) { if (commonSpecialProperties == null) { - commonSpecialProperties = PortfolioList.create(this, + commonSpecialProperties = PortfolioSet.create(this, "CommonSpecialProperties", SpecialProperty.class); } return commonSpecialProperties.moveInto(property); diff --git a/src/rails/game/MapHex.java b/src/rails/game/MapHex.java index 1c9f497..17e3c65 100644 --- a/src/rails/game/MapHex.java +++ b/src/rails/game/MapHex.java @@ -7,7 +7,7 @@ import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import rails.algorithms.RevenueBonusTemplate; import rails.common.LocalText; @@ -25,7 +25,7 @@ import rails.game.state.BooleanState; import rails.game.state.Observer; import rails.game.state.Owner; import rails.game.state.Portfolio; -import rails.game.state.PortfolioList; +import rails.game.state.PortfolioSet; import rails.game.state.AbstractItem; import rails.util.*; @@ -126,7 +126,7 @@ StationHolder { protected List<PublicCompany> destinations; /** Tokens that are not bound to a Station (City), such as Bonus tokens */ - protected final PortfolioList<Token> offStationTokens = PortfolioList.create(this, + protected final PortfolioSet<Token> offStationTokens = PortfolioSet.create(this, "offStationTokens", Token.class); /** Storage of revenueBonus that are bound to the hex */ @@ -979,7 +979,7 @@ StationHolder { return tokens; } - public PortfolioList<Token> getTokens() { + public PortfolioSet<Token> getTokens() { return offStationTokens; } @@ -1015,11 +1015,11 @@ StationHolder { return false; } - public ImmutableList<Token> getTokens(int cityNumber) { + public ImmutableSet<Token> getTokens(int cityNumber) { if (stops.size() > 0 && mStops.get(cityNumber) != null) { return (mStops.get(cityNumber)).getTokens().items(); } else { - return ImmutableList.of(); // empty List + return ImmutableSet.of(); // empty List } } diff --git a/src/rails/game/OperatingRound.java b/src/rails/game/OperatingRound.java index 3c02255..27a5377 100644 --- a/src/rails/game/OperatingRound.java +++ b/src/rails/game/OperatingRound.java @@ -10,6 +10,8 @@ import java.util.SortedMap; import java.util.TreeMap; import java.util.TreeSet; +import com.google.common.collect.Iterables; + import rails.common.*; import rails.common.parser.GameOption; import rails.game.action.*; @@ -2811,7 +2813,7 @@ public class OperatingRound extends Round implements Observer { int cash = operatingCompany.value().getCash(); int cost = 0; - List<Train> trains; + Set<Train> trains; boolean hasTrains = operatingCompany.value().getPortfolioModel().getNumberOfTrains() > 0; @@ -2862,7 +2864,7 @@ public class OperatingRound extends Round implements Observer { if (train.canBeExchanged() && hasTrains) { cost = train.getCertType().getExchangeCost(); if (cost <= cash) { - List<Train> exchangeableTrains = + Set<Train> exchangeableTrains = operatingCompany.value().getPortfolioModel().getUniqueTrains(); BuyTrain action = new BuyTrain(train, ipo.getParent(), cost); action.setTrainsForExchange(exchangeableTrains); @@ -3031,7 +3033,7 @@ public class OperatingRound extends Round implements Observer { public void checkForeignSales() { if (getGameParameterAsBoolean(GameDef.Parm.REMOVE_TRAIN_BEFORE_SR) && trainManager.isAnyTrainBought()) { - Train train = trainManager.getAvailableNewTrains().get(0); + Train train = Iterables.get(trainManager.getAvailableNewTrains(), 0); if (train.getCertType().hasInfiniteQuantity()) return; scrapHeap.addTrain(train); ReportBuffer.add(LocalText.getText("RemoveTrain", train.getId())); diff --git a/src/rails/game/PublicCertificate.java b/src/rails/game/PublicCertificate.java index f6e2cd1..e72b973 100644 --- a/src/rails/game/PublicCertificate.java +++ b/src/rails/game/PublicCertificate.java @@ -10,8 +10,9 @@ import rails.common.LocalText; import rails.game.model.CertificatesModel; import rails.game.state.Item; import rails.game.state.OwnableItem; +import rails.game.state.Typable; -public class PublicCertificate extends OwnableItem<PublicCertificate> implements Certificate, Cloneable { +public class PublicCertificate extends OwnableItem<PublicCertificate> implements Certificate, Cloneable, Typable<PublicCompany> { /** From which public company is this a certificate */ protected PublicCompany company; @@ -188,6 +189,11 @@ public class PublicCertificate extends OwnableItem<PublicCertificate> implements return certTypeId; } + // Typable interface + public PublicCompany getType() { + return company; + } + @Override protected Object clone() { try { diff --git a/src/rails/game/PublicCompany.java b/src/rails/game/PublicCompany.java index c961906..bc673b4 100644 --- a/src/rails/game/PublicCompany.java +++ b/src/rails/game/PublicCompany.java @@ -4,6 +4,8 @@ import java.awt.Color; import java.util.*; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import rails.common.GuiDef; import rails.common.LocalText; @@ -1046,7 +1048,7 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner // TODO: Check if this works correctly // move all laid tokens to free tokens again - PortfolioList.moveAll( + PortfolioSet.moveAll( baseTokens.getLaidTokens(), baseTokens.getFreeTokens()); // close company on the stock market stockMarket.close(this); @@ -1601,7 +1603,7 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner privatesCostThisTurn.change(price); // Move any special abilities to the portfolio, if configured so - List<SpecialProperty> sps = privateCompany.getSpecialProperties(); + Set<SpecialProperty> sps = privateCompany.getSpecialProperties(); if (sps != null) { // Need intermediate List to avoid ConcurrentModificationException List<SpecialProperty> spsToMoveHere = @@ -1818,7 +1820,7 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner public BaseToken getFreeToken() { if (baseTokens.getFreeTokens().size() > 0) { - return (BaseToken)baseTokens.getFreeTokens().items().get(0); + return (BaseToken) Iterables.get(baseTokens.getFreeTokens().items(), 0); } else { return null; } @@ -1854,7 +1856,7 @@ public class PublicCompany extends Company implements CashOwner, PortfolioOwner return list; } - public ImmutableList<Token> getLaidBaseTokens() { + public ImmutableSet<Token> getLaidBaseTokens() { return baseTokens.getLaidTokens().items(); } diff --git a/src/rails/game/Stop.java b/src/rails/game/Stop.java index 9c9607c..8f398b2 100644 --- a/src/rails/game/Stop.java +++ b/src/rails/game/Stop.java @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory; import rails.game.state.AbstractItem; import rails.game.state.GenericState; import rails.game.state.Owner; -import rails.game.state.PortfolioList; +import rails.game.state.PortfolioSet; import rails.util.Util; /** @@ -31,7 +31,7 @@ public class Stop extends AbstractItem implements Owner { //private Station relatedStation; private GenericState<Station> relatedStation; private int slots; - private PortfolioList<Token> tokens; + private PortfolioSet<Token> tokens; private String trackEdges; @@ -99,7 +99,7 @@ public class Stop extends AbstractItem implements Owner { super(hex, String.valueOf(number)); this.number = number; uniqueId = getParent().getId() + "_" + number; - tokens = PortfolioList.create(this, "tokens", Token.class); + tokens = PortfolioSet.create(this, "tokens", Token.class); relatedStation = GenericState.create(this, "City_"+uniqueId+"_station"); } @@ -232,7 +232,7 @@ public class Stop extends AbstractItem implements Owner { return uniqueId; } - public PortfolioList<Token> getTokens() { + public PortfolioSet<Token> getTokens() { return tokens; } diff --git a/src/rails/game/Train.java b/src/rails/game/Train.java index 8d2f027..6d64c58 100644 --- a/src/rails/game/Train.java +++ b/src/rails/game/Train.java @@ -9,8 +9,11 @@ import rails.game.state.GenericState; import rails.game.state.Item; import rails.game.state.OwnableItem; import rails.game.state.Portfolio; +import rails.game.state.Typable; -public class Train extends OwnableItem<Train> { +// FIXME: Trains a tricky as they can swap their type +// This change has to be tracked if used in a PortfolioMap +public class Train extends OwnableItem<Train> implements Typable<TrainType> { protected TrainCertificateType certificateType; diff --git a/src/rails/game/TrainManager.java b/src/rails/game/TrainManager.java index dd821c9..82b0469 100644 --- a/src/rails/game/TrainManager.java +++ b/src/rails/game/TrainManager.java @@ -4,8 +4,10 @@ package rails.game; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -331,9 +333,9 @@ public final class TrainManager extends AbstractItem implements ConfigurableComp } - public List<Train> getAvailableNewTrains() { + public Set<Train> getAvailableNewTrains() { - List<Train> availableTrains = new ArrayList<Train>(); + Set<Train> availableTrains = new HashSet<Train>(); Train train; for (TrainCertificateType type : trainCertTypes) { diff --git a/src/rails/game/action/BuyTrain.java b/src/rails/game/action/BuyTrain.java index ce341af..c70873b 100644 --- a/src/rails/game/action/BuyTrain.java +++ b/src/rails/game/action/BuyTrain.java @@ -1,14 +1,9 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/action/BuyTrain.java,v 1.22 2010/06/21 21:35:50 stefanfrey Exp $ - * - * Created on 20-May-2006 - * Change Log: - */ package rails.game.action; import java.io.IOException; import java.io.ObjectInputStream; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import rails.game.Bank; import rails.game.CompanyManager; @@ -34,7 +29,7 @@ public class BuyTrain extends PossibleORAction { private String fromName; private int fixedCost = 0; private boolean forcedBuyIfNoRoute = false; // TODO Can be disabled once route checking exists - transient private List<Train> trainsForExchange = null; + transient private Set<Train> trainsForExchange = null; private String[] trainsForExchangeUniqueIds; /** Obsolete, but left in for backwards compatibility of saved files */ @@ -79,13 +74,13 @@ public class BuyTrain extends PossibleORAction { this.typeName = type.getName(); } - public BuyTrain setTrainsForExchange(List<Train> trains) { + public BuyTrain setTrainsForExchange(Set<Train> trains) { trainsForExchange = trains; if (trains != null) { trainsForExchangeUniqueIds = new String[trains.size()]; - for (int i = 0; i < trains.size(); i++) { - trainsForExchangeUniqueIds[i] = trains.get(i).getId(); - // Must be replaced by unique Ids - why was this a todo? + int i = 0; + for (Train train:trains) { + trainsForExchangeUniqueIds[i++] = train.getId(); } } return this; @@ -165,7 +160,7 @@ public class BuyTrain extends PossibleORAction { return trainsForExchange != null && !trainsForExchange.isEmpty(); } - public List<Train> getTrainsForExchange() { + public Set<Train> getTrainsForExchange() { return trainsForExchange; } @@ -325,7 +320,7 @@ public class BuyTrain extends PossibleORAction { // from = gameManager.getPortfolioByName(fromName); if (trainsForExchangeUniqueIds != null && trainsForExchangeUniqueIds.length > 0) { - trainsForExchange = new ArrayList<Train>(); + trainsForExchange = new HashSet<Train>(); for (int i = 0; i < trainsForExchangeUniqueIds.length; i++) { trainsForExchange.add(trainManager.getTrainByUniqueId(trainsForExchangeUniqueIds[i])); } diff --git a/src/rails/game/action/DiscardTrain.java b/src/rails/game/action/DiscardTrain.java index 35b4f9f..9bb98e9 100644 --- a/src/rails/game/action/DiscardTrain.java +++ b/src/rails/game/action/DiscardTrain.java @@ -1,14 +1,9 @@ -/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/action/DiscardTrain.java,v 1.11 2009/12/27 18:30:11 evos Exp $ - * - * Created on 20-May-2006 - * Change Log: - */ package rails.game.action; import java.io.IOException; import java.io.ObjectInputStream; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import rails.game.*; @@ -18,7 +13,7 @@ import rails.game.*; public class DiscardTrain extends PossibleORAction { // Server settings - transient private List<Train> ownedTrains = null; + transient private Set<Train> ownedTrains = null; private String[] ownedTrainsUniqueIds; /** True if discarding trains is mandatory */ @@ -30,25 +25,26 @@ public class DiscardTrain extends PossibleORAction { public static final long serialVersionUID = 1L; - public DiscardTrain(PublicCompany company, List<Train> trains) { + public DiscardTrain(PublicCompany company, Set<Train> trains) { super(); this.ownedTrains = trains; this.ownedTrainsUniqueIds = new String[trains.size()]; - for (int i = 0; i < trains.size(); i++) { - ownedTrainsUniqueIds[i] = trains.get(i).getId(); + int i = 0; + for (Train train:trains) { + ownedTrainsUniqueIds[i++] = train.getId(); } this.company = company; this.companyName = company.getId(); } - public DiscardTrain(PublicCompany company, List<Train> trains, + public DiscardTrain(PublicCompany company, Set<Train> trainsToDiscardFrom, boolean forced) { - this(company, trains); + this(company, trainsToDiscardFrom); this.forced = forced; } - public List<Train> getOwnedTrains() { + public Set<Train> getOwnedTrains() { return ownedTrains; } @@ -110,7 +106,7 @@ public class DiscardTrain extends PossibleORAction { } if (ownedTrainsUniqueIds != null && ownedTrainsUniqueIds.length > 0) { - ownedTrains = new ArrayList<Train>(); + ownedTrains = new HashSet<Train>(); for (int i = 0; i < ownedTrainsUniqueIds.length; i++) { ownedTrains.add(trainManager.getTrainByUniqueId(ownedTrainsUniqueIds[i])); } diff --git a/src/rails/game/model/BaseTokensModel.java b/src/rails/game/model/BaseTokensModel.java index 5f487ac..c11e680 100644 --- a/src/rails/game/model/BaseTokensModel.java +++ b/src/rails/game/model/BaseTokensModel.java @@ -4,20 +4,20 @@ import rails.game.BaseToken; import rails.game.PublicCompany; import rails.game.Token; import rails.game.state.Model; -import rails.game.state.PortfolioList; +import rails.game.state.PortfolioSet; /** * A model presenting the number of tokens */ public class BaseTokensModel extends Model { - private final PortfolioList<Token> freeBaseTokens; - private final PortfolioList<Token> laidBaseTokens; + private final PortfolioSet<Token> freeBaseTokens; + private final PortfolioSet<Token> laidBaseTokens; private BaseTokensModel(PublicCompany parent, String id) { super(parent, id); - freeBaseTokens = PortfolioList.create(parent, "freeBaseTokens", Token.class); - laidBaseTokens = PortfolioList.create(parent, "laidBaseTokens", Token.class); + freeBaseTokens = PortfolioSet.create(parent, "freeBaseTokens", Token.class); + laidBaseTokens = PortfolioSet.create(parent, "laidBaseTokens", Token.class); } public static BaseTokensModel create(PublicCompany parent, String id){ @@ -46,11 +46,11 @@ public class BaseTokensModel extends Model { laidBaseTokens.moveInto(token); } - public PortfolioList<Token> getFreeTokens() { + public PortfolioSet<Token> getFreeTokens() { return freeBaseTokens; } - public PortfolioList<Token> getLaidTokens() { + public PortfolioSet<Token> getLaidTokens() { return laidBaseTokens; } diff --git a/src/rails/game/model/CertificatesModel.java b/src/rails/game/model/CertificatesModel.java index 5938b0c..76ccffc 100644 --- a/src/rails/game/model/CertificatesModel.java +++ b/src/rails/game/model/CertificatesModel.java @@ -2,7 +2,7 @@ package rails.game.model; import java.util.Iterator; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import rails.game.Player; import rails.game.PublicCertificate; @@ -23,7 +23,7 @@ public final class CertificatesModel extends Model { public final static String ID = "CertificatesModel"; - private final PortfolioMap<PublicCertificate> certificates; + private final PortfolioMap<PublicCompany, PublicCertificate> certificates; private CertificatesModel(PortfolioHolder parent) { super(parent, ID); @@ -39,7 +39,7 @@ public final class CertificatesModel extends Model { return (PortfolioHolder)getParent(); } - public PortfolioMap<PublicCertificate> getPortfolio() { + public PortfolioMap<PublicCompany, PublicCertificate> getPortfolio() { return certificates; } @@ -78,11 +78,11 @@ public final class CertificatesModel extends Model { return certificates.toString(); } - public ImmutableList<PublicCertificate> getCertificates() { + public ImmutableSet<PublicCertificate> getCertificates() { return certificates.items(); } - public ImmutableList<PublicCertificate> getCertificates(PublicCompany company) { + public ImmutableSet<PublicCertificate> getCertificates(PublicCompany company) { return certificates.getItems(company); } diff --git a/src/rails/game/model/PortfolioModel.java b/src/rails/game/model/PortfolioModel.java index a9901e5..96049e1 100644 --- a/src/rails/game/model/PortfolioModel.java +++ b/src/rails/game/model/PortfolioModel.java @@ -2,14 +2,17 @@ package rails.game.model; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; +import com.google.common.collect.ImmutableSet; import rails.common.LocalText; import rails.game.Bank; @@ -31,7 +34,7 @@ import rails.game.special.SpecialProperty; import rails.game.state.Model; import rails.game.state.PortfolioHolder; import rails.game.state.Portfolio; -import rails.game.state.PortfolioList; +import rails.game.state.PortfolioSet; // FIXME: Solve id, name and uniquename clashes @@ -57,7 +60,7 @@ public final class PortfolioModel extends Model implements PortfolioHolder { /** Owned tokens */ // TODO Currently only used to discard expired Bonus tokens. - private final Portfolio<Token> bonusTokens = PortfolioList.create(this, "BonusTokens", Token.class); + private final Portfolio<Token> bonusTokens = PortfolioSet.create(this, "BonusTokens", Token.class); /** * Private-independent special properties. When moved here, a special @@ -65,7 +68,7 @@ public final class PortfolioModel extends Model implements PortfolioHolder { * 18AL named train tokens. */ private final Portfolio<SpecialProperty> specialProperties = - PortfolioList.create(this, "SpecialProperties", SpecialProperty.class); + PortfolioSet.create(this, "SpecialProperties", SpecialProperty.class); private final GameManager gameManager; @@ -140,11 +143,11 @@ public final class PortfolioModel extends Model implements PortfolioHolder { return null; } - public ImmutableList<PrivateCompany> getPrivateCompanies() { + public ImmutableSet<PrivateCompany> getPrivateCompanies() { return privates.getPortfolio().items(); } - public ImmutableList<PublicCertificate> getCertificates() { + public ImmutableSet<PublicCertificate> getCertificates() { return certificates.getPortfolio().items(); } @@ -166,7 +169,7 @@ public final class PortfolioModel extends Model implements PortfolioHolder { } */ - public ImmutableList<PublicCertificate> getCertificates(PublicCompany company) { + public ImmutableSet<PublicCertificate> getCertificates(PublicCompany company) { return certificates.getPortfolio().getItems(company); } @@ -336,7 +339,7 @@ public final class PortfolioModel extends Model implements PortfolioHolder { return trains.getPortfolio().size(); } - public ImmutableList<Train> getTrainList() { + public ImmutableSet<Train> getTrainList() { return trains.getPortfolio().items(); } @@ -355,9 +358,9 @@ public final class PortfolioModel extends Model implements PortfolioHolder { } /** Returns one train of any type held */ - public List<Train> getUniqueTrains() { + public Set<Train> getUniqueTrains() { - List<Train> trainsFound = new ArrayList<Train>(); + Set<Train> trainsFound = new HashSet<Train>(); Map<TrainType, Object> trainTypesFound = new HashMap<TrainType, Object>(); for (Train train : trains.getPortfolio()) { @@ -506,9 +509,9 @@ public final class PortfolioModel extends Model implements PortfolioHolder { */ /** - * @return ArrayList of all special properties we have. + * @return Set of all special properties we have. */ - public ImmutableList<SpecialProperty> getPersistentSpecialProperties() { + public ImmutableSet<SpecialProperty> getPersistentSpecialProperties() { return specialProperties.items(); } @@ -542,7 +545,7 @@ public final class PortfolioModel extends Model implements PortfolioHolder { public <T extends SpecialProperty> List<T> getSpecialProperties( Class<T> clazz, boolean includeExercised) { List<T> result = new ArrayList<T>(); - List<SpecialProperty> sps; + Set<SpecialProperty> sps; if (getParent() instanceof Player || getParent() instanceof PublicCompany) { diff --git a/src/rails/game/model/PrivatesModel.java b/src/rails/game/model/PrivatesModel.java index 055d2a5..86ad87d 100644 --- a/src/rails/game/model/PrivatesModel.java +++ b/src/rails/game/model/PrivatesModel.java @@ -5,7 +5,7 @@ import rails.game.PrivateCompany; import rails.game.state.Model; import rails.game.state.Portfolio; import rails.game.state.PortfolioHolder; -import rails.game.state.PortfolioList; +import rails.game.state.PortfolioSet; public final class PrivatesModel extends Model { @@ -17,7 +17,7 @@ public final class PrivatesModel extends Model { private PrivatesModel(PortfolioHolder parent, String id) { super(parent, id); - privates = PortfolioList.create(parent, "privates", PrivateCompany.class); + privates = PortfolioSet.create(parent, "privates", PrivateCompany.class); } /** diff --git a/src/rails/game/model/TrainsModel.java b/src/rails/game/model/TrainsModel.java index b266a23..a8f6289 100644 --- a/src/rails/game/model/TrainsModel.java +++ b/src/rails/game/model/TrainsModel.java @@ -1,21 +1,24 @@ package rails.game.model; import com.google.common.collect.HashMultiset; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multiset; import rails.game.TrainCertificateType; import rails.game.Train; +import rails.game.TrainType; import rails.game.state.Model; import rails.game.state.Portfolio; import rails.game.state.PortfolioHolder; import rails.game.state.PortfolioMap; +// FIXME: It is tricky to use the PortfolioMap as the TrainType can switch +// their type, potentially it is better to use a PortfolioSet public class TrainsModel extends Model { public static final String ID = "TrainsModel"; - private final PortfolioMap<Train> trains; + private final PortfolioMap<TrainType, Train> trains; private boolean abbrList = false; @@ -39,7 +42,7 @@ public class TrainsModel extends Model { this.abbrList = abbrList; } - public ImmutableList<Train> getTrains() { + public ImmutableSet<Train> getTrains() { return trains.items(); } diff --git a/src/rails/game/specific/_1835/OperatingRound_1835.java b/src/rails/game/specific/_1835/OperatingRound_1835.java index 18b8e0c..5f8d738 100644 --- a/src/rails/game/specific/_1835/OperatingRound_1835.java +++ b/src/rails/game/specific/_1835/OperatingRound_1835.java @@ -2,6 +2,8 @@ package rails.game.specific._1835; import java.util.*; +import com.google.common.collect.Iterables; + import rails.common.DisplayBuffer; import rails.common.LocalText; import rails.common.parser.GameOption; @@ -81,7 +83,7 @@ public final class OperatingRound_1835 extends OperatingRound { * so it can be subtracted if PR operates */ if (recipient instanceof Player && priv.getSpecialProperties() != null && priv.getSpecialProperties().size() > 0) { - SpecialProperty sp = priv.getSpecialProperties().get(0); + SpecialProperty sp = Iterables.get(priv.getSpecialProperties(), 0); if (sp instanceof ExchangeForShare) { ExchangeForShare efs = (ExchangeForShare) sp; if (efs.getPublicCompanyName().equalsIgnoreCase(GameManager_1835.PR_ID)) { @@ -144,9 +146,9 @@ public final class OperatingRound_1835 extends OperatingRound { super.initTurn(); - List<SpecialProperty> sps = operatingCompany.value().getSpecialProperties(); + Set<SpecialProperty> sps = operatingCompany.value().getSpecialProperties(); if (sps != null && !sps.isEmpty()) { - ExchangeForShare efs = (ExchangeForShare) sps.get(0); + ExchangeForShare efs = (ExchangeForShare) Iterables.get(sps, 0); addIncomeDenialShare (operatingCompany.value().getPresident(), efs.getShare()); } } diff --git a/src/rails/game/specific/_1835/PrussianFormationRound.java b/src/rails/game/specific/_1835/PrussianFormationRound.java index 835f4be..6ced1eb 100644 --- a/src/rails/game/specific/_1835/PrussianFormationRound.java +++ b/src/rails/game/specific/_1835/PrussianFormationRound.java @@ -2,6 +2,8 @@ package rails.game.specific._1835; import java.util.*; +import com.google.common.collect.Iterables; + import rails.common.DisplayBuffer; import rails.common.GuiDef; import rails.common.LocalText; @@ -79,19 +81,19 @@ public final class PrussianFormationRound extends StockRound { log.debug("Original Prussian starting player was "+startingPlayer.getId()); setCurrentPlayer(startingPlayer); if (forcedMerge) { - List<SpecialProperty> sps; + Set<SpecialProperty> sps; setFoldablePrePrussians(); List<Company> foldables = new ArrayList<Company> (); for (PrivateCompany company : gameManager.getAllPrivateCompanies()) { sps = company.getSpecialProperties(); - if (sps != null && !sps.isEmpty() && sps.get(0) instanceof ExchangeForShare) { + if (sps != null && !sps.isEmpty() && Iterables.get(sps, 0) instanceof ExchangeForShare) { foldables.add(company); } } for (PublicCompany company : gameManager.getAllPublicCompanies()) { if (company.isClosed()) continue; sps = company.getSpecialProperties(); - if (sps != null && !sps.isEmpty() && sps.get(0) instanceof ExchangeForShare) { + if (sps != null && !sps.isEmpty() && Iterables.get(sps, 0) instanceof ExchangeForShare) { foldables.add(company); } } @@ -135,18 +137,18 @@ public final class PrussianFormationRound extends StockRound { foldablePrePrussians = new ArrayList<Company> (); SpecialProperty sp; for (PrivateCompany company : currentPlayer.getPortfolioModel().getPrivateCompanies()) { - sp = company.getSpecialProperties().get(0); + sp = Iterables.get(company.getSpecialProperties(), 0); if (sp instanceof ExchangeForShare) { foldablePrePrussians.add(company); } } PublicCompany company; - List<SpecialProperty> sps; + Set<SpecialProperty> sps; for (PublicCertificate cert : currentPlayer.getPortfolioModel().getCertificates()) { if (!cert.isPresidentShare()) continue; company = cert.getCompany(); sps = company.getSpecialProperties(); - if (sps != null && !sps.isEmpty() && sps.get(0) instanceof ExchangeForShare) { + if (sps != null && !sps.isEmpty() && Iterables.get(sps, 0) instanceof ExchangeForShare) { foldablePrePrussians.add(company); } } @@ -321,7 +323,7 @@ public final class PrussianFormationRound extends StockRound { player = ((PublicCompany)company).getPresident(); } // Shortcut, sp should be checked - efs = (ExchangeForShare) company.getSpecialProperties().get(0); + efs = (ExchangeForShare) Iterables.get(company.getSpecialProperties(), 0); cert = unavailable.findCertificate(prussian, efs.getShare()/prussian.getShareUnit(), president); player.getPortfolioModel().addPublicCertificate(cert); diff --git a/src/rails/game/specific/_1856/CGRFormationRound.java b/src/rails/game/specific/_1856/CGRFormationRound.java index a2ea45d..7283e94 100644 --- a/src/rails/game/specific/_1856/CGRFormationRound.java +++ b/src/rails/game/specific/_1856/CGRFormationRound.java @@ -34,7 +34,7 @@ public final class CGRFormationRound extends SwitchableUIRound { * effects from the merger, processed at the end * thus no need for state variables */ - private List<Train> trainsToDiscardFrom = null; + private Set<Train> trainsToDiscardFrom = null; private boolean forcedTrainDiscard = true; private List<ExchangeableToken> tokensToExchangeFrom = null; private List<BaseToken> nonHomeTokens = null; @@ -556,7 +556,7 @@ public final class CGRFormationRound extends SwitchableUIRound { } // Move any remaining trains - List<Train> trains = comp.getPortfolioModel().getTrainList(); + Set<Train> trains = comp.getPortfolioModel().getTrainList(); for (Train train : trains) { cgr.getPortfolioModel().addTrain(train); if (train.isPermanent()) cgr.setHadPermanentTrain(true); @@ -668,7 +668,7 @@ bonuses: for (Bonus bonus : bonuses) { // Check the trains, autodiscard any excess non-permanent trains // int trainLimit = cgr.getTrainLimit(gameManager.getCurrentPlayerIndex()); int trainLimit = cgr.getCurrentTrainLimit(); - List<Train> trains = cgr.getPortfolioModel().getTrainList(); + Set<Train> trains = cgr.getPortfolioModel().getTrainList(); if (cgr.getNumberOfTrains() > trainLimit) { ReportBuffer.add(""); int numberToDiscard = cgr.getNumberOfTrains() - trainLimit; @@ -770,7 +770,7 @@ bonuses: for (Bonus bonus : bonuses) { } else if (!this.cgrHasDiscardedTrains.value()) { // Check if CGR still has non-permanent trains // these may be discarded voluntarily - trainsToDiscardFrom = new ArrayList<Train>(); + trainsToDiscardFrom = new HashSet<Train>(); for (Train train : cgr.getPortfolioModel().getTrainList()) { if (!train.isPermanent()) { trainsToDiscardFrom.add(train); diff --git a/src/rails/game/specific/_1856/OperatingRound_1856.java b/src/rails/game/specific/_1856/OperatingRound_1856.java index 9c0981e..6c40d6d 100644 --- a/src/rails/game/specific/_1856/OperatingRound_1856.java +++ b/src/rails/game/specific/_1856/OperatingRound_1856.java @@ -3,6 +3,8 @@ package rails.game.specific._1856; import java.util.ArrayList; import java.util.List; +import com.google.common.collect.Iterables; + import rails.common.DisplayBuffer; import rails.common.GuiDef; import rails.common.LocalText; @@ -66,7 +68,7 @@ public class OperatingRound_1856 extends OperatingRound { if (!operatingCompany.value().hasOperated()) { int soldPercentage = getSoldPercentage (operatingCompany.value()); - Train nextAvailableTrain = gameManager.getTrainManager().getAvailableNewTrains().get(0); + Train nextAvailableTrain = Iterables.get(gameManager.getTrainManager().getAvailableNewTrains(), 0); int trainNumber; try { trainNumber = Integer.parseInt(nextAvailableTrain.getId()); diff --git a/src/rails/game/specific/_1856/PublicCompany_1856.java b/src/rails/game/specific/_1856/PublicCompany_1856.java index 0eec963..6625635 100644 --- a/src/rails/game/specific/_1856/PublicCompany_1856.java +++ b/src/rails/game/specific/_1856/PublicCompany_1856.java @@ -1,5 +1,7... [truncated message content] |
From: Stefan F. <ste...@us...> - 2012-07-26 06:06:32
|
junit/rails/game/state/ArrayListMultimapStateTest.java | 89 ++++++ junit/rails/game/state/ArrayListStateTest.java | 12 junit/rails/game/state/BooleanStateTest.java | 16 - junit/rails/game/state/FormatterTest.java | 60 ---- junit/rails/game/state/GenericStateTest.java | 16 - junit/rails/game/state/HashMapStateTest.java | 9 junit/rails/game/state/HashMultimapStateTest.java | 185 ++++++++++++++ junit/rails/game/state/HashSetStateTest.java | 9 junit/rails/game/state/IntegerStateTest.java | 14 - junit/rails/game/state/OwnableItemImpl.java | 16 + junit/rails/game/state/OwnerImpl.java | 22 + junit/rails/game/state/PortfolioListTest.java | 114 ++++++++ junit/rails/game/state/PortfolioManagerTest.java | 104 +++++++ junit/rails/game/state/StateTestUtils.java | 22 + junit/rails/game/state/StringStateTest.java | 22 - src/rails/game/Bank.java | 17 - src/rails/game/BankPortfolio.java | 6 src/rails/game/BonusToken.java | 4 src/rails/game/Company.java | 10 src/rails/game/CompanyManager.java | 2 src/rails/game/GameManager.java | 5 src/rails/game/MapHex.java | 9 src/rails/game/OperatingRound.java | 3 src/rails/game/Player.java | 3 src/rails/game/PrivateCompany.java | 28 -- src/rails/game/PublicCertificate.java | 4 src/rails/game/PublicCompany.java | 32 +- src/rails/game/Round.java | 15 - src/rails/game/StartItem.java | 10 src/rails/game/StockRound.java | 12 src/rails/game/Stop.java | 6 src/rails/game/Token.java | 2 src/rails/game/Train.java | 5 src/rails/game/TrainManager.java | 11 src/rails/game/TreasuryShareRound.java | 2 src/rails/game/action/BuyBonusToken.java | 2 src/rails/game/action/BuyCertificate.java | 9 src/rails/game/action/BuyPrivate.java | 2 src/rails/game/action/BuyTrain.java | 5 src/rails/game/model/BaseTokensModel.java | 4 src/rails/game/model/CertificatesModel.java | 2 src/rails/game/model/PortfolioModel.java | 7 src/rails/game/model/PrivatesModel.java | 2 src/rails/game/model/TrainsModel.java | 2 src/rails/game/special/ExchangeForShare.java | 2 src/rails/game/special/SpecialProperty.java | 2 src/rails/game/special/SpecialRight.java | 2 src/rails/game/specific/_1835/PrussianFormationRound.java | 2 src/rails/game/specific/_1835/StockRound_1835.java | 2 src/rails/game/specific/_1856/OperatingRound_1856.java | 2 src/rails/game/specific/_1856/PublicCompany_CGR.java | 6 src/rails/game/specific/_1856/StockRound_1856.java | 4 src/rails/game/specific/_1889/OperatingRound_1889.java | 8 src/rails/game/specific/_18EU/GameManager_18EU.java | 3 src/rails/game/specific/_18EU/StockRound_18EU.java | 9 src/rails/game/specific/_18TN/OperatingRound_18TN.java | 2 src/rails/game/state/ArrayListMultimapChange.java | 48 +++ src/rails/game/state/ArrayListMultimapState.java | 18 - src/rails/game/state/ArrayListState.java | 10 src/rails/game/state/ChangeStack.java | 1 src/rails/game/state/DelayedItem.java | 8 src/rails/game/state/Formatter.java | 23 - src/rails/game/state/HashMapState.java | 5 src/rails/game/state/HashMultimapChange.java | 37 ++ src/rails/game/state/HashMultimapState.java | 25 + src/rails/game/state/Manager.java | 6 src/rails/game/state/MultimapChange.java | 37 -- src/rails/game/state/MultimapState.java | 18 - src/rails/game/state/Observable.java | 3 src/rails/game/state/Ownable.java | 13 src/rails/game/state/OwnableItem.java | 45 ++- src/rails/game/state/OwnableManager.java | 5 src/rails/game/state/Portfolio.java | 54 ++-- src/rails/game/state/PortfolioChange.java | 2 src/rails/game/state/PortfolioHolder.java | 10 src/rails/game/state/PortfolioList.java | 32 +- src/rails/game/state/PortfolioManager.java | 81 +++++- src/rails/game/state/PortfolioMap.java | 23 - src/rails/game/state/Root.java | 31 +- src/rails/game/state/StateManager.java | 26 - src/rails/game/state/UnknownOwner.java | 17 + src/rails/ui/swing/GameStatus.java | 22 - src/rails/ui/swing/ORUIManager.java | 2 83 files changed, 1102 insertions(+), 475 deletions(-) New commits: commit 428eefc5b1ebcd1f7b33634512b1a671f539f320 Author: Stefan Frey <ste...@we...> Date: Thu Jul 26 07:31:26 2012 +0200 refined MultiMap states and added tests diff --git a/junit/rails/game/state/ArrayListMultimapStateTest.java b/junit/rails/game/state/ArrayListMultimapStateTest.java new file mode 100644 index 0000000..2960dbb --- /dev/null +++ b/junit/rails/game/state/ArrayListMultimapStateTest.java @@ -0,0 +1,89 @@ +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 ArrayListMultimapStateTest { + + private final static String STATE_ID = "State"; + private final static String ITEM_A_ID = "ItemA"; + private final static String ITEM_B_ID = "ItemB"; + private final static String ITEM_C_ID = "ItemC"; + + private Root root; + private ArrayListMultimapState<String, Item> state; + private Item itemA, itemB, itemC; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + state = ArrayListMultimapState.create(root, STATE_ID); + itemA = OwnableItemImpl.create(root, ITEM_A_ID); + itemB = OwnableItemImpl.create(root, ITEM_B_ID); + itemC = OwnableItemImpl.create(root, ITEM_C_ID); + StateTestUtils.startActionChangeSet(root); + } + + @Test + public void testPut() { + state.put(ITEM_A_ID, itemA); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA); + state.put(ITEM_A_ID, itemA); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemA, itemA); + state.put(ITEM_A_ID, itemB); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemA, itemA, itemB); + // test undo + StateTestUtils.closeAndUndo(root); + assertTrue(state.isEmpty()); + // test redo + StateTestUtils.redo(root); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemA, itemA, itemB); + } + + @Test + public void testRemove() { + // initialize state + state.put(ITEM_A_ID, itemA); + state.put(ITEM_A_ID, itemB); + state.put(ITEM_A_ID, itemA); + StateTestUtils.startActionChangeSet(root); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemA, itemB, itemA); + // remove items + state.remove(ITEM_A_ID, itemA); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemB, itemA); + state.remove(ITEM_A_ID, itemA); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemB); + // test undo + StateTestUtils.closeAndUndo(root); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemA, itemB, itemA); + // test redo + StateTestUtils.redo(root); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemB); + } + + @Test + public void testGet() { + state.put(ITEM_A_ID, itemA); + state.put(ITEM_A_ID, itemB); + state.put(ITEM_C_ID, itemC); + assertThat(state.get(ITEM_A_ID)).containsExactly(itemA, itemB); + assertThat(state.get(ITEM_C_ID)).containsExactly(itemC); + } + + @Test + public void testContainsEntry() { + state.put(ITEM_A_ID, itemA); + state.put(ITEM_C_ID, itemB); + assertTrue(state.containsEntry(ITEM_A_ID, itemA)); + assertTrue(state.containsEntry(ITEM_C_ID, itemB)); + + assertFalse(state.containsEntry(ITEM_B_ID, itemA)); + assertFalse(state.containsEntry(ITEM_A_ID, itemB)); + assertFalse(state.containsEntry(ITEM_B_ID, itemB)); + assertFalse(state.containsEntry(ITEM_C_ID, itemC)); + } + +} diff --git a/junit/rails/game/state/HashMultimapStateTest.java b/junit/rails/game/state/HashMultimapStateTest.java new file mode 100644 index 0000000..67a91a1 --- /dev/null +++ b/junit/rails/game/state/HashMultimapStateTest.java @@ -0,0 +1,185 @@ +package rails.game.state; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.junit.Assert.*; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +public class HashMultimapStateTest { + + private final static String STATE_ID = "State"; + private final static String ITEM_A_ID = "ItemA"; + private final static String ITEM_B_ID = "ItemB"; + private final static String ITEM_C_ID = "ItemC"; + + private Root root; + private HashMultimapState<String, Item> state; + private Item itemA, itemB, itemC; + private List<Item> initContents; + + @Before + public void setUp() { + root = StateTestUtils.setUpRoot(); + state = HashMultimapState.create(root, STATE_ID); + itemA = OwnableItemImpl.create(root, ITEM_A_ID); + itemB = OwnableItemImpl.create(root, ITEM_B_ID); + itemC = OwnableItemImpl.create(root, ITEM_C_ID); + StateTestUtils.startActionChangeSet(root); + } + + private void initState() { + // initialize state + state.put(ITEM_A_ID, itemA); + state.put(ITEM_A_ID, itemB); + state.put(ITEM_A_ID, itemC); + state.put(ITEM_B_ID, itemB); + state.put(ITEM_C_ID, itemC); + StateTestUtils.startActionChangeSet(root); + initContents = Lists.newArrayList(itemA, itemB, itemC, itemB, itemC); + } + + @Test + public void testPut() { + state.put(ITEM_A_ID, itemA); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA); + assertFalse(state.put(ITEM_A_ID, itemA)); // cannot add identical tuple + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA); + state.put(ITEM_A_ID, itemB); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA, itemB); + // test undo + StateTestUtils.closeAndUndo(root); + assertTrue(state.isEmpty()); + // test redo + StateTestUtils.redo(root); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA, itemB); + } + + @Test + public void testRemove() { + initState(); + // remove items + state.remove(ITEM_A_ID, itemA); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemB, itemC); + state.remove(ITEM_A_ID, itemC); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemB); + // test undo + StateTestUtils.closeAndUndo(root); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA, itemB, itemC); + // test redo + StateTestUtils.redo(root); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemB); + } + + @Test + public void testRemoveAll() { + initState(); + Set<Item> removed = state.removeAll(ITEM_A_ID); + assertThat(removed).containsOnly(itemA, itemB, itemC); + assertThat(state.get(ITEM_A_ID)).isEmpty(); + // test undo + StateTestUtils.closeAndUndo(root); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA, itemB, itemC); + // test redo + StateTestUtils.redo(root); + assertThat(state.get(ITEM_A_ID)).isEmpty(); + } + + @Test + public void testGet() { + initState(); + assertThat(state.get(ITEM_A_ID)).containsOnly(itemA, itemB, itemC); + assertThat(state.get(ITEM_C_ID)).containsOnly(itemC); + } + + @Test + public void testContainsEntry() { + state.put(ITEM_A_ID, itemA); + state.put(ITEM_C_ID, itemB); + assertTrue(state.containsEntry(ITEM_A_ID, itemA)); + assertTrue(state.containsEntry(ITEM_C_ID, itemB)); + + assertFalse(state.containsEntry(ITEM_B_ID, itemA)); + assertFalse(state.containsEntry(ITEM_A_ID, itemB)); + assertFalse(state.containsEntry(ITEM_B_ID, itemB)); + assertFalse(state.containsEntry(ITEM_C_ID, itemC)); + } + + @Test + public void testContainsKey() { + state.put(ITEM_A_ID, itemA); + state.put(ITEM_C_ID, itemB); + assertTrue(state.containsKey(ITEM_A_ID)); + assertFalse(state.containsKey(ITEM_B_ID)); + assertTrue(state.containsKey(ITEM_C_ID)); + } + + @Test + public void testContainsValue() { + state.put(ITEM_A_ID, itemA); + state.put(ITEM_C_ID, itemB); + assertTrue(state.containsValue(itemA)); + assertTrue(state.containsValue(itemB)); + assertFalse(state.containsValue(itemC)); + } + + @Test + public void testSize() { + assertEquals(0, state.size()); + initState(); + assertEquals(5, state.size()); + } + + @Test + public void testIsEmpty() { + assertTrue(state.isEmpty()); + initState(); + assertFalse(state.isEmpty()); + } + + @Test + public void testKeySet() { + state.put(ITEM_A_ID, itemA); + state.put(ITEM_C_ID, itemB); + assertThat(state.keySet()).containsOnly(ITEM_A_ID, ITEM_C_ID); + } + + @Test + public void testValues() { + initState(); + assertThat(state.values()).containsAll(initContents); + } + + private void assertTestIterator(Item thirdItem) { + // no order is defined, so store them + Set<Item> iterated = Sets.newHashSet(); + + Iterator<Item> it = state.iterator(); + while (it.hasNext()) { + iterated.add(it.next()); + } + assertThat(iterated).containsAll(initContents); + // iterator is an immutable copy, thus not changed by adding a new item + state.put(ITEM_C_ID, itemA); + assertFalse(it.hasNext()); + // remove the last added item + state.remove(ITEM_C_ID, itemA); + } + + @Test + public void testIterator() { + initState(); + Item thirdItem = AbstractItemImpl.create(root, "Third"); + assertTestIterator(thirdItem); + } + + + +} diff --git a/src/rails/game/state/ArrayListMultimapChange.java b/src/rails/game/state/ArrayListMultimapChange.java new file mode 100644 index 0000000..5d10ee0 --- /dev/null +++ b/src/rails/game/state/ArrayListMultimapChange.java @@ -0,0 +1,48 @@ +package rails.game.state; + +final class ArrayListMultimapChange<K,V> extends Change { + private final ArrayListMultimapState<K,V> state; + private final K key; + private final V value; + private final int index; + private final boolean addToList; + + ArrayListMultimapChange(ArrayListMultimapState<K,V> state, K key, V value, int index) { + this.state = state; + this.key = key; + this.value = value; + this.index = index; + this.addToList = true; + super.init(state); + } + + ArrayListMultimapChange(ArrayListMultimapState<K,V> state, K key, int index) { + this.state = state; + this.key = key; + this.value = state.get(key).get(index); + this.index = index; + this.addToList = false; + super.init(state); + } + + @Override void execute() { + state.change(key, value, index, addToList); + } + + @Override void undo() { + state.change(key, value, index, !addToList); + } + + @Override ArrayListMultimapState<K,V> getState() { + return state; + } + + @Override + public String toString() { + if (addToList) { + return "Change for " + state + ": Add key = " + key + " with value " + value + " at index " + index; + } else { + return "Change for " + state + ": Remove object with key = " + key + " at index " + index ; + } + } +} diff --git a/src/rails/game/state/ArrayListMultimapState.java b/src/rails/game/state/ArrayListMultimapState.java index 8dd69c1..3e3c7aa 100644 --- a/src/rails/game/state/ArrayListMultimapState.java +++ b/src/rails/game/state/ArrayListMultimapState.java @@ -4,7 +4,7 @@ import java.util.List; import com.google.common.collect.ArrayListMultimap; -public final class ArrayListMultimapState<K,V> extends MultimapState<K,V> { +public final class ArrayListMultimapState<K,V> extends State { private final ArrayListMultimap<K,V> map = ArrayListMultimap.create(); ; @@ -27,7 +27,7 @@ public final class ArrayListMultimapState<K,V> extends MultimapState<K,V> { */ public boolean put(K key, V value) { - |