From 073726b357996f213863af05c0434fa5095c0316 Mon Sep 17 00:00:00 2001 From: astrid Date: Fri, 18 Oct 2024 18:00:15 +0200 Subject: [PATCH 1/9] Espionage Description --- Programs/Games/Espionage/Espionage.md | 59 +++++++++++++++++++++++++ Programs/Games/Espionage/Espionage.png | Bin 0 -> 32338 bytes 2 files changed, 59 insertions(+) create mode 100644 Programs/Games/Espionage/Espionage.md create mode 100644 Programs/Games/Espionage/Espionage.png diff --git a/Programs/Games/Espionage/Espionage.md b/Programs/Games/Espionage/Espionage.md new file mode 100644 index 0000000..b26b275 --- /dev/null +++ b/Programs/Games/Espionage/Espionage.md @@ -0,0 +1,59 @@ +# Espionage + +## The Game +This is a boardgame roughly based on the Rock Paper Scissor idea. +The more SecretCards you can capture, the faster you will move forward on the board. + + +Each round consist of three phases: +* All the players are divided into two groups. + + +* Group 1 fight each other to get one of the two displayed secret cards on the board. +The player using the highest bribe will get the card. +An agent can steal this bribe - but only if it is the only agent in the group. + + +* Group 2 fight each other to make the most progress on the board (and to steal SecretCards from each other!). +If you have enough SecretCards you can choose to Report. +The players with the two best Reports will move forward on the board. But beware... +the Agents will steal your cards if there is not a Counter-espionage present. +If there IS a counter-espionage, all the agents will fail and become prisoners +and the counter-espionage players will move forward... + + +## The Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EspionageProgram main w GUI Frame and Menu
PlayerKeeps track of the player's hand of cards and the current position on the board.
BattleHolds the Game Logic
BoardConsists mainly of a paint method that draws the board and the Player's hand of cards.
ActionCardEach player has a set of ActionCards used to select next action.
SecretCardThis is the wanted treasure!
ReportUtilUtility to get all possible Reports from the player's hand of SecretCards - returns the best one.
+ +## A Screenshot + +![Espionage](https://github.com/agrvsk/Java/blob/master/Espionage.png) diff --git a/Programs/Games/Espionage/Espionage.png b/Programs/Games/Espionage/Espionage.png new file mode 100644 index 0000000000000000000000000000000000000000..806561aeb3144426e548cc08aae14e937ca4eb9d GIT binary patch literal 32338 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 Date: Fri, 18 Oct 2024 18:15:34 +0200 Subject: [PATCH 2/9] Espionage Description --- Programs/Games/Espionage/Espionage.md | 2 +- README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Programs/Games/Espionage/Espionage.md b/Programs/Games/Espionage/Espionage.md index b26b275..edcb31b 100644 --- a/Programs/Games/Espionage/Espionage.md +++ b/Programs/Games/Espionage/Espionage.md @@ -56,4 +56,4 @@ and the counter-espionage players will move forward... ## A Screenshot -![Espionage](https://github.com/agrvsk/Java/blob/master/Espionage.png) +![Espionage](https://github.com/agrvsk/Java/Programs/Games/Espionage/blob/master/Espionage.png) diff --git a/README.md b/README.md index cb3d676..680a3fb 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ It is very easy to contribute, you may follow these steps - 99.[RotateLinkedList](https://github.com/PrajaktaSathe/Java/blob/main/Programs/RotateLinkedList.java)-Program to demo rotating a linked list 100. [ReverseString](https://github.com/PrajaktaSathe/Java/blob/main/ReverseString.java) -Program to reverse a String using the java method substring. 101.[Overriding](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Overriding.java)-Program to demo overriding in java +102.[Espionage](https://github.com/agrvsk/Java/blob/main/Programs/Games/Espionage/) - Espionage Game # Contributors - ## A big thank you to all our contributors!!! From 736de2e36a3c5f2262c935f4563536466327c60a Mon Sep 17 00:00:00 2001 From: astrid Date: Mon, 21 Oct 2024 09:18:30 +0200 Subject: [PATCH 3/9] Espionage Description --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 680a3fb..bd1e1f2 100644 --- a/README.md +++ b/README.md @@ -122,11 +122,11 @@ It is very easy to contribute, you may follow these steps - 95. [Strassen's Multiplication](https://github.com/PrajaktaSathe/Java/blob/main/Programs/StrassensMultiplication.java) - Program to multiply two square matrices using Strassen's Multiplication method. 96. [Xor Palindrome](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Xorpalindrome.java) - Program/Solution to Xor Palindrome 97. [Streams API](./Programs/JavaStreams.java) - Program to demo the Java Stream API with String and Integer Lists. -98.[Stack](https://github.com/PrajaktaSathe/Java/blob/main/Stack.java)-Program to demo the stack implementation -99.[RotateLinkedList](https://github.com/PrajaktaSathe/Java/blob/main/Programs/RotateLinkedList.java)-Program to demo rotating a linked list +98. [Stack](https://github.com/PrajaktaSathe/Java/blob/main/Stack.java)-Program to demo the stack implementation +99. [RotateLinkedList](https://github.com/PrajaktaSathe/Java/blob/main/Programs/RotateLinkedList.java)-Program to demo rotating a linked list 100. [ReverseString](https://github.com/PrajaktaSathe/Java/blob/main/ReverseString.java) -Program to reverse a String using the java method substring. -101.[Overriding](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Overriding.java)-Program to demo overriding in java -102.[Espionage](https://github.com/agrvsk/Java/blob/main/Programs/Games/Espionage/) - Espionage Game +101. [Overriding](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Overriding.java)-Program to demo overriding in java +102. [Espionage](https://github.com/agrvsk/Java/blob/main/Programs/Games/Espionage/) - Espionage Game # Contributors - ## A big thank you to all our contributors!!! From 8c57c03c27f02bb23e6d6b27fa20366da557f12e Mon Sep 17 00:00:00 2001 From: astrid Date: Mon, 21 Oct 2024 09:24:45 +0200 Subject: [PATCH 4/9] Espionage Description --- Programs/Games/Espionage/Espionage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Programs/Games/Espionage/Espionage.md b/Programs/Games/Espionage/Espionage.md index edcb31b..d376881 100644 --- a/Programs/Games/Espionage/Espionage.md +++ b/Programs/Games/Espionage/Espionage.md @@ -56,4 +56,4 @@ and the counter-espionage players will move forward... ## A Screenshot -![Espionage](https://github.com/agrvsk/Java/Programs/Games/Espionage/blob/master/Espionage.png) +![Espionage](https://github.com/agrvsk/Java/blob/main/Programs/Games/Espionage/Espionage.png) From 500d4ec794104530c8827059d369594ee6c13b34 Mon Sep 17 00:00:00 2001 From: astrid Date: Mon, 21 Oct 2024 09:41:58 +0200 Subject: [PATCH 5/9] Espionage Description --- Programs/Games/Espionage/Espionage.png | Bin 32338 -> 25366 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Programs/Games/Espionage/Espionage.png b/Programs/Games/Espionage/Espionage.png index 806561aeb3144426e548cc08aae14e937ca4eb9d..e9cf58dfe502f374c53b2da541566309833ff144 100644 GIT binary patch literal 25366 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 R^ml|c&;{SGx%c#+{{x7IVTS+! literal 32338 zcmYhi1y~f{_c**DAc!=Af`oJmN=bv#vY?HCb>g*2Lu9E+(!qyYzzv?YJXjtCs)!=KF~bM$i9V?4eFT9>JFvev-A+F&Kp@`@RR#Gs z9>#kML``g#o|~A0;>Mw;yh69`a1n;+?Stb(nC}V-_211>YJUCkR%jTp68Qb`6S|9_ zuFhf(F?ST(V%_bP0I}aj@nAW*oRJ?#i>v6sEK_PdE9sBxX^Yz!nTfNELT&8@Bka%F z`GL1bN@??A(RR_r)A z=#~?tMj(kvN&VC8M+W>U=_w*BL%mCRU8b;^ln3HI9#4`pHJs1_mP7r0-wd3D`!{}7 zRhiWDWo*HlnjYR5l<4Fcm%Z%!R-l#_`=+RY@vTrz@)l29`IiR;hJ`)HqrbKs)pBNH z)w=qH(lnCRQapFy?CE6>YITb7QIkLQSiR48V^Ulct<)Lmt$bbIaVKk8{QlW^K6W za`yNo3oY!w73vp4mcFmCuAGVP>i8PqTQH|JrFxOz*nNIu*XFwCpht3^@E9RB*Qj68 zlcr}}T*1egacCosIx0{Z_?gKl1ar5gubN_TezpD>SE zA`EkW)Bv05TPk3U{k_A*{SlIXQ1$w5W&TouXk+Hs@xamRTlrKwo;Ce50;ZEw>=K4s9lQqP9Zi#m#)lbqvi$VFMwq1kT+KQZsQr)s8 z&^eE^FU&T|#iH|VTyDzer#YYA&E-67K6e;txzrbe{Q>z3|;Cr^|;jQ7XOv-Nor#8&xn}>lsPRa?_|^tJgn(` zyOPkV=_yz+`0?0{U77c639F54bAIgxeWbP4n0=B}&I9|v1ijQfEuu2iUaqI3iSC|j zn@`8pv|sg2mMSE}{z^XS$K23GhnW?$!6^Vm^%E{VJB!)I1fD&yrZK7^o!a_z#VJ)T;v9IOCHSU$Vk_{wQn~e9bHF{KB&u`bPU|Anfb)c4cQK=OHB3A|z`XA+VF5R4 zo=V^jE)o1~Y_*-W#n_Xb)%qdd{4}>&ZkKCF!JkC_)H!op?bROwo6NhkV~oN$7IxaUgC_|V$i7L9Hbu~#tjp-x=!E1M|?ZU!n2T~QVcxiZ{y$y`;G6NBHWX zx0o7^7NJ_>kCHgsCZV6~iQL=hNnJdo(}P2eo=FHce`(3TclsyiYCq8(H+1CJ z99&ne7;zL+vMFOOd)i8X>!RsIa+xPI6nz_dOyzml_BFtOCBQ1O+i`|jpy5WWeZ+sO z3!f=&_`un^`yk<`hZsko@2iK`2GL-Uj`!rp4DOxDA=P@8Wr#!P$IKHx@g)zKkXeIs zj4TVppxhVq&8SL2Ha`}1p9Y6|HqpGcCzy6GdRtwuX(lBs&FjxfyL_wbpQh+txk7_V za}%GjiwanWQ#jKsZ) zzv?o5PAicbB~L5sK-&eao$9F_`VpBbqwDkh>%p60hdGG5`k7mlQ@k;~d63C($8ZgO zJ_N0L4hnhR$7FKFd9AXlHO2f~y2>!|<)H7cw3Ckof9f&&Rm={ki>M^dO!T|@wKyh9 zKa8dY@`0uxiV6PoCM{D^F{6HuPkb$Og@@fo;7wvyI?b{bvkq6(5$@(fYdR&@$9{$C- z67V}htWM6gJZySf|Dfq@g>-34Jw@x~jNN0}&It*JxXp7lHRVtmuiXv#u{t(>N$z0E z6B6}yJW{2`p2!W*vz-Vhj}rTtDjm_%Ot5;Y=wP3n$%%K{T>r@`x29*T&sAS7-r511 z`=Y0^phmMXG4gKTlw5W#jEF$k!zP&;kEli9<;$1Hy+giA=ycs!yY-E=WhEo@u^&qF zYD<%eFduT8N?&M1Jo?#6s4U#J+h^HHmXUNTYH$ONs+A>c^hZ0#aP5n3S~t%Op~f6& zG&}CQc};cIeiAmjncg4ULLGRQ&3hq@jysS{(Mag&Sk9;z=E(c_yPYgoNg6&S1_j3i z-wZmz4ILZzCUXLaNLZjJmI8^g$Vv>|&1NP(d_tLd#3ngnE!@Mn>!;k?{kk2E`jtfb zwc4ql2_~YSJ5&4N-8XQ*7)_t^F)h)R&1*aT{nxBV>3-L=Gkzb$RfdogZH|A?=k6Fi zW7PK47b7{p{H5n3{85Smxe8D@rZQpr0mpe8o&ZMrPtiXW3burO;U{UL+Ks-?1O=`1 z31ydpsMeCrMSFiobU#ecklZ_3Mxs|sWf{`k7q5;pE}(}$Oxp=4{Em_i68GlZt4vsu za25zMRHgZ+Y^}aqUM-RBCtS2_2&|s@9X1}<5BX^gO7HO1quXw;tt0p28u#m!-7?%W zZf=G!-)`oj0AqGYW|HK0)9nPa;jj0??+Ju7$jmft!$*Wkp7s@I2;^+^Z+=l%Q#%mw#V z&j5zmTT{v;5*d85c2lzPXRtulNT#uz+3yB*&}X17cqEi$#6g?pUE^~-=EsXUz@RF9 z4lp;`ADk57#wSR4?dW{3sNU%M%h}W3bHDwM84pf%udj+tnuRWJZc*({J7pHYGW@dWTBcq! z3fWQ5<~=Hao-YchBfyirY?J04NY4f*%G@m3>0Tqu1CnyRd0e3;O-qRhM>3b_i&DCw z!567-jLwvuNRc(E$}^BR-qQOCNiD0vyaQ#f-SgfD(rq8|`hJaVJ}bLIAxOS5A3T+< z*ZkWq;*gExgJ2@g0>E3Q!H!|Z5XJTji;2S!4OD@VYa<8yeX3bf7S9(v`tBD#G6e+eC>_+#r(buJHf7ZDk&+}cnk+2HsL={1FYz2+D|SM6h^>YtHM88;-I9JN5%Eie z*^Q2bXV*0u_j)gsAM zbxzrR=cR&uuZRM9g{qntffU7aRT3HLzd2SBMLX)J_6W`P=}olSV|trBTgeEE0=B&a zd1CGnPsI&g3)CtrWIle(eG#+SnX+dI7l1@nLxmQHnvjA4dbovMPCr}z1~`O@nOe6$ z+%?V{Emho9I*7SkKp<~<4lvz(zuEqX$+4fUQa#`GWV5Ns9Y{?~B<*93l47aWN7h#j zSiKm8n|@7eJj2zK@_Dv7C4f3JN#$CA&Lwrouw-73BZ4#8Y+O#q3o@wOs%K{J8W?1u zFH3Y8M2us#H6T;MHYC9%de4rYMCnc3sNN!-tKx>}^}ydwr98~oTi_KwYtWio+HB2UBjR=4|+LeuR{MS zZF>V&tK~SMtOuMgh`Ji`lP`s%y{>+XwLBt|y(#}`0N2<)`$8m`=w0I(zR3E0Af?LG zu`$!_Xz=Yo%06<5O!te?NjC=amWtzLs@j&To0P+Bys&XR0sn#bfeHQ!=1*m2g%<1g zu`QR~CfD0D`CzqM>6^b|Vdjry^Y_~&MAILqHnqjM?ANh@&+|zd!oZY;g81oItt^dR8p4_|73P zRQ57Z_qOb%^`mD6h95@Ct}>C0WYtL5!+gw5(s3u1=pXo^Z|%H0f^6+`=Da`@^winq zpjkG$<11NTfB#Rw{2+HL*F1;3OQjCSlvgjQG-CKuMf<9!5PW{8a{_lZgrE89j~2+B z1ScTxaVU~8!vyaQy`~*{n0T2o`^-)kaeUf>2! z`MsG&P3ZYXrcFT5%eA*<*S?-h#3mdC8ON0z%QO5#e(0BLT>{YhH1uU=!U6Omb2W$Q zD*2&A72AZ`ThhmjvB(3sY}(5sNW_a%G!b=2QCWP((npU(&Fk5Vk39GHAgqu;b_bO? z0mwVA9M3LIpLEK}Cv?>DyN5Pms`nIrRIPyPWkll`4@S&o78xcSrmH?WHcp$XVD=J0 z$`L{#gf@R&+DbP7Dvv9-%k-8u?z0}JGcm=Ur;kBjCFJnZJ4jC22wNapn%m$8H4l03 z2@M94-6#w`J9~DOj=0|Y@UsnEr1ad5na^P|H!4)o`RBFT+97T%hS)Qaeow`F^xUv< z$h+JjPWWw<6dTEY&7r!eD*EC^A#YyFO*i*}blk!^bInVe*0Nkj_+_rWwtD!~&H2I0 zttR5k6~84RCSq@#{b$<^(H)gY|Ebcu5$-t(FG7u9GTP566sV=tUfL|sq;0LkZWf11 zC>&r%jC);Kb8L{0nhP~_ZBJ+yzPOz~4EzvEKxv#}_u!%HxY@vrB&VygE8;=J0f8+4 z%vEIvu|x90l;y>oIWH{VsK7z+?cA4JIQNq`jz|K`BPFuAwId@Ok&f2!HV=j(={3#8 zD(-D+Eh}PDIa_l+X-5*b@SU}-|bt-3K=nXsJmWs?#pOg zkD2@PzP~f#fY`zP;~1(27jbROR~_8^lsvn%CAK7&Hk(hux@dnzgD6DVe=A)4&`M!h zW`P@e=QG~?hw&~bkH$Hy7dp0juhdlZ7@QP^T27M@wL48#myjWL@6Z4HJ_Gbkv)+)V zj9O})oU111aR~mipSK%B?0#o+%P!kd4Q0B`#S=G+TGpDej(C5D=vdkpOKPa5sHMJU z5Ll~Qh}7h)>U{7s@q-;S|7Mjo5%VI|-i8J^8*7Apfu@yE@R^t?W_afJ|tjh%=!?UGaYYyrmMEXGp}u?cWltUObNP8n+q%g7(34+GGjKU`la`tbNo*6C3&$#Z2Ph9 zyFTIb%rVfIBg`wbg7NXX}q-+ zkMdw1rR=hz=*K4pceWF3aS8~~g%Rx^HDw{IjHY@_X3X51%`LCRdSX1KF)g|<%QPN8 zpE3FXQ#{~(a?s|Zi$y+p2;u_OIc~ea>F#so7&GSHGufRC-LQ`{DoLF8K_=D)nG;+zCuR@l%bnFZfeVKvm%b@OfBGzQ% z5lz=L;(P1|G4Q5Swj=m?!LjRD^U3zk+Sx|@s-2%#g`p?lhOf8W`?!<*xHoTO8H89o zMf#05D=niN9f<=%(sg~Y0l+nLGm^a^bYp>~)~`fb!@#w{Epx0klQ+tDduO#MoxdIl zaI%b`nsU$VTE1Hv8L(hwe9^Puevn8!7&#b--ORr|t%+3Yw-B+Z>30lE@Q9?!#!EUi z&-t{x8kF2o!BAy-eNMAQH*cMn5iH2t|1HbVL0&CwR6_UIk3H&DOPlv)#ug&kcFQOA zHhP2CO=do2q%r&)j`58CKZ51nox)nNv-uwE06JHu%&7NzgqBs1m;>u~Ui(M~f zWqnfP2W2qtF+1+_INtnnTo`c}*Z8Mk zasad7=r?`2|1x*ggR1YhyNUhrrW;4IyH_bwk#1hs7TA3do{xw9TS{vuGCZSH!b8 z#m_px&xo(hhOs)@$anO1E}B8?R@fgZS)1c?mbh*>DSEmEF7dH#=8^a$j}eUK;L`P@OA zt3Qg@KV)o8$&S;IkgMuxyIpmiGFD#pN0O!>|k-iuifnVd0|<2+dN; zo>(pfV-XG~Ap6>HvKTZ*7QSh4P67y2*qB=892-U2R%nGjC4%x&7K*h#qsWcJ6f z6084S_4beDk<`+^ZF7}2f9=yMQ9ES((s0F_t#?vz&^BH9E-@vg+&c2DRnhZC4lDp) zZtn~twz?TQ;2K|dRX;R)LWzq?A!GyDq=My(oY$Jm1Rf`NQC-gCm`ZV+NsS+D7>}OGn za`u~SEi6Kg6>UNM8e zI?IFidNg#Fgb)5vX*`pG9BtJ3eX?A=swq1ARYTOi3pdzUBv<=ba4QK$b2rvJ8%K@1z6RNcd8om<3P zYSx+V-!W&B@Q3H4=Nc__Xq9*W3>^t%(SWFN{*6qv3ti;C8qtp4zAsKQkyn%R>)<%bS zReegT(Xo3jSiT9?=@dh7LrL-NN>V;N!HUHFNSb14eQMwev>A?2bDYHrI%vT|_yYTM zSl}NKL8k?)cFgh-|C9jzkK&*#r++F8y4HH?#}WM(-vPUBbSz2AyJ-unhH`!$QUB)S zkgH%HZHCuCj(y-0`&c~ug?%#r$qeXph}ZK!Kpp=~8|ZpHlnMH8618y9p-<+28j#UV zjO|r}PWv_(v1+ivAcTlllHLV99kv(Eb3LDAKu;Ysi0tM?1)V9{aT_`uuevPegV(C8 zE{POtuv9x>NAzZ=Hly_+&SOSPzR2|1b@5#}GwJha_uB|l#a~NA8vgPqR;-^`Q#%MN>jqJ<%5^El<&uLc2WQ! zwI89m-jVPXy$v9``}@RTo(*91-v*5fm0b}W{5HJnHO~y0$1pj71Fe>-A{6JZ%SZlx zHpPWh!@!O;fb&YGp;MSvZkrt%`P(+B0g}GDzSIT4J{uq)Ia&w5#-rF&etCCQ*jHCi?s*-uSq&*Ew|4yHpim>3GQ{rX5Xg(A)mgrlI>#hc}q*7pu{jyx5=Dk^sG z2uF?{c@5;uovQK_h;(T7!Y*oKbS#jrBUF?4u#wOk);u{8u)p!4CGAe4KQddp8s|&l*v%MW~C$h`au~wot8ml zUc*Fe%!?tPA#Y}sw5q~z}~U@$&O{oH-VBVp__YvaBXp`2f_+;`uiWn?SI zDDZY92SJnFTakvMaq?BiZpTeRTndgIZ^pkm278G2rH=pbZ&_V!VFH>!>;kCAFtjs=>jP~}N= zq4BfE6RgcRt&4R`Utj!-dBk^Bwsue4Po6h8o@PJfpa0#sS5t|Kt+8~4$=6n=e@&0N zcfiENxtOjaY~psE`$;nnV@$BX5m+94>R~1wVe?&W;5A_E!eGLAfa z`Q(6oXDv!!_`VHVTT&(DHVx|8)6CH#|5j+tXL;9mZ)T4qw%mQDTzSR|^2R*bX^=Lb9xIRi%7gsjjVwThEsrFnhJ8_T2~W4Sa0;LKy;inP0hcH>Kk855{GA_X0j_ z;QCelEtUAhIpVzQfl`Ax`ONS*n8_H29K1~Xh4~qaMr6M zX9A+9%Wd+t%<^An6mB0L-v3Yb}DnTCmT#0F@y zvWK4sf?ua!M}el9=9KyE8W%<)fb(cCy{YE{Ge9mCH@sX07 zUYY>}%p=Tf+%_RmW1*2_ynoA2oT8Ej+(z4dPmCR=XFQ=JuwY}6`>OV!Cp}e)`64uH zCgb|ytRm!rAye;j<;i0r(G8idnw{ld17ctY1%aB$j>)i9RV|XvI@~+_KX!f{>%TkD zu^V~W6gu|ftSGcR_IC&M*ooF91#5ONZmLA@$46OnUSuy%7zU7BwJ)0fE|xToStp3T zyPpWe3{=&G4kK3T=`!7lsj4Kl(agAAS)b*0&Xfa4=ZO}*piV-u>5awim<4Zy|0t@2l^8hCdgJqjH_3{q= z&{VmrjOv^Ma>jx^LhPr_cLY>p+Zs{}eognPGce4IjbE4K*EbJ-x!QHbg#i5Y(&n2% zqR@>btIsLf44jEvl&D4x6=zcp#4`hrbr?b#g{0nF#@zF z$@Rv0Is?CIETnIGG|1GXQ0t5ZRHJ`6#nJpq;I|>uKdd>4(3ITusiYjJ9r$Q$6Kz`a zr^vtk{3WZg+z?C1CPzb)#z6M2V5+@bw42dbr%1;ouG92OzPKTUGj9o8JO*Oy zXunyup2ZDv@Xd|*gCl?W#xv-hJu#AM3YEXLohNF_wHD)q9czGN@?Xrxc_A>arcPUC zm^hlEDUHCaBM=nl5-w3eefjLkSp)Dk+wq(U{$`4Sw|!ySvvkDNaXLysk^|(>fbagWeDPAj?onM*yEOYr_rHK4nuuPIT%k_W zM$T79?S7`bCR{0t&1YA-{GS9hemL|7&G0 z=5c-Z9TrjIbeIr?TpqL(O(|voo`$?7l|8k*kQO!81^u@%bZ(>LFHXKjjM-y`$GJDG6 zkdK_GDaFSd{DWsGLJ%mj2FozD=@|17SSZW*b9>{lczym||Fr5)N%0vjgZOA!pFLhP z0bHUaY_uxq8%C+ZMZ)3n+DOLU*bX;ut(-Nua%hepIHDsC2*lJrp*Mv}U69;+VaMjP z$wR6zTjcrP5+{hN0N=P95n&+WM{=@JRHD1cmggeRlJsc)Y;s{)Y+)e^C9%_Fgh%<9 zHTpgYy$bm&>Zt@>WAPDlLOHz83QJ&ZX6Jo_mQ4#|`1NFX?!@lFmxKcQ1=TT*Bnp*p zO2X0873Ru^54yf1Bjj*>l@)P+#Mts4kU({FS|Ae~4Mj(E9cRH&C)IozyfS zc*79~wVkPjgF)$_e3CYR!}o&_$6Y6R-Xc7p3vwx}*j=(ylv!pIf%bFG0sdNq7Kq}I zvU&iV%E=6tt#Wj>Q_woeh~sbpzL#;R8c{3$xC{t%%)-b= zE>*`#$mX-eNR;)15U8_y<~cRV9KZ|$bDaV?l0QUE?XW9>jxFQcIwBb)bpS!>2q7S) zdqb{X$NnQG>p3nLLBLm6rRsDLXlthR5l@U~{iSZ!WjMMaF<((@(MWBqwFa}1bnZ&n1aOY2Y|M@=7K-Ec=>LG@-78kC zRR%J7b)8d+@^c|E{l+d{@3li#|Lo*-+>f(9nmgw>{!+uOZ3K5mhIkeumXCdwj>_a> zUYintR$reIfk(Pqk2^WsJ(MmfTI;@LGr&o>3`u#if$l9C#X{ndV*np0`L4l9mV6Ki zxq(NF?1=Y=od-!&<*moxU`7(CR2xV3-E}VRpDv@oW3WNPAEWhe`+m zJ^mdY`w$`wZW#&wSL2%R%+9C}T} z9J_fcPR4P~tdg;ESrSFBUg3x3LpZhW!~rmdAle!Z)ZForTVs|$Agb)=viy( zs&8T9?4qeVLsZ;*BYEF)$#2w?{@#L>uCeD@k-3WBs|S~jv6kdnmc#P8ITPF0&0MLY znUO*veBs^t1Pu24{a(VUZ7tgt$x`d=Njd%IiSlxJ**kP@r-f!Z3MUoMQ~Odq-}ajb zO_Mnmrouf>rUd;;w_Oo03OI%Doyial4AnbbWyf83_?(r{sut^!HI9k{rU(g7!TDWZ+z8+Kb+eR7m;J@Zl$znP>bv@E<%PNtKyK$X0=tc*Y_I_; zE|G#8L{9p!E6`Ygepp&Lj=~M~T%jM%O!lWHm4!mTC-s>x>E$|aebqqWWR=9{Fa?7w zBD3BrRPFw-?9n*wpXGhEDXLL+6(wJW7^}X&P)xYskmhq^d;opyJwcaSKlOd?*|=I3 zy+ga}##_lqHDNoKpn46@r-u;`P*_kFkkeXp)0V9sY2yky5OOK~FaQU#j^1dP`0Q^y z1v}sg{?NEkp6>LebUc)D01=t;yngwFnS|zays&p9OFn!=G<=_?U|}e)dFZn@L-g&D zd<|hI9+~EW*^{#yBGYY(H+Q+{-q@(ozq6^YX5K*9I2&lsvRtelkZ*oP)_)_ohr*+o zzx~+^FnIl9pB4I!Bs@UAtjYH)jOBxF4di&;E2}otzmWg|1ne4^P1XR?ncHMFy;R`T z`Bz@sSCThy_)5>5^OLUT41h$(9DRQ+wFH^4 zE_N*+Hl5>J`3bHR*C)011PtzE{*32T}*Unyg(5?E&pQ~kWuJ&u@>~9(sn=25~yCWMeqn_$iazD&q!hkz1F!=EIz1&g})Q&wsZn<#7WD|p8Fd_XvPfN%a=JfM( zP~w%+Lxmrz1e7a;EaMi$Gb_DoY$wkmnV$m?I2~S*lkkMyS9!%+p--*?c=tw31kiH& zKM-}w*_XfFqJk1Hev<<*@F`dBu#B(XnOW&u%RPQp`VWS+zAdeA^k2qM)S85V;TBPb;~S|4#BWL!8@;kAGnhQc49o&-tZ9(Nznnw6htcUV zXH2)SyaEkQ5U?sk<8zSR0F01LXH2d=t&BsL`IdiSf*E;?t{wr!)f)71a}p-SqiBW}xaWB6VFg}^T*36d z{z=xsw~zve4MBpAu!jmg^E8Bm;g!u@Gu+T}VvwNMxWcml7$FE1J|*$<4nZP#bmv8x zuz76Eo4_agf7??n41g~^Ky|9Af?dQ7d+qzDB6i#F!pTV(+djeFhkL_*%riqcLnTZ8D6cl%%VndZJML>~A!co<$P0-|`*A%w#H68To zuIfNtHfp&8@W=^SqR;)7qUQgm8PKUG`zt%OGPdYs=SD~ov4Nds(}o99S9;Y$3UDn|LY(~o3|oF`yPW%$!Z;iV!?=`8)X>Q)Y-vfSE929#bj<>jp!)SNkd zdYu2i)F{~)g-3u#0TL8f#knOPB@;lCh9uvr+O2HPneDd;{K$wNaQ zKRks$*H$~Rey3%Ps&Ehx2K@_ofWF7G?141HI?ea9)%yHLJPE6k3je>D2X~ibBApUs zdQ8YTpSSkppn@}#+6`9@okv1V$OSTW0orY3jP}}`uxH|Ow?g&PH^~9E&H!i8%?-3K5Y(HE~QjH`iKSLVrg619abx`|WmM1-X!1Q50l+Xx5v{2XQ~Oug3Z zx-pk|mhXsOA28{-sV|yiH4=$dxx?H5j?;xDeFUQRgfrt_gV!c%v_x!Zw8PLQGS3w_ z!QgsCLqh}fg1Nrr%JCI40ZFQ%Uw`G%qA?%{T2|=idv3Z zsXHQgopXBQxT9&8j6=WeN7(Q}BJdo>0mk@$Uu_Q6{sM;0sxvPkyP)5&J=tSx+x-~9 z0DU5dW!GWX)hEg2@}0l!VZ!)o>+s6K8+Hsm;->%btD3<)YWB#Wmup#QGeX&K> z*Xm8m0T(LNBUM0;Ys!~gb!;_#o%@^NN+ewBuX98Q)Y$e}=11roeV z!ZF*X_0A@<6Ffb_Y~=_ziNdwe+Hw!Be;vl?;I}wkb+(-EffiBpC-U!VP}Qcct`0M7 z|K6VuA2@YfO{G5^m2VahetGjAr}K}CvZB0=r5 zO_p&Ud0HCur!v%jgqj(fGnlmi&HE*fGN>vKy#=cQ|@+s+`b#j>gnGS#oe<~?a zQH%NeNCxhVN6y>7Rpk2nf%PQ$(0{{;;cDj;!60?Nn5Fj-upRU>#cC9TXJ@vr#gTw^* z4i6=_yc{k-wAde6V<^v_R&wIZba)+(uFnCBZW$NW)PuTblYJs)l zEX`yTiS1N_n5E$pu|N^Z^$Vut;1%l<3%1qO`r|cgOhi>RuF3T%ZJz$Xc_BD(T*a{I zW2#3q5G^}aT`*P6v-s2sxQyHD4Mco2fI?cA``f-)qsl6o3nq>@7ea{J> z(TmalT5C$CZ}3DVqO%NjP2433d{Y24cau5v)yL%Ks&KewkK+rb<7|-Ugaj^ET z#_TgiwMFXHig{_#FX56Pb^x6%>G@3(h$` zXw(b=Rdq0a33t933jjp$M-u_XBv(M_uSNUj`7QY>U<{-+!lB@KmxYgB-6pPpPk5(q zSp=qin2+s)n&MT7KF=JaZf+AV1I{G)bB1?!Y*#*Nnwdc(px7R@dgCS)EQ~EYwJdeE zs_<#6T@@fs{u)*OB~cIe;&+kv45KeNz|MLi&c_BV9?&tee`hkXYPAY2aEX?IY81#~ z^9y|oTY?(0%jfzk(ZJC-VYi%xceI(pd1js$2;5w%O~r5fr=3U%T;}B)9228?HR=sD z`gMh?PZO5#MM*rz+YPl^vI`5H#vYdod%6~;fHS5|+iB{SXqv-3*B&eaJ#oDe=Il-R z=K}hzkG*gjk{~@fG>2h~Y^P62Jo_aL=)WV|*%h&FyCh-QE?u{bfe^rQ<$3E80WPW7 zo8q_7C%3OxU%qTY?xUv4KUU`!$BS29yM(uF*$(bbfRCz5Ij_mC(N?%pZHa zuZ4S@kI?_ZGO2coB=({3tH}H!b#Bo2s#8A{I+dayYCqEr{{?1PPwL`jPrJeTX6_he zF`%5&!|CnRDU@;4H`pTke*3D$V`n|iM1>Z$HkC)6AUq%Z?++ezC|ZBd>#!JpV@nd= zm;WeAzh{h&CTR(pKT5BZ^r>Frdo=L8;{so2_ zI$jHrcvcO-3>_COQbk6Zh&p}=%#B?Lj^ELb&q$5?D}5hpD*|Whpy@{+4LS{KTQEd8 zAmzJrQjqDbZnNopNktnhh=*0ZQ6jsiD}uWcqfJCA*7;R@i|P|WTELs-zU;D^u88T* z)jp>+im_w=QWEj1+6vrs%bOPP&~k~(11ZZ3k3+=HoGY*!d9s+++qDipT2~i#qAT$z z|EqTB&q_lo)+vd;uDPN?lCiu9Euf9Fk*-<*lw^v|7 z6(N65m_7$ilE7P@Ra5HISNOs4M7TQ+QQ}8Mm0cdY%m7+ptaQ(&t>jAasbFQ*cD%v% zv!^LTcNc%EPS9m|3^WksfIunR3U@li0o`>_eFX&4toCvOQ_GjH-E`hmSzt^d|>mer1@@{BkUc>;B*JRg00;?mu2o zy&kW0n?>O!jkcg-f!scCs)C;|VZDi~Umks53;#J?f;^m9QD+Gc!OXTG5*AU%hb^jc zB4V<<83$AM(X`)=5TX=a#1UDAF3j;-si^_;Xr!@XT(NeOTk?FjOl zLhfC7-=`y*#D$hZGSDyKQY+;+`$geW4)Hkqe-f-)nWHM|L^t)T`jyfNheaFBX-=Vm zgQ8X#u>2~5)xVsSPdL|gaYpm_;O5%B-I&s_?(}z#YV8oiy;QN|clIzb(+~RPk}h{4 z;sSe*L{i)!d~bNI2nHKWIM635>AxME(`GEs=R_c z;(MC;8lN(7wZdTF)@KE4)z1pGoI>|R4nLqE+NcJL?gv^8%bs(n3*TkzF_IwS|6Vca z$2?LpTz1WUX`nZt-IrKwC1eVW$o>5F*rK@Vq@O3c=Og35x2HsG4fo0?n1grw*9-A` zdVB~-*pyPn0%cePq;o~D%1FtVQ9S7d&o z&RF>)fjN59aU2|^6igR7QR5)3tp-2i)jUR=al=IGE&c8qHugCB+F@BlCZY|m?)6og7CYL76dblkY&Eyae)pH@ZTnH z$v}!v2iFxBAa=4&| zk@ifQRmnU)7<+{Ig9V#5K1jW&<%os#!@f-`y5k@CRk>@k!s>BMcG!W3eN*dT)svb~ zlX35G0t#%A`&nZDMdw_j`;&j+{x1qRZM&#D3;D+m=O_uCCY?d2LmQ zdJC|qo;Pe514R(9L1ICq6e;QME@^3yT!}?`Nd+Y(q(izyVv%NvB}6)xt|gZSm!7h`sUyK+t!#S>Co4F<-`f07C zB+BEMRp5({+P&Xv)LQTXQ;uFT?!%RFzb{;~u@n>W5Mm$q@+v9Ve(N4)u9??0D?}4B z5>NAF=d&CDiUUQ<$QtDQ=bBl=f=ENgY*+z+18Aq4&E!%^-bCu`wD90FTp?t^9nE}3 zHRd#@TKd^cnJbRp$IZctP9xhD>o%5zF(AJLxOp~?*_8(I@je*E+@vdiu0wX{{QhL5 zm5Rf-UnygnE?ZD)VVoiZlcv^?Bbf&7Kb+qH^Ju!)z$a^M2nGNRjNE zsxs}a$^t!c9OvQ(z?DMi(W1vNV-ur>*u4$*kl1!0ItUG*ZD9?vZS-hNpRT|?D!JAf zC?v;=@r|L^A!yX=9~)ELlK~>Ds5aGryj)PJ{@j3PN>QOKI3!$RDHt}Z--q36{81{! z)18-(E-waO2xE0EEU{yR2Sx_3!t&(G8=i$K(|pXjZNbF0q@Ge`BPtmu>t&)(jLkoV zcl<=FVSi=4k8TxfQd5dyC{{miArsxPxUx+eYBdme3bx<3On_Q@<%+RQOUZ5NWLW;p zxOj9q0mxe6WvEd||E9TA7T|k}=W7_4V|zh9RW_dimK=vq;jM}M zMKWOGZI!Mf$*Axnkq6UU^YIP0MKJHXgRXd^c&l4;^T~j$#53Zuvaa#T!S#>e4AP`I z3{0kV(S#UusZRjJe=7RfK$0f1=Ey%k*nI)h4!rk|X3)GS-Ph_Nh@V=1pQ#-*^D(?T^z z5y{`+Pnzu`;801TE_frDXk4FQM0mYQU5434O$xM_buHjYDUVn(>9Pig1nbSHhV|r7 z4<;%G>oSb&P5kHNq_W;-MGm}Xm=1Aq=QeWOpnszKaJ zyEg_t-SB#FO4N|&@ZU3ajY`^-@!T&NqEz7dffp67r}qTn;J}D`9Dmvc8-3<*-iPb% zCko^i)Y&{wWjf5+F?p&bH_2|^7eAl~iU%yg&NpDd53u_a@F`1y^5bqv<4)~ire;5V zxq*9G69fLxisQ(zL)tf#*G!YwUbF~VVL5SU5CT*K9K;n-UQ2S1Sg}?gQUWes7WYE6h8iBa)lfg#0R>*r zg4p221+IN^gjf~qN)p1%^^`#r{5Bpjo$!Cx-|Lf<@8las1-gZ)+j^#Ygg51*)Ir&Q zj43k@Sw44bKGq~3^a1nqq;GGi2RBAJ#PXTy_NJrFWk%?O(#5@ifSqEZswXClz0qR% z=u^j(F*G7JZGX@DD81o=2vATY-qL@QVn};Gf!hI5VJEOAE-4cvXQ@8dCq+B>!f$lo zcv#Xq;n+G(j)g*+{;7hg1nvBH@Ev+X_f7^iqDC@s!}2bZ!Wy8Ijl7V9oudBLNa;tL znYH*sb#Y&*J040vuT@`~3V3Y<^k2X3+5n5=Q+e;@#kwBf?zx;m?J5(`uwhE0#&k`z zcE49vtnczf!cqE3Pr_9P?n%xa$sGL9sPf9A4byxElIIT*Z@EJuKfO0ktx;@2*0a)f z(5)P$wX^g2WY^@F0kh6CYex)BKH7%m<@ngN(;nwD#Od@Ht}<3bSR8X0w+d+Hbbd2< zts~1O%rXJ{BRnkm#I~Wk^1-k?zu7R)18|D!jN43K&zM;hMF^SEuC%kmZo7vC&QxdG zBizdEd}dWx3I_R4K0RVX&NZV&w$91ik`+*}4`zc;+-2G1WqIQ<(yV?7kuw zW5H4V0+zCJe}iRVB=|XS?~mWsv~Vc`yN?55sf^&W52HFqy~!RUq21vRfIuoruG-H# zVR}DgM#BDcVdVpizfb+>GyA_$^aZz`1E|KXY0Ken1B8_ku&CqVeT}g18}6=BnmSZ{ zw4WBDdhIvICn<`-<*#tJg@LR_KBi5e5FVonK%%7$)mO^IKf>4a7;8DJxgN}K+O6vR*CGvV{i4Hzj`Ce5Ff#D{S}> zQlLPKi}o>VBfkrREAFU+0&t3k$)y)W;eo-`J55qo7M4T!^w0Z*>t9p>C;YBf^{uZxR*sf26r!@H>?`yjSJfT zqwNqA-+Q_I{7_(zkTKLlOq#b0rF}V4--Utf`p~9<+NEri%`D z0UnI}lgHL)rBD}$^z=_JhV=j*h<>@RY<;wx1%N?(+-ytXakWK%ewUP#LI!L5j}RoD z-(aG)Hv5tRJvytUPsaQ9$t%UQG#-roXF_*tS0NHxJEdMjj8w>06NJucdp-t$v zZRGi(#`_Nrtnf(093e)@8z8gCTKlRi<_`MM@Ho~iXA9~2fA**@tPnt|(9Av?30;v! zGV)jtWkh~D??v$&cv#_JB8^{_q$li=&Z!QzR(zo=)q!3jyujDf)&aq*y~x2P|BQEV z;UlCJfXm@znKt*#QaEI85Xx|H8iBkWn{Pg-_yRnT_-zcWWL@z+^3I|{`-B8lhhBU23Ki5%aj*!YaxMmabzopEF=X4C z$4uT1uf3c(d;;z=!`G@Nca)I!^lS?JHW_T^uH}+wExMrtUOVeSV78fslo^PtUFxmu zJSM?%xu}$41hn3oH;Ua_bYSSl>W}SJ{+9)QlVEL^x6!^UNyB1W6)y!}b@D~Br(g`M z>hqrVD^q5-_Ma*EjBp5r3u2k91b0@~JUe%-Hj>a{N?!KT@0Zg}3Iunm5diVI^=@^m z9pXsvRU3S95fJc{FJLtX!9ps0MGDh)=Pd}|)QXnH{*!^Q3uROyrCTwGNw8?D!tHJS zR49AvdPNaG^$v{PZ{_EFg2|~MI8fyej0YJnq%8DaZ`O{Q_%63;a3f{QEzxLmmo=ioQEfHMdT&rHlSiEXRry45P zwt`fGEn9)dEyJB=WF?3WF{Vvrt(%U8Q`~xMj~sJ2dn%wK1&(R5E|Xk-@AIC%^GxL} zKrxRoQQXU^eEFASEC7;b3MX>eF|2O_vD(Q6@dQ$VXr5S}x>Kal!+W@gN|e5VGtXPu zFR;HQ{n#7wD$fCWHfq0ALi(O~;?B^r)udGy82b`LKAu7MBKS?}Nvld+8M`sO`>9sN z07|9)BQ?8Cdk_$qZRd?SAwyx-OyDuSm4`Gilxwn81K}aXO`Fmo+pu--h06QjeAZBp z%m&SQkpd1-x{eId-vIKJlhvauI`AZ5%qFp$!ZY-)EII8&V-188gDqa(`XlxpF0)m6 z8AzvSbg|%mWEfj(XvtK?(>zC%0(V9*K-yIuduB}eVQYB{%%n~9jfawZ@2BO!Jo02O zZ>nVK>9FeRRHp5g@t0p3l$p>UByK%yG(VGenm&?sfU~A-9!zzzaTSz`7Pxk4B-7HX zRmf&)meUK_X;qSdf7_B7=HstGL?@THncCGgnrV(R@Ue2@2kQ}^LVK(z>CDUO6QKKf95gZCL&{@DLm*1`PJum8K z9`zZ9^Jtc}3gVN$6n(`?e7DOiYM_^+Hzt()v&*S#BUvi1O$&0Fzv7c3qB)e9`Gj-x zWVLi|Ht-ptu*Ads_=&t5v(GsRF)dDrFDpl|qeTK{&ybQBV!{)%>SkIb+NdH51-aHZ zRsnRb@wG3hK|mG1eug0Lp*j^pMmcisFcQ#BA~s=s1Yhm+6q{Q?>C?!H;BC=rNs`Fil&*qWz*8V zAD46%&gjtao`DzJB0ddN{Q7e4@d*XQhCVvr8<8I3-+0LU38thwZ#}}yJ)2ayH|Ri7 zQL^y342&c;Ll#MF3B7p;)6Pg)|D!_G2__m=uX7>`YZz#6yIbWbG5_@s_IM$EBByk6RYc7my@$qLCkpBO?kc zxdy$c7u4((;bM}-H}B8)j>HTUsJ`GIdT&h82`pl zlCawZKhx(iW&z|@zIw2*LV(gYc+rq7E|afDkx%BMAHyc4`7LcSc33MUBU20tS%}q+ zVYIdS6Eh^E<`?g`xSvk!r4sataI@nRCqOOE9@+7tk5bcXl)E0o6>=y~>vdi)2N0jt z0g+8IM`au8`ThJ>GKyl_M1C8Mv{_cOfM9^LzyqH2onXaf|1A5@88FP6H^d=TI<#pO z@jyh$tWR{m*tL}B{@}Jp>8I?8QwHwf4$WR^811_^-RQ)>^-jE8H}Dd`F?3!ulHB20 zN%sK&G(S05wfW{y$gFpXIs=~Mz&mV!b0>#qru|bJQ=<-~y_@VClGzzXlxc-#2oKIjb)*A=j<^>I zXp5qCA4Hzs1iYW=$Hm}*YHcQb!a-C2Je6#70BsyDuA+M(0~9^O!H6RodiAo|_i;W> z6AuOXxPRU)g25&_3axPr0o|WMl>TR%zZ`u{&m4TKT8P%(nAS)2-2wiH|Mz$B#f2WXX~C10TF-2L2n$W6?%4@ag%YB63F@^GxXqdOR?mc<>8KQZ~ zt$*?eonTA8vq2&GG3~TtlA62q6R~v2sk}g$zyJnSC2xBz#fPyAW4n0=(ZQy#vsl z_w-S@txC6RaZ1%DOA7IEw2HV6361fC9rbq5e@>-1WaKB)Y<8rd%M~7g*8pri8a!sV z`x63Gg10sjZ@ZxVf92i0n#I9~YN%7hmEVfDH@YiRe@o>`*1Bi*A(Juf?-lC>&*#UO z4C=WA&iMrbnxqK8H2*tcON{vm(5`W?1YQI6 zTaHiCAy-~H-btw&;EL)LKK)m6V>DU3g$4Sr5xiU**kK$C9Pj+6!WtCeR(lx|X+n9B zNOBP?T+p?DYI3I3A3NlVx?49r{2KZyMHue=JMCCpsSzrvhe$M|IRt`f+vW6xTEGip z*>oG^UcyMRpKw73DlUol?U}3^B)mG&4s|dC< zMxIDD5~2y~i<|->UaEx%2xtc%>MR(^2&o+Ezx8F4L37;gSM#QFB3}ZQ-*)$)xisp0 zECHcuXm@f3xL-z5!1o@Vis#47l<0LeYiawL_=MVAxB z%||j?FSUQCMBgR{MnOhc_KjeVVyVfwXMnm#_N~E(wceW#@%K8?S{IZUc|6qhA&N%liIpEU(u$eEX;$5@-aRaMZ8E z1!`mdp0j?+4zTBuLB07trzD|#n#;d%09uK``R6>kdGv;Ga_UGvZ(PA^T>D6%kfBF% z5A*9M9eb=WIYmOa+%DeGM4fe{M_8DC8!o)neY`On%)cGikv&mc<`GWej+0B^$-@LS zAHYTcVi9mq^3u)zvrMt{?B>jAu!kk$%536^L(0n^Ka?ln!4<(9N-5CU7kO|(&Vf6U z&mXi2bzhAVRU*GSS)lcEL1cbKmH1z#SvLFGtcDK`RRgU4?D~GZN9C>mbn8*Z->fP5ithKb^j-nWxSn2+ zj>(&5sr-#K*rdg+Wgl`vVxA0R$pL-(J64rsCp!lRoqErht6M0?oB?@}`!c_*`>$dC zlZt!5d*tH>mOSK46a&l9x*7=V#=W#z%64%-$)yHy!9Dy=uk zFvs`BA0@%qb6D_&aIa7P{r|-2Z$)~$oCs(M!I*(E4{W(-KA?fXbNtM@DyMlk8Jgol z?-AV3F7QS|{T1u!g0}UZIB*&dzF}G2spU`X}WiBhfXy@yB8e&rL zFLHm4c@Vm_$X+9P_5jtMCA6Gma@Vg8Z)gf|k(%qC4S8Pp@f#@idu_9yrXSVy2Q}cH zC8KV|a8DXTQ6EVH9EsCVu->tyPxH_jFYHB}{QRrg7+2EBc;>>r%OSe-j7B&nNcHgq zYfKOwx6W#EkgYO^@Qvn<(Y_8wsK{m`nMDP(i(u+vBrPU^+9V5m;P{n z6&%K~cyxW}Pm)I#_vM#>MQB_Vo~N zN6x64-ba$5drje6Rt@e+L~a%LR6&2#u%%N=&-4kHNEh>=1J~`iqnPzURY`O6(L&pA zAInddph%HMk9bMRyw_qhPPR}p%a_aXM1%%58dZPgK#XC+O98B($#{a_ut1q@?q%B1 zst*IyA4w1O0D`zj@~bkX7NRSuMq@dW{7`b5x)OyijzA~78O2-=$y$=Q5s2*<6XT2; zxG=ui%aW9^>d2_SK!#E`U$_vREdtg$(PuYS4;PB)#H41{O z9n1y(8LYiq?y!lWI^@-5sW)zuwb`yB`L2#~J!i;vni^&QnI&*`-VieFfc`RUMR;YE z%#nC-LBWJ%D7-Prk@?q3rMq`X;v#glG6GEeoox4Bq6cWN+4kH1#*w6;kDtUV#5wtz zdzL0>fjwsT@(n(ButvhT1;$qL65`Y+%ha@5QiCn#(rH)#V9ycMJYNs(O zCD|QP@$8aFsEb!j2}nw>o~pZKgO=TS19zvC1hd^JS(vxgFZNA%#JZ(}OqUeQbxT(a zTD~E;Nwmh86jWp^pTB5*%xE{`d;V$)Jx?aK|H9e6!$Cv?nflg+ZK-*veq2jy$&C9% zFTcL{G~=X`>m>i$XJeN-qnpUDG1i`&7J6@z=zF`1t7j>4>X!=AUCS2H_I@={x0}BI zXcMwRDv#q=sJ)eu1C?>E3a+}aZQh7m@unY=!a64m-dU(s{m`()6%d!H(2lVLOv2BMpCo;^y^?1^jKFV0?PUHIl!QdjjjM9YEqUvS( zgK(hq!uxI>%)w^Cm(=WRzN|+^-*z)Lk{MmInFhDW51mQR(^b=rbLLE?_-Qk-jt z&q(oe9KKi@$+6yKD7LOPTSQBOKGHV|@HRLx)P-qQ`^!iBw$t1u+Z`YkQGZMgB{!~K z*A3oT{)0%M z69h4BHy;@P9oQN~vP%xuM%~V!p~4>LApWYAeGJOZWqtI{gU!wsP>N@09JC2l{D3^6 zpe6%^7I`0C7Eq73s_slM>)*SNAZ^JL9uwY^inJ&E3~bIPH(9I_7&>g%@kO{vqA|GI zN`+yQB0>j7{BB@Pw)uuKh2lDCFT`>ZB)>!+9=Z9j}rI9zv|xiCpZT&K2AF&CKv3@w=wLz z{qb(1W(FT$9pk1yi=7#>%DTnSm+>6etysZlq;J60mG8VFNqdtRr4Tm`?q@Y<_LYWjN?&z=^0ihT?Yt(hBipMyRaYP{0mEaIV~fxVedLUgrpx zecZIV$NN}aeXQ<>P2cAq>i8Uj=QZym3_ETNq~4*|?_Dwp1lVS&gs9XLHT`P+I~Fia z`rYdTpT~?Jo{=^&?>oP8r{wF$KXBOi<1Qd1 zLqz9-ip=`R`}0^e#<$9>`h(C2`PTqoj>Pf_2~qm?1cHXan#K&pw)sofMHFzePPN*6 z;){J)r&9r=B!WdjO-wIN-s z=ebp0DqiD#q1G_!WBBQfK2RI7)1cgq?To+Pm*_6^m1zwynrfohcLxwf3A#Bx1NKJy zbfl}CLu$>%C`{P9>EkX>Xv{b}aH0G{Z@;xyhc)y{y$w)raAfJx4xx{t@eV(1g^aGf(t;l6kI7zEAk#cfc zb^BnBwPAN>v@eWF@8ifasprE}4y0A*7h$~kv}Qnpo;SloFVb|IbJZn#P7-u07s~7@ z+97qYd6M(rssvxo3>G7yrSvqstAE7e*{p_*%D-M@l+L{oTkTp6jFC4(x2?{Ctc~XU zPI` z=DYW14rIDowIPpDMc!A=9vw^Sig2t-Xod946yXYGP%sL!=+miqFbzU6$RnRH^ahoE86?7E-N~AwQV!tuetXR@c?L$ zw8r+e{|oktM=1c&%EVO+gy(6?D-7(+3e=w=R$lJB5a)F2se!v4w8A|z7gB}3+5rh* zb?kN+W6pF~{`pP3GwH*uQ;Fl)z++YWDz9!L*Ssjv0kxB@(18a7|rY}>1NT#t!CD4 zc4pRqM88mDHupu&axQIx6{Xx5kLWas5|?T`ycbDQzH#4#CeF$S`IYOd1Gcnv(RG@~rz`zZ?y!++_5H(|HKiP|^NzrmVyP`cm6aY*Yc zp<-(5HJp}O8x1Nk@egZ<)tcAn^v4q|u03b1 zYgC`vO<~ zeDRgB<{->#=RDKHiGKp zj8r6YlOdwoqZ(QxGbdYy(mci-t>yh_*Qq{#6YG;RCDJ{YL1PdhA`7YNyAXK*$FPdj zWZ`G5a@=L>@ucHve#xO`ad3;uJB!}vsG*yQED(A#0j4D_=};Xmlk z$Iw|hHY%~1N6X{uRW!G#c^y)dxx)>LXYawZK)r;kfe}jULCv}UPxE9M3ip+`NIqg# zwVM)MruMmAW-7r_6;H!^)zo(ffQQx^2y>nX8awqXj;Y~5$~ZFpheQBDs%m7p*>*^< zP|Zq|UeJ);_|xnu$Bqi0_5MqOMHaJ3 zhwhM)_8;vEtiVTXIGg+MqWq+7WEvzouV0Fe^jIDYW4DaK9dvC|By~JFu?u}7oQ2;~ zPbRw%8Xd&FkyH`6n}u3rQt=%`IJC>BMW!=Tl8-+kX3LTY*c!7RZ|V_N>_=?kUj+GW zyI^3AFEa2E*MB-WI(&kT+jiearaW@kA&nn+_Dta@9d#A`~NIUp|v;+0$9HC zIsNK< z7jmJ%nb6qV#GcXDLtdp&g(vs6Qqo-H#in74@{iMnvENPcz94XjhdAvw(wh&C=ibq( zOADz;ywE3Lrz6`f?Z%-LSDyg9fs!;OWIq{mK4rF~o;u6UU3f>zoB-W!<+?RZ@y8>CSZd48!s?>i+#^x|a@98hzA`n}MCgT*@nhDP~1i20_OA;SGJbYo9X z4^a$$CkE`_4t)_8gohI=(kqwWSRjx5#(0_!PUgCmoUq!En8+F3GrYTayCt)aFcA}P zaZvB#66%r@y28?Gf;7R99NWCbix`!!*ha7&wVglS@d&D4d|c;mGK0blp8i&2eu46v zVF_4sF@_QRu^;n2x-i;R<%%?dd3>pVr#o(vV2PfwKZX$`IFAWM4(Alz<=V)`4uQ8k z)Zsm1KAmw+iwIF;fJRRDK!@LAY;nODZ zdd73U?M1_cz?6`7K}6?IoseE)bneH6DR;nTXZAa_2C6=tr%Qj_?PHLQ>2Gd09u_zq zhx2vy@*&i#()M`D&km{dF8a2+Ba!>iu%xk5lLL?1!yCFCLOX(&{ntRIU@ zxBc0Y8#7|z>snm4M0_auz8SalYh^16xqRxhkt#;m{&s7RdZkk#H)d%`vlYZC2H)s* zs!l>hU_mSlkU~SpZ&XGeh}G*8!1e;a{q``=yTud|5c@49-I2DiNHS%2{q6*>9WJCy z*WcVBo!UL(gw9$fh9bGoMv*LO>7^hy-@5AJB6lYD25g+uelK0Grpe2Gv1;eJ>v$cq zg?eOavW{3vfD;@kqQ@;;a~gCA>{@VHc%qR1eYW8y&Ea^=iT*_alUS9=r8d%%_B-m( zFUr?3X}*`F+uQ7*s@ofL$p~c{%4~`yK$6t?f2chjV{jNXYxp9fwkC-+UOxK@@TZ{VX=GHxv%ZM%Z=DM z-O8U_sj@|R}GUfy3Nw#K)!zSiY14?@5vZWJNyoU9G>uw7Z#FaSJC zV!Vznb9SGw`pv9p@3~N=rG+q9w3nO7Ga8Tc(YZTPxiM@p?mlytP8iaXXco5Gx5j77 znoFUFq!(eHYdK2GtO%&5<04iD;aYc8S4WoadIpr{i+pt%|GfLKr?i{>HP+K_1)A!+ zPP+UY;rgxqXr^(qae>uoLLmU=4vf8eMdK$$?TZ?a+r)y~m`U>)r^<;xWJZsKWkTn! z;mK~ui5-z8rHH)By}S@&I$drTR`M;iHvXTLlzDJ=-EUt7*ob)66%71nMS6qutaJb4 z-3xc4mrT|k{o*bHmm6g<0T~2%93s5-lk|MPCk?w3wy*~~i4!7DN6m8>GhvL{78kMqV~EUN&XsompV`fnQrwORyHcbS*m`WD3g0 zl}~gdJ)1h;{dRa+>%Bv15`}K|T29<|)_@-zjvhw}JH0)iwo!0K^CyWNV4NzDTuL9@`?z4zq0%l*Z^)YFRW|`S(J|st^m1U_I*13FzytO{NbBNsD+dL+HS)#|B52;|Y1YxlpJO3+v7If-3v(oi@6z3Oak<+9=~_uWs{ zJ9PT{If8+@;1}~q+1jp8L1Nr@&J7+ezK2Wwkda)=KPc~>Kc-K`d@K+ZJ@B6XzAkvB zt;GjSsorJuk@3WmnRPT}Yu(p`8JGMM-Mi zkj}|U=b<9@uvmR7gWg2@%H}0-WKxiIm0p|O4U}C#-~>oTV0(N&&!qd+VboLi(V~=2 z_mRy<1)Y-uYNJV(qfZik7X@yb*d)G6I_^&q)@E_)5iIwk2(rYYiLGdOmV+*<aI#mh*Ic$$W-15U0_1k6w%okLqQno~PSc!} zOX`$kDfYhdB(Ju~xRN)8#-rXdOwU@G#P{<04*#;veOIMoU+YkX)faGdR5+k|Yqt|= zS#D(A^&0UfW`Sx%Jid>poIeA-TB zZbb<#vp7(ZA)z+rO}GBd(w{6+e7f?nNY5bdr(Ph)FFbid6g>x2V#3ji9xJ+oJ|2)d z?Q!f^wkCO7Za)e$VeeK_vH}4(u(dyBAmF^)oQ(AFKQ5p7X?60&6vfKUj*k_cA2i6R zt*5>Hgrw`2K|~yUBIt1D@F6(SFCoD|qa@yPCa_Y2=Ts&ES;V)j-cD^@b)F@B)&WW~ zsq3@buyhvY={bC-$7?@LPjpI}X#OXG82wh*E?(1ixaajsuji|jv$39EABvt{mQJvT zmGx0U!Y7^nQX7gICWLRS^zysv)u~n|bs_`z^9&-zuroq6Roav7^%GARu$NY?-q!o$lclo4s7=lCNIuAGtOGDq+hocw z(f&Kq#e=~9Wh?&X$8!?SMJa18BBRMZ_Kml!>NebrZ6iLgcl7u4d|z8ha<%EaLAuGe zvC{pkJ!xn9L;!k}dCmwy*T3dtX&3d3Ia|6W^5mt{X7*@O%$RX`e=nwHnVc*A%iIwx z@q8;~$8Cnnc_E?4@!WW$g!jDH$pBrai&1R85VJcdfHd|KW6$}~i7Hk`WXir|xjCp0 zT#=QwW7Ux&&UZJC%>o3_2ck~QM{NDD^v5VFA_hob-nI`-|MViT2VOn3A&Y^?J^$HMRJWM2N3Sk04;ww!^lFS#?BL&r6;`YDivWS{jt!QkO zCaFzO1$Co^24`WOP9>}xRqy3{?U0sScBol=t|GgWq@B!Thqzuh<7(gVi7Lt*tEzUh zatEcbZYvaopbD7M*k{fqdV=-j-%;z84CN*0BKuv}g%BpiiSGgNy&sAf*LerehdA0t zqXn$?k~z&wCpBX~1=3f2ZIiba@mJ0QkL~)3(QlFJ``#HV zywvWa-jM;ei2_eZsE4py%8sf{z*D9+pu`OkO@65NQ|5a zXcC#UIJU{>%$;&Z9aXu}%V~2kap4o>?+QuUA94Ouua|#(tOs4qCz41@v7#*IZ0`Yn zYw;E~*?`Nu@5@Gy``X82hn)mD8o%!X)+Jn6wj?a-hSddH*zzC}6s=vZVv9b_U&#G`b_@8X}j77J9V`fe&XUHTk$W=D$jQDuAe)I!u8eURtcoGb3H(Ae*_jh9x133Qhd&tPnDrI( zqN9^8XXnU`>)f&@jIn5{zok@uXXZUsuU8nHiER?MN+Bo-XS=?XjlYJaJ1&%~AF>tH z_~GAwuE9{bmgSJWabc^)KXZm9E12k{F^O_2krj5f^}}ql63+I-EkWyuZkh7p3U4HV zM)&vpo|{%r^KM%F8G{5kkO3PWmt2GQlcbo#eeSNtwDmN;K6S>%vsztlRHF8{6cD7v zI!JG|-e2~OY9}It%VRxIqsVTlpq>lf(@d+rg5|PWwzQ;!e3S*Pdq~pl!7MV|Qa_n{w3t_3`Ut&XsHD5w>dzhXy0x zkt8WZC%YO_Pe^D88_ju~i$`5Y%M5ehM;K_54A{yc`BpadJMH>q9gUDXspvwxsxR>g z@6q-1DI3z|(DA#FBs27h)d3v*H)5wYpj~`gk&Up!}i#FA~XfO+1uE5*Sth2 zPk5XIwMD#P)yspCm?*8XD-lE2=?mGQ&8xyX5yq{1hCfk8BJ67i>Ym;k?yCKiXg{=& zd4x;MPsVhWaywM)%$~=XRE|TRnWw{m;kxMPny_Zo@G-v0OjLXd1&_$#TD{9t^fV`= zkI5=YTjVlj;~QEAAq5w7b>1pW+VONG;g#yW4=y=GdqKL&M}8WU^?LWfwfBVW(Ycm$ z@kwuB)bKw2Q84#jUCGo~&s5Q2vlLGOpNg-K=C&U9$}KM6&hIEIYelOR?VhTXgwUjk z=XrM7%e5*gqqk7cXX1lYj%!}qM!yhS=lwC#b9`R Date: Tue, 22 Oct 2024 17:18:03 +0200 Subject: [PATCH 6/9] Espionage --- Programs/Games/Espionage/ActionCard.java | 188 +++++ Programs/Games/Espionage/Battle.java | 997 +++++++++++++++++++++++ Programs/Games/Espionage/Board.java | 943 +++++++++++++++++++++ Programs/Games/Espionage/Espionage.java | 414 ++++++++++ Programs/Games/Espionage/Player.java | 433 ++++++++++ Programs/Games/Espionage/ReportUtil.java | 105 +++ Programs/Games/Espionage/SecretCard.java | 101 +++ 7 files changed, 3181 insertions(+) create mode 100644 Programs/Games/Espionage/ActionCard.java create mode 100644 Programs/Games/Espionage/Battle.java create mode 100644 Programs/Games/Espionage/Board.java create mode 100644 Programs/Games/Espionage/Espionage.java create mode 100644 Programs/Games/Espionage/Player.java create mode 100644 Programs/Games/Espionage/ReportUtil.java create mode 100644 Programs/Games/Espionage/SecretCard.java diff --git a/Programs/Games/Espionage/ActionCard.java b/Programs/Games/Espionage/ActionCard.java new file mode 100644 index 0000000..e07756f --- /dev/null +++ b/Programs/Games/Espionage/ActionCard.java @@ -0,0 +1,188 @@ +package Espionage; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import Espionage.Player.AgentName; + +/** + * @author Astrid + * This is the cards to make your choices with. + * This class produces different images of the card. + **/ +public class ActionCard { + + static enum CardType { + _1_SECRET_MISSION, + _2_EMBASSY_MEETING, + AGENT, + BRIBE, + COUNTERESPIONAGE, + REPORT, + + PLACEHOLDER + } + + private CardType type; + private AgentName player; + private boolean disabled; + private boolean selected; + private long value; + + public ActionCard(CardType kt, long idx) { + value = idx; + type = kt; + disabled = false; + selected = false; + } + + public CardType getType() { + return type; + } + + public long getValue() { + return value; + } + + + public ActionCard setPlayer(AgentName arg) { + player = arg; + return this; + } + + public AgentName getPlayer() { + return player; + } + + public void setDisabled(boolean b) { + disabled = b; + } + + public boolean getDisabled() { + return disabled; + } + + public void setSelected(boolean b) { + selected = b; + } + public boolean getSelected() { + return selected; + } + + public BufferedImage getDisabledFrontImage(int width, int height) { + return getFrontImage( width, height, true ); + } + + public BufferedImage getFrontImage(int width, int height) { + return getFrontImage( width, height, disabled); + } + + //Creates Image to show the ActionCard on the Board. + public BufferedImage getFrontImage(int width, int height, boolean gray) { + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = bufferedImage.createGraphics(); + + // fill the inner part with white or yellow + if(selected) g2d.setColor(Color.decode("0xFFFFC3")); //pale yellow + else g2d.setColor(Color.white); + g2d.fillRect(4, 4, width - 8, height - 8); + + // draw 4px border in player's color + Stroke line4px = new BasicStroke(4f); + g2d.setColor(getPlayer().color); + g2d.setStroke(line4px); + g2d.drawRoundRect(4, 4, width-8, height-8, 5, 5); + + + if (gray) g2d.setColor(Color.lightGray); + else g2d.setColor(Color.black); + + String msg1 = ""; + String msg2 = ""; + + switch (type) { + case _1_SECRET_MISSION: msg1 = "1"; msg2 = ""; break; + case _2_EMBASSY_MEETING: msg1 = "2"; msg2 = ""; break; + case AGENT: msg1 = "A"; msg2 = Long.toString(getValue()); break; + case BRIBE: msg1 = "B"; msg2 = Long.toString(getValue()); break; + case COUNTERESPIONAGE: msg1 = "C"; msg2 = ""; break; + case REPORT: msg1 = "R"; msg2 = ""; break; + default: msg1 = ""; msg2 = ""; break; + + } + + //Vary the fontsize + Font myFont1 = g2d.getFont().deriveFont(Font.BOLD, height / 2 ); + Font myFont2 = g2d.getFont().deriveFont(Font.BOLD, height / 5 ); + + g2d.setFont(myFont1); + { + int w = g2d.getFontMetrics().stringWidth(msg1); + int q = (width - w) / 2; + g2d.drawString(msg1, q, g2d.getFontMetrics().getAscent()); + } + + g2d.setFont(myFont2); + { + int w = g2d.getFontMetrics().stringWidth(msg2); + int q = (width - w) / 2; + g2d.drawString(msg2, q, height - g2d.getFontMetrics().getDescent()-4); + } + + g2d.dispose(); + return bufferedImage; + } + + public BufferedImage getBackImage(int width, int height) { + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = bufferedImage.createGraphics(); + // -------------------------------------------------------------------------- + if (type == CardType.PLACEHOLDER) { + g2d.setBackground(new Color(0, 0, 0, 0)); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.0f)); + g2d.setColor(getPlayer().color); + float[] pattern = {5f, 5f}; + Stroke dotted = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, pattern, 0f); + g2d.setPaintMode(); + g2d.setStroke( dotted ); + g2d.drawRoundRect(5, 5, width - 10, height - 10, 5, 5); + g2d.dispose(); + return bufferedImage; + } + + // --------------------------------------------------------- + // draw 4px border in white + Stroke line4px = new BasicStroke(4f); + g2d.setStroke(line4px); + g2d.setColor(Color.white); + g2d.drawRoundRect(5, 5, width-10, height-10,5,5); + + // fill inner image with black + g2d.setColor(Color.black); + g2d.fillRect(5, 5, width - 10, height - 10); + + // draw a question-mark in player's color. + g2d.setColor(getPlayer().color); + Font myFont = g2d.getFont().deriveFont(Font.BOLD, height / 2 ); + g2d.setFont(myFont); + + FontMetrics qqq = g2d.getFontMetrics(); + Rectangle2D r = qqq.getStringBounds("?", g2d); + double wq = r.getWidth(); + double hq = r.getHeight(); + double ds = qqq.getDescent(); + + double w2 = (width - wq) / 2; + double h2 = (height -hq) / 2; + g2d.drawString("?", (int)w2, (int)(h2+hq-ds)); + + g2d.dispose(); + return bufferedImage; + } +} \ No newline at end of file diff --git a/Programs/Games/Espionage/Battle.java b/Programs/Games/Espionage/Battle.java new file mode 100644 index 0000000..6477808 --- /dev/null +++ b/Programs/Games/Espionage/Battle.java @@ -0,0 +1,997 @@ +package Espionage; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.border.BevelBorder; + +import Espionage.ActionCard.CardType; +import Espionage.Board.City; +import Espionage.Player.AgentName; +import Espionage.Player.PlayerHandler; +import Espionage.Player.Report; + +/** + * @author Astrid + * This class contains the game Logic. + * GuiState is used to handle what to draw on the board + * and what content is valid to select during the current state. + */ +public class Battle extends MouseAdapter { + + public enum GuiState { + HIDE_GROUP, + SHOW_GROUP, + + HIDE_FIRST, + SHOW_FIRST, + GRAB_TOP, + + HIDE_SECOND, + SHOW_SECOND, + MINE_REPORT, + GRAB_REPORTS, + + RELEASE, + } + + GuiState spel = null; + private boolean AUTOPLAY; + private JLabel statusLabel = null; + + private List lPlayers = null; + private List lGroupOne = null; + private List lGroupTwo = null; + + //Agents in prison (FIFO) + private Queue qPrison = new LinkedList(); + + //Two visible cards from counterfoil. + private List lCounterfoil = new ArrayList(); + private SecretCard top1; + private SecretCard top2; + + private List lPositions; + + private List lReports = new ArrayList(); + private List lTrick = new ArrayList(); + + private Board board = null; + private String statusMsg; + private int iDelay; + + + public Battle(Espionage f) { + super(); + board = (Board) f.getContentPane(); + + // Add a statusbar for game-info + board.setLayout(new BorderLayout()); + board.add(createStatusBar(), BorderLayout.SOUTH); + + spel = null; + iDelay=50; + } + + public JPanel createStatusBar() { + JPanel statuspanel = new JPanel(); + statuspanel.setBorder(new BevelBorder(BevelBorder.LOWERED)); + statuspanel.setPreferredSize(new Dimension(board.getWidth(), 25)); + board.getInsets().bottom += 25; + statusLabel = new JLabel(); + statuspanel.add(statusLabel); + return statuspanel; + } + + // To display info during game + public void setStatus(String arg) { + statusLabel.setText(arg); + } + + public void init(List arg) { + qPrison.clear(); + lCounterfoil.clear(); + lCounterfoil.addAll(arg); + arg.clear(); + + top1 = lCounterfoil.get(0); + if (top1 != null) + lCounterfoil.remove(top1); + + top2 = lCounterfoil.get(0); + if (top2 != null) + lCounterfoil.remove(top2); + + if (board != null) { + board.cleanUp(); + board.settop1(top1); + board.settop2(top2); + } + } + + + + public Predicate manual() { + return (u -> u.getHandledBy() == PlayerHandler.MANUAL); + } + + public void startGame(List d) { + System.out.println("============="); + System.out.println("GAME STARTED!"); + System.out.println("============="); + setStatus("Game started."); + lPlayers = d; + + qPrison.clear(); + board.updatePrison(d.size(), qPrison); + + // Put the markers on the board + board.setProgress(d); + + + // Start Listener + board.addMouseListener(this); + spel = GuiState.HIDE_GROUP; + AUTOPLAY = (lPlayers.stream().noneMatch(manual())); + + autoSelectGroup(); + } + + public void endGame() { + board.removeMouseListener(this); + board.setProgress(lPlayers); + board.setGameOver(); + + //The winner is on square No. + lPositions = lPlayers.stream() + .map(u -> u.getPosition()) + .sorted(Comparator.reverseOrder()) + .distinct() + .collect(Collectors.toList()); + + long maxPos = lPositions.get(0); + + //The winner(s)! + List lUsers = lPlayers.stream() + .filter(u -> u.getPosition() == maxPos) + .collect(Collectors.toList()); + + setStatus("Game over."); + + System.out.println("============="); + System.out.println("GAME OVER!"); + if(lUsers.stream().count() > 1) + { + System.out.println("It's a tie!"); + } + else + { + if(lUsers.get(0).getHandledBy() == Player.PlayerHandler.MANUAL) + System.out.println("You won this game!"); + else + System.out.println(lUsers.get(0).getName()+" won this game!"); + } + System.out.println("============="); + spel = null; + } + + + public boolean manualHasTheWinningBribe() + { + long lBribes = lTrick.stream().filter(m -> m.getType() == CardType.BRIBE).count(); + if(lBribes == 0) return false; + + ActionCard winner = lTrick.stream() + .filter(m -> m.getType() == CardType.BRIBE) + .max(Comparator.comparingLong( m -> m.getValue() )) + .get(); + + long x = lGroupOne.stream() + .filter(p -> p.getName() == winner.getPlayer() + && p.getHandledBy() == PlayerHandler.MANUAL ).count(); + + if(x == 1) return true; + else return false; + } + + + //Action to take after Player input + //GUIState spel is used to control valid mouse input + public void runNextStep() { + if (spel == null) return; + + switch (spel) { + case HIDE_GROUP: { + spel = GuiState.SHOW_GROUP; + showSelectedGroups(); + break; + } + case SHOW_GROUP: { + spel = GuiState.HIDE_FIRST; + autoSelect4Group1(); + break; + } + case HIDE_FIRST: { + spel = GuiState.SHOW_FIRST; + showSelection4Group1(); + + if( manualHasTheWinningBribe() ) + { + spel = GuiState.GRAB_TOP; + grabMyTopCard(); + break; + } + + break; + } + case SHOW_FIRST: { + spel = GuiState.HIDE_SECOND; + autoSelect4Group2(); + break; + } + case GRAB_TOP: { + spel = GuiState.HIDE_SECOND; + autoSelect4Group2 ( ); + break; + } + case HIDE_SECOND: { + spel = GuiState.SHOW_SECOND; + showSelction4Group2(); + break; + } + case SHOW_SECOND: { + spel = GuiState.RELEASE; + releasePrisoners(); + break; + } + case MINE_REPORT: { + spel = GuiState.RELEASE; + embassyMeeting(); + releasePrisoners(); + break; + } + + case RELEASE: { + spel = GuiState.HIDE_GROUP; + autoSelectGroup(); + break; + } + default: + } + + } + + public void mousePressed(MouseEvent e) { + if (spel == null || AUTOPLAY) { + return; + } + + Point p2 = e.getPoint(); + for (Player usr : lPlayers) { + if (usr.getHandledBy() == PlayerHandler.MANUAL) { + + //Will paint the board. If the click occurred + //in an allowed position, the clicked object + //will be added to the Player object(usr). + board.handleClick(usr, spel, p2); + + + //Wait for the paint cycle to finish and check + //if the player object contains the wanted object. + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + //------------------------------ + if (spel == GuiState.GRAB_REPORTS) { + HashMap STOLEN = usr.getStolen(); + if (STOLEN == null || STOLEN.isEmpty()) + { + return; + } else { + System.out.print("\t* You stole secretCard(s) from: "); + STOLEN.forEach((k, v) -> { + for (Player u2 : lGroupTwo) { + if (u2.getName() == k) { + usr.addSecretCard(v); + u2.delete(v); + System.out.print(k+" "); + lReports.stream().forEach(r-> + { + if(r.getName() == k) + r.getCardList().remove(v); + }); + } + } + }); + System.out.print("\n"); + if(Battle.this.currentTask != null) + { + Battle.this.currentTask.goForward(); + Battle.this.currentTask = null; + } + + + } + } + //------------------------------ + else if (spel == GuiState.MINE_REPORT) { + if (usr.getReport() == null) { + return; + } else { + runNextStep(); + } + } + //------------------------------ + else if (spel == GuiState.GRAB_TOP) { + if (usr.getSelectedSecretCard() == null) { + setStatus("Select a secret card from the board!"); + return; + } else { + SecretCard selected = usr.getSelectedSecretCard(); + if (selected == top1) { + usr.addSecretCard(top1); + top1 = lCounterfoil.get(0); + lCounterfoil.remove(top1); + board.settop1(top1); + } else if (selected == top2) { + usr.addSecretCard(top2); + top2 = lCounterfoil.get(0); + lCounterfoil.remove(top2); + board.settop2(top2); + } else { + System.out.println("No secret card grabbed???"); + } + runNextStep(); + } + } + //------------------------------ + else { + if (usr.getSelectedAction() == null) { + return; + } else { + runNextStep(); + } + } + //------------------------------ + } + }); + return; + } + } + } + + // Showing group selection back-side up (1|2). + public void autoSelectGroup() { + + // Current positions! + lPositions = lPlayers.stream() + .map(u -> u.getPosition()) + .sorted(Comparator.reverseOrder()) + .distinct() + .collect(Collectors.toList()); + + // If the leading marker has entered the last city - end the game. + if (board.getCityTable().get(lPositions.get(0)) == City.SUMMIT) { + System.out.println("\t============================"); + System.out.println("\tLAST CITY. DO FINAL REPORT! "); + System.out.println("\t============================"); + doReport(true); + endGame(); + return; + } + // ------------------------------------- + //Clear temp.vars + for (Player usr : lPlayers) { + usr.getAllCards().forEach(c->c.setSelected(false)); + usr.setActionCard(null, spel); + usr.setSecretCard(null, spel); + usr.setReport(null); + usr.setStolenCards(null); + } + board.setProgress(lPlayers); + // ------------------------------------- + // Showing group selection back side up. + lTrick.clear(); + for (Player usr : lPlayers) { + if (usr.getHandledBy() == PlayerHandler.MANUAL) { + // A placeholder is added. + usr.addSelectedGroup(lTrick); // may disable some cards. + board.setCards(usr, spel); // update user's visible cards. + setStatus("Join group 1(secret mission) or 2(embassymeeting)."); + } else + usr.addSelectedGroup(lTrick); + } + board.setTrick(lTrick, spel); + // ------------------------------------- + + if (AUTOPLAY) + proceed(); + // wait for manual user to select group... + } + + // Showing group selection front up (1|2). + public void showSelectedGroups() + { + lTrick.clear(); + for (Player usr : lPlayers) { + if (usr.getHandledBy() == PlayerHandler.MANUAL) + setStatus("Click to continue...."); + + lTrick.add(usr.getSelectedAction()); + } + board.setTrick(lTrick, spel); + + //manual user will be sorted last. + lGroupOne = lPlayers.stream() + .filter(d -> d.getSelectedAction().getType() == CardType._1_SECRET_MISSION) + .sorted(Comparator.comparing(d -> ((Player) d).getHandledBy())) + .collect(Collectors.toList()); + + lGroupTwo = lPlayers.stream() + .filter(d -> d.getSelectedAction().getType() == CardType._2_EMBASSY_MEETING) + .sorted(Comparator.comparing(d -> ((Player) d).getHandledBy())) + .collect(Collectors.toList()); + + if (AUTOPLAY) + proceed(); + + } + + // showing group1's selection back side up(Agent|Bribe) + public void autoSelect4Group1() + { + lTrick.clear(); + + if (lGroupOne != null && !lGroupOne.isEmpty()) + for (Player usr : lGroupOne) { + usr.setAction4_G1_inAutoPlayer(lTrick); + if (usr.getHandledBy() == PlayerHandler.MANUAL) { + board.setCards(usr, spel); + setStatus("Group1: Choose Agent or Bribe."); + } + } + board.setTrick(lTrick, spel); + + if (AUTOPLAY) + proceed(); + + // if no manual participant in this group continue... + else + if (lGroupOne.stream().filter(manual()).count() == 0) { + runNextStep(); + } + } + + // showing group1's selection front side up(Agent|Bribe) + public void showSelection4Group1() + { + lTrick.clear(); + if (lGroupOne != null && !lGroupOne.isEmpty()) + secretMission(lGroupOne); + else + board.setTrick(lTrick, spel); + + if (AUTOPLAY) + proceed(); + + // if no manual participant in this group continue... + else + if (lGroupOne.stream().filter(manual()).count() == 0) { + runNextStep(); + } + } + + // Group2 Show the hidden trick back side up (Agent|Counter-espionage|Report). + public void autoSelect4Group2() { + + lTrick.clear(); + for (Player usr : lGroupTwo) { + if (usr.getHandledBy() == PlayerHandler.MANUAL) { + usr.setAction4_G2_inAutoPlayer(lTrick); // may disable some cards, add a placeholder + board.setCards(usr, spel); + setStatus("Group2: Choose Agent, Report or Counterespionage."); + } else + usr.setAction4_G2_inAutoPlayer(lTrick); + } + board.setTrick(lTrick, spel); + + if (AUTOPLAY) + proceed(); + + else + if (lGroupTwo.stream().filter(manual()).count() == 0) { + runNextStep(); + } + + } + + // Group2 Show the trick (Agent|Counter-espionage|Report) + public void showSelction4Group2() + { + + lTrick.clear(); + if (lGroupTwo != null && !lGroupTwo.isEmpty()) + for (Player usr : lGroupTwo) { + if (usr.getHandledBy() == PlayerHandler.MANUAL) { + setStatus("Click to continue..."); + + if (usr.getSelectedAction().getType() == CardType.REPORT) { + spel = GuiState.MINE_REPORT; + usr.setReport(null); + setStatus("Select cards for the Report."); + } + } + lTrick.add(usr.getSelectedAction()); + } + board.setTrick(lTrick, spel); + + if (spel != GuiState.MINE_REPORT) + embassyMeeting(); + + if (AUTOPLAY) + proceed(); + + else + if (lGroupTwo.stream().filter(manual()).count() == 0) { + runNextStep(); + } + } + + //If the prison contains more than one Agent per player + //The agents exceeding the number of players will be released. + public void releasePrisoners() { + + while (qPrison.size() > lPlayers.size()) { + ActionCard agent = qPrison.remove(); + if (agent != null) { + Player zzz = lPlayers.stream().filter(m -> m.getName() == agent.getPlayer()).findFirst().orElseThrow(); + zzz.addActionCard(agent); + + if(zzz.getHandledBy() == PlayerHandler.MANUAL) + System.out.println("\t* Your agent (" + agent.getValue() + ") was released."); + else + System.out.println("\t* "+zzz.getName() + "s agent (" + agent.getValue() + ") was released."); + + } + } + + //both types present? + if( lGroupTwo.stream() + .map(m -> m.getSelectedAction().getType() ) + .filter(m -> m == CardType.AGENT + || m == CardType.COUNTERESPIONAGE) + .distinct() + .limit( 2 ) + .count() == 2 ) + { + //Remove the Agents from the trick. + lTrick = lTrick.stream() + .filter(m -> m.getType() != CardType.AGENT) + .collect(Collectors.toList()); + } + + board.setProgress(lPlayers); + board.updatePrison(lPlayers.size(), qPrison); + board.setTrick(lTrick, spel); + + if (AUTOPLAY ) + proceed(); + + else + if (lGroupTwo.stream().filter(manual()).count() == 0) { + runNextStep(); + } + } + + //Handle Auto Playback speed. + public int getAutoDelay() + { + return iDelay; + } + public void setAutoDelay(int speed) + { + iDelay = speed; + } + public void proceed() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + Thread.sleep(iDelay); + } catch (InterruptedException e) { + ; + } + if (spel != null) + runNextStep(); + } + }); + } + + public void grabMyTopCard() + { + Player x = lGroupOne.stream().filter( manual() ).findFirst().get(); + board.setCards(x, spel); + setStatus( "Group1: You won a SecretCard. Pick it from the board! " ); + + } + + public SecretCard getTopCard(int no) + { + if(no == 1) return top1; + else return top2; + } + + public void secretMission(List deltagare) { + System.out.println("\n\tSECRET MISSION - " + deltagare.size() + " participants"); + if (deltagare.size() == 0) + return; + + + // If no Bribe was played - return! + long bribe_cnt = deltagare.stream().filter(m -> m.getSelectedAction().getType() == CardType.BRIBE).count(); + if (bribe_cnt == 0) { + setStatus("Group1: No bribe was used - click to continue..."); + System.out.println("\t* No bribe was used."); + + //Show the actioncards + lTrick.clear(); + for (Player usr : deltagare) { + lTrick.add(usr.getSelectedAction()); + } + board.setTrick(lTrick, spel); + return; + } + + long agent_cnt = deltagare.stream() + .filter(m -> m.getSelectedAction().getType() == CardType.AGENT) + .count(); + + // 1. Who played the bribe with the greatest amount? + Player x = deltagare.stream() + .filter(m -> m.getSelectedAction().getType() == CardType.BRIBE) + .max(Comparator.comparing(m -> (long) (m.getSelectedAction().getValue()))) + .get(); + + + if (x != null) { + String msg=""; + + //highlights the winning bribe. + x.getSelectedAction().setSelected( true ); + + if (x.getHandledBy() == PlayerHandler.MANUAL) { + msg="Group1: "; + System.out.println("\t* You won a secretCard. " ); + } else { + msg = "Group1: " + x.getName() + " won a secret card. "; + System.out.println("\t* "+x.getName()+" won a secretCard. Winning bribe "+x.getSelectedAction().getValue() ); + // Select top1 or top2! + SecretCard selected = x.getSelectedSecretCard(); + if (selected == top1) { + x.addSecretCard(top1); + top1 = lCounterfoil.get(0); // Tills lCounterfoil tar slut. + lCounterfoil.remove(top1); + if (board != null) { + board.settop1(top1); + } + + } else if (selected == top2) { + x.addSecretCard(top2); + top2 = lCounterfoil.get(0); // Tills lCounterfoil tar slut. + lCounterfoil.remove(top2); + if (board != null) { + board.settop2(top2); + } + + } else { + //Should never get here + System.out.println("AUTO did not select a secretcard???"); + msg += x.getName() + " did not select a secretcard??? "; + } + } + + // Handle Agents + if (agent_cnt != 1) { + msg += " The Bribe was not stolen. "; + System.out.println("\t* "+agent_cnt+" agents - the bribe was NOT stolen."); + x.delete(x.getSelectedAction()); + } else { + Player z = deltagare.stream().filter(m -> m.getSelectedAction().getType() == CardType.AGENT) + .findFirst().orElseThrow(); + if( z.getHandledBy() == PlayerHandler.MANUAL) + { + msg += "You stole the bribe. "; + System.out.println("\t* You stole "+x.getName()+"'s bribe."); + } else { + msg += z.getName()+" stole the bribe. "; + System.out.println("\t* "+z.getName()+" stole the bribe."); + } + + + x.delete(x.getSelectedAction()); + z.addActionCard(x.getSelectedAction()); + } + + if(spel != GuiState.GRAB_TOP) + msg += " click to continue..."; + + setStatus(msg); + } + + //Show the actioncards + lTrick.clear(); + for (Player usr : deltagare) { + lTrick.add(usr.getSelectedAction()); + } + board.setTrick(lTrick, spel); + + } + + public String doReport(boolean gameOver) { + + lReports.clear(); + + if (gameOver) { + lPlayers.stream().forEach(u -> { + Report r = ReportUtil.getBestReport(u); + if( r != null) + lReports.add( r ); + }); + } else { + lPlayers.stream().filter(m -> m.getSelectedAction().getType() == CardType.REPORT) + .collect(Collectors.toList()) + .forEach(u -> u.addMyReport(lReports)); + } + + if (lReports == null || lReports.isEmpty()) { + return " "; + } + System.out.println("\t* We got " + lReports.size() + " Report(s)."); + + // Find the best Report + List sorterad = lReports.stream() + .sorted(Comparator.comparingLong(c -> ((Report) c).getCardCount()) + .thenComparingLong(c -> ((Report) c).getMaxValue()).reversed()) + .collect(Collectors.toList()); + + // The leading participant's position is used... + long lLeader = lPositions.get(0); + City stad = board.getCityTable().get(lLeader); + + // The two best will move forward on the board. + String msg = "Group2: "; + int max = sorterad.size(); + if (max > 0) { + Report No1 = sorterad.get(0); + Player p1 = lPlayers.stream().filter(p->p.getName() == No1.getName()).findFirst().get(); + + if(p1.getHandledBy() == PlayerHandler.MANUAL) { + msg += "You had best R and move " + stad.first + " step(s). "; + System.out.println("\t* You had the best Report("+No1.getCardCount()+", "+No1.getMaxValue()+") and is moved forward "+stad.first+" step(s)." ); + } + else { + msg += No1.getName() + " had best R and move " + stad.first + " step(s). "; + System.out.println("\t* "+No1.getName()+" had the best Report("+No1.getCardCount()+", "+No1.getMaxValue()+") and is moved forward "+stad.first+" step(s)." ); + } + p1.add2Position(stad.first); + if(!gameOver) + p1.getSelectedAction().setSelected(true); //Highlight the ReportCard + } + if (max > 1) { + Report No2 = sorterad.get(1); + Player p2 = lPlayers.stream().filter(p->p.getName() == No2.getName()).findFirst().get(); + + if(p2.getHandledBy() == PlayerHandler.MANUAL) { + msg += "and you had 2nd best R, move " + stad.second + " step(s). "; + System.out.println("\t* You had the second best Report ("+No2.getCardCount()+", "+No2.getMaxValue()+") and is moved "+stad.second+" step(s)." ); + + } + else { + msg += "and "+No2.getName() + " had 2nd best R, move " + stad.second + " step(s). "; + System.out.println("\t* "+No2.getName()+" had the second best Report ("+No2.getCardCount()+", "+No2.getMaxValue()+") and is moved "+stad.second+" step(s)." ); + + } + p2.add2Position(stad.second); + if(!gameOver) + p2.getSelectedAction().setSelected(true); //Highlight the ReportCard + } + + + setStatus(msg); + board.setProgress(lPlayers); + return msg; + } + + public void embassyMeeting() { + System.out.println("\n\tEMBASSY MEETING - " + lGroupTwo.size() + " participants."); + if (lGroupTwo.size() == 0) + return; + + statusMsg = "Group2: "; + + long reportCnt = lGroupTwo.stream() + .filter(m -> m.getSelectedAction().getType() == CardType.REPORT) + .count(); + + long AgentCnt = lGroupTwo.stream() + .filter(m -> m.getSelectedAction().getType() == CardType.AGENT) + .count(); + + long CounterCnt = lGroupTwo.stream() + .filter(m -> m.getSelectedAction().getType() == CardType.COUNTERESPIONAGE) + .count(); + + if((reportCnt == 0 && AgentCnt == 0) + || (reportCnt == 0 && CounterCnt == 0) ) + { + statusMsg += "click to continue"; + System.out.println("\tNo action in Group2."); + setStatus(statusMsg); + return; + } + + + if (reportCnt != 0) { + boolean GameOver = false; + statusMsg = doReport(GameOver); + } + + // All the agents may steal one card from each Report + if (CounterCnt == 0 && AgentCnt != 0 && reportCnt != 0) { + + //highlights agents + lGroupTwo.stream() + .filter(m -> m.getSelectedAction().getType() == CardType.AGENT) + .forEach(c->c.getSelectedAction().setSelected(true)); + + // all the agents will choose in order - we need to wait for the manual one to pick his card(s). + Thread t = new Thread(new Runnable() { + Object monitor = new Object(); + + @Override + public void run() { + + lGroupTwo.stream().filter(m -> m.getSelectedAction().getType() == CardType.AGENT) + .sorted(Comparator.comparingLong(m -> ((Player) m).getSelectedAction().getValue()).reversed()) + .collect(Collectors.toList()).forEach(u -> { + // ----------------------------------------------------------------- + if (u.getHandledBy() == Player.PlayerHandler.MANUAL) { + // Wait for user to select the secret cards... + spel = GuiState.GRAB_REPORTS; + Thread t2 = new Thread(new Task(monitor, u)); + t2.start(); + synchronized (monitor) { + try { + monitor.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + spel = GuiState.SHOW_SECOND; + } + } + // ----------------------------------------------------------------- + else { + System.out.print("\t* " + u.getName() + " stole secretCard(s) from: "); + Battle.this.statusMsg += " "+u.getName() + " stole secretCard(s) from "; + lReports.forEach(r -> { + SecretCard gc = u.stealCard(r); + if (gc != null) { + for (Player u2 : lGroupTwo) { + if (u2.getName() == r.getName()) { + if(u2.getHandledBy() == PlayerHandler.MANUAL) + System.out.print( "You " ); + else + System.out.print( r.getName()+" " ); + + u.addSecretCard(gc); + u2.delete(gc); + Battle.this.statusMsg += r.getName()+" "; + } + } + } + }); + System.out.print("\n"); + } + // ----------------------------------------------------------------- + });// User + //Get rid of the display when all the agents are done. + board.setRedovisningar(null, spel); + lReports.clear(); + } // Run + }); // Thread + t.start(); + // ----------------------------------------------------------- + } + + + // All the agents will be imprisoned + if (CounterCnt != 0 && AgentCnt != 0) { + lGroupTwo.stream().filter(m -> m.getSelectedAction().getType() == CardType.COUNTERESPIONAGE) + .collect(Collectors.toList()).forEach(u -> { + + if(u.getHandledBy() == PlayerHandler.MANUAL) + System.out.print("\t* You selected counterespionage and is moved forward. "); + else + System.out.print("\t* " + u.getName() + " selected counterespionage and is moved forward. "); + + for (long qqq : lPositions) { + if (qqq == u.getPosition()) { + long idx = lPositions.indexOf(qqq) + 1; + System.out.println(idx + " step(s)."); + u.add2Position(idx); + } + } + }); + + statusMsg += CounterCnt+" Counter.. moved forward. "; + statusMsg += "and "+ AgentCnt+" agent(s) was put in jail. "; + + + lGroupTwo.stream().filter(m -> m.getSelectedAction().getType() == CardType.AGENT) + .sorted(Comparator.comparing(m -> m.getSelectedAction().getValue())) + .collect(Collectors.toList()) + .forEach(u -> { + ActionCard agent = u.getSelectedAction(); + u.delete(agent); + + //So the Player can get it back. + agent.setPlayer(u.getName()); + qPrison.add(agent); + + if(u.getHandledBy() == PlayerHandler.MANUAL) + System.out.println("\t* Your agent ("+agent.getValue()+") was put in jail."); + else + System.out.println("\t* " + u.getName() + "'s agent ("+agent.getValue()+") was put in jail."); + }); + + } + + setStatus(statusMsg); + board.setProgress(lPlayers); + + + } + +// //====================================================================== + class Task implements Runnable { + Object monitor; + Player u; + + public Task(Object monitor, Player usr) { + this.monitor = monitor; + this.u = usr; + } + + @Override + public void run() { + spel = GuiState.GRAB_REPORTS; + setStatus("Pick one SecretCard from each Report."); + board.setRedovisningar(lReports, spel); + Battle.this.currentTask = this; + } + + public void goForward() { + spel = GuiState.SHOW_SECOND; + synchronized (monitor) { + monitor.notify(); + } + } + } + + // ====================================================================== + Task currentTask; + // ====================================================================== +} diff --git a/Programs/Games/Espionage/Board.java b/Programs/Games/Espionage/Board.java new file mode 100644 index 0000000..469a6ca --- /dev/null +++ b/Programs/Games/Espionage/Board.java @@ -0,0 +1,943 @@ +package Espionage; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import Espionage.Battle.GuiState; +import Espionage.Player.AgentName; +import Espionage.Player.PlayerHandler; +import Espionage.Player.Report; +import Espionage.ActionCard.CardType; + +/** + * @author Astrid + * This class contains the drawing of + * the gameboard and + * the manual player's different cards. + * + * GuiState is used to handle what to draw on the board + * and what content is valid to select during the current state. + * **/ +@SuppressWarnings("serial") +public class Board extends JPanel { + + public static final long MAX_Position = 40; + + public enum City { + STOCKHOLM (2, 1, 5, Color.white), + BERLIN (3, 2, 2, Color.decode("0xff5733")), + HONG_KONG (4, 2, 2, Color.decode("0x33e9ff")), + MOSCOW (5, 3, 2, Color.decode("0xfc0329")), + PARIS (3, 2, 2, Color.decode("0xa5608d")), + SYDNEY (4, 2, 3, Color.decode("0xc6ad44")), + PRAGUE (2, 1, 2, Color.decode("0xbebebd")), + BAGHDAD (3, 2, 2, Color.decode("0x3b81c0")), + PEKING (4, 2, 3, Color.decode("0xf4fc03")), + SAO_PAULO (3, 2, 2, Color.decode("0xd41202")), + LONDON (4, 2, 2, Color.decode("0x028a02")), + CAIRO (2, 1, 2, Color.decode("0xfdd361")), + WASHINGTON (5, 3, 2, Color.decode("0x0321fc")), + SUMMIT (8, 4, 8, Color.white); + + public final int first; + public final int second; + public final int rutor; + public final Color pnt; + + private City(int i, int j, int r, Color c) { + first = i; // steps for vinner to progress + second = j; // steps for second to progress + rutor = r; // inner squares to draw. + pnt = c; + } + + }; + + + public enum Status { + INACTIVE, + STARTED, + ENDED, + }; + + private JFrame frame = null; + private Status gameStatus=Status.INACTIVE; + private final int TOOLTIP = 25; + + private HashMap hmPlayerPosition = new HashMap(); // MARKERS + private HashMap hmPosBelongToCity = new HashMap(); + + private SecretCard top1=null; + private SecretCard top2=null; + private int iPrisonlength=0; + private LinkedList qPrison=new LinkedList(); + + // Used to draw the players currently selected action. + private List lTrick = null; + + // Used to draw the manual player's hand of cards.. + private Player pManual = null; + + // When the manual player choose Grp:2 + Agent and succeed... + private List lReportsToStealFrom = null; + + // Event handling + private Point clicked = null; + private GuiState state = null; // Used to check if it is allowed to select this card at this time. + + // Variables set during paint event ( handled in handleClick ) + private ActionCard selectedActionCard=null; + private SecretCard selectedSecretCard=null; + + private Report myReport=null; + + private boolean bIamDone=false; + private HashMap hmStolenCards = new HashMap(); + //will contain one selected SecretCard from each Reporting Player! + + public Board(JFrame f) { + frame = f; + init(); + } + + /* + * Predicate for SecretCards + */ + Predicate ok4Click() { + return (sc -> { + switch (state) { + case GRAB_TOP: { + if (sc == top1 || sc == top2) + return true; + else + return false; + } + case GRAB_REPORTS: { + if (pManual.getAllDocs().contains(sc)) + return false; + else if (sc == top1 || sc == top2) + return false; + else + return true; + } + case MINE_REPORT: { + if (pManual.getAllDocs().contains(sc)) + return true; + else + return false; + } + default: + return false; + } + }); + } + + /* + * Predicate for ActionCards + */ + Predicate ok2Click() { + return (ac -> { + switch (state) { + case HIDE_GROUP: + return (ac.getDisabled() == false + && (ac.getType() == CardType._1_SECRET_MISSION + || ac.getType() == CardType._2_EMBASSY_MEETING)); + + case HIDE_FIRST: + return (ac.getDisabled() == false + && pManual != null + && pManual.getFirstSelection().getType() == CardType._1_SECRET_MISSION + && (ac.getType() == CardType.AGENT + || ac.getType() == CardType.BRIBE)); + + case HIDE_SECOND: + return (ac.getDisabled() == false + && pManual != null + && pManual.getFirstSelection().getType() == CardType._2_EMBASSY_MEETING + && (ac.getType() == CardType.REPORT + || ac.getType() == CardType.AGENT + || ac.getType() == CardType.COUNTERESPIONAGE)); + + case RELEASE: + default: + return false; + } + + }); + } + + public Status getGameStatus() + { + return gameStatus; + } + + public void cleanUp() + { + pManual = null; + myReport = null; + bIamDone = false; + top1 = null; + top2 = null; + + hmPlayerPosition.clear(); + if(lTrick != null) lTrick.clear(); + if(lReportsToStealFrom != null) lReportsToStealFrom.clear(); + qPrison.clear(); + if(hmStolenCards != null) hmStolenCards.clear(); + + gameStatus = Status.INACTIVE; + clicked = null; + state = null; + + selectedActionCard = null; + selectedSecretCard = null; + + } + + private void init() { + gameStatus = Status.INACTIVE; + setBackground(Color.decode("0xacacac")); + + City[] cities = City.values(); + int stad = 0; + + // squares on the board... + for (long i = 0; i < MAX_Position; i++) + { + // All squares need to be in a city. + hmPosBelongToCity.put(i, cities[stad]); + + if (stad < cities.length - 1) + { + // 3 squares in the right corners + if (i > 9 && i < 17) + { + if (i % 2 == 1) // Uneven. + stad++; + } + else + if (i % 2 == 0) // Even. + stad++; + } + } + + cleanUp(); + } + + public HashMap getCityTable() { + return hmPosBelongToCity; + } + + /* + * Set data to be drawn on the board at next paint event + */ + public void settop1(SecretCard t1) { + top1 = t1; + frame.repaint(); + } + + public void settop2(SecretCard t2) { + top2 = t2; + frame.repaint(); + } + + public void setTrick(List l, GuiState s) { + state = s; + lTrick = l; + frame.repaint(); + } + + public void setGameOver() { + gameStatus = Status.ENDED; + frame.repaint(); + } + + public void setProgress(List deltagare) { + gameStatus = Status.STARTED; + hmPlayerPosition.clear(); + for (Player u : deltagare) { + hmPlayerPosition.put(u, u.getPosition()); + } + frame.repaint(); + } + + public void setRedovisningar(List r, GuiState s) { + state = s; + lReportsToStealFrom = r; + hmStolenCards.clear(); + if (lReportsToStealFrom != null && !lReportsToStealFrom.isEmpty()) { + lReportsToStealFrom.stream().forEach(redov -> { + if(redov.getCardList() != null && !redov.getCardList().isEmpty()) + hmStolenCards.put(redov.getName(), null); + }); + } + frame.repaint(); + } + + public void setCards(Player usr, GuiState s) { + pManual = usr; + myReport = usr.getEmptyReport(); + bIamDone = false; + state = s; + frame.repaint(); + } + + public void updatePrison(int len, Queue arg) + { + iPrisonlength = len; + qPrison.clear(); + if(arg != null) { + qPrison.addAll(arg); + Collections.reverse(qPrison); + } + } + + public void handleClick(Player usr, GuiState s, Point p) { + clicked = p; + state = s; + + frame.repaint(); + if (p != null) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + + if (selectedSecretCard != null) + { + usr.setSecretCard(selectedSecretCard, state); + clicked = null; + selectedSecretCard = null; + } + if (selectedActionCard != null) + { + usr.setActionCard(selectedActionCard, state); + clicked = null; + selectedActionCard = null; + } + if (usr != null && myReport != null && bIamDone && ReportUtil.isValid(usr, myReport) ) + { + usr.setReport(myReport); + clicked = null; + myReport = null; + bIamDone = false; + } + + if (hmStolenCards != null && !hmStolenCards.isEmpty() && hmStolenCards.values().stream().filter(x -> x == null).count() == 0) { + usr.setStolenCards(hmStolenCards); + clicked = null; + // Don't set lReportsToStealFrom to null until all the agents are done with it! + } + } + }); + } + + } + + + + + + public boolean test4Click(SecretCard card, int x1, int y1, int width, int height, AgentName namn) { + if (ok4Click().test(card) + && clicked != null + && clicked.x > x1 && clicked.x < x1 + width + && clicked.y > y1 && clicked.y < y1 + height) { + + if (state == GuiState.GRAB_REPORTS) { + + if(hmStolenCards.containsValue( card )) { + hmStolenCards.put(namn, null); + return false; + }// toggle + else { + hmStolenCards.put(namn, card); + return true; + } + } + else + if (state == GuiState.MINE_REPORT) { + if (myReport.getCardList().contains(card)) // toggle + { + myReport.getCardList().remove(card); + return false; + } else { + myReport.add(card); + return true; + } + } else { + //GuiState.GRAB_TOP + selectedSecretCard = card; + return true; + } + } + else + if (ok4Click().test(card) + && state == GuiState.MINE_REPORT + && myReport != null + && myReport.getCardList().contains(card)) { + return true; + } + return false; + } + + + + public Rectangle getPanelSize() { + int width = this.getWidth(); + int height = this.getHeight(); + return new Rectangle(width, height); + } + + public Rectangle stepSize(Rectangle panel, int w, int h) { + int width = panel.width / w; + int height = panel.height / h; + return new Rectangle(width, height); + } + + //Paint other agencies Reports to steal cards from + public int paintRedov(Graphics g, int width, int height) { + if (lReportsToStealFrom == null || lReportsToStealFrom.isEmpty()) + return 0; + Rectangle ReportPanel = new Rectangle(width, height); + + //Divide the width between the Players who selected to Report +// int antal = REPORTS.size(); + Rectangle zzzz = stepSize(ReportPanel, lReportsToStealFrom.size(), 1); + +// int q = width - (antal * zzzz.width); +// int gap = 0; +// if (antal > 1 && q > 0) +// gap = q / (antal - 1); + + //No rotated cards here. + int maxWidth = height / 2; + + int x = 0; + int y = 0; + for (Report r : lReportsToStealFrom) { + + List cardsToStealFrom = r.getCardList(); + + //If all the cards in the Report already got stolen by other agents? + if (cardsToStealFrom == null || cardsToStealFrom.isEmpty()) { + hmStolenCards.remove(r.getName()); + } + else + { + //Margin(L+R) = Size of one card + int card_width = zzzz.width / (1 + cardsToStealFrom.size()) ; + + // Paint Background in users color. + Player user = hmPlayerPosition.keySet().stream().filter(u -> u.getName() == r.getName()).findFirst().get(); + if (user != null) + g.setColor(user.getColor()); + + card_width = (card_width > maxWidth) ? maxWidth : card_width; +// g.fillRect(x, 0, zzzz.width, height); + g.fillRect(x, 0, card_width * (1+cardsToStealFrom.size()), height); + + //Left margin + x += card_width / 2 ; + + for (SecretCard s : cardsToStealFrom) { + test4Click(s, x + 1, y + 1, card_width - 2, height - 2, r.getName()); + if (hmStolenCards.containsValue(s)) + g.drawImage(s.getClickedImage(card_width - 2, height - 2), x + 1, y + 1, frame); + else g.drawImage( s.getFrontImage(card_width - 2, height - 2), x + 1, y + 1, frame); + x += card_width; + } + + //Right margin + x += card_width / 2 ; +// x += gap; + } + } + return height; + + } + + public int getCityFontSize(Graphics g, String text, int width, int height) + { + //Shrink till it fits + int iMax = (width > height) ? height : width; + float textSize = iMax/4; + + Font myFont1 = g.getFont().deriveFont(Font.BOLD, width/4); + + java.awt.FontMetrics fmf = g.getFontMetrics(myFont1); + java.awt.geom.Rectangle2D textBox = fmf.getStringBounds(text, g); + + while(textBox.getWidth() > iMax) + { + myFont1 = myFont1.deriveFont(--textSize); + fmf = g.getFontMetrics(myFont1); + textBox = fmf.getStringBounds(text, g); + } + return (int)textSize; + } + public void drawCityText(Graphics g, int x, int y, int width, int height, String text, char pos, int size) + { + Font myFont1 = g.getFont().deriveFont(Font.BOLD, size); + + g.setFont(myFont1); + java.awt.FontMetrics fm = g.getFontMetrics(); + java.awt.geom.Rectangle2D textBox = fm.getStringBounds(text, g); + + double kat = Math.sqrt( Math.pow( textBox.getWidth(), 2 ) / 2 ); + int wq = (width - (int)textBox.getWidth()) / 2; + int advance = fm.getMaxAdvance()/4; + + g.setColor(Color.BLACK); + + if(pos == 'T') + g.drawString(text, x+wq, (int)(y+textBox.getHeight())); + + if(pos == 't') //SYDNEY + { + AffineTransform affineTransform = new AffineTransform(); + affineTransform.rotate(Math.toRadians(-45), 0, 0); + Font rotatedFont = myFont1.deriveFont(affineTransform); + g.setFont(rotatedFont); + g.drawString(text, (int)(x+advance), (int)(y+kat+textBox.getHeight()-advance)); +// g.drawLine(x, (int)(y+kat), (int)(x+kat), y); + g.setFont(myFont1); + } + if(pos == 'b')//PEKING + { + AffineTransform affineTransform = new AffineTransform(); + affineTransform.rotate(Math.toRadians(45), 0, 0); + Font rotatedFont = myFont1.deriveFont(affineTransform); + g.setFont(rotatedFont); + g.drawString(text, (int)(x), (int)(y+height-kat)); +// g.drawLine(x, (int)(y+height-kat), (int)(x+kat), y+height); + g.setFont(myFont1); + + } + if(pos == 'L') { + AffineTransform affineTransform = new AffineTransform(); + affineTransform.rotate(Math.toRadians(-90), 0, 0); + Font rotatedFont = myFont1.deriveFont(affineTransform); + + g.setFont(rotatedFont); + fm = g.getFontMetrics(); + textBox = fm.getStringBounds(text, g); + wq = (height - (int)textBox.getWidth()) / 2; + g.drawString(text, (int)(x+textBox.getHeight()), (int)(y+height-wq)); + g.setFont(myFont1); + } + if(pos == 'B') + g.drawString(text, x+wq, (int)(y+height-1)-fm.getDescent()); + + } + + + public void paint(Graphics g) { + super.paint(g); + if (gameStatus == Status.INACTIVE) { + g.dispose(); + return; + } + + // ------------------------------------------------------------------- + // Divide the area between + // * gameboard and + // * user's card-display. + // ------------------------------------------------------------------- + Rectangle panel = getPanelSize(); + Rectangle step = stepSize(panel, 13, 13); + + // CardDisplay at the bottom. + int cardDisplay = (pManual != null) ? step.height * 2 + TOOLTIP : TOOLTIP; + + //Black background in the game-board area. + g.setColor(Color.black); + g.fillRect(0, 0, panel.width, panel.height-cardDisplay); + + // Leave some margins around the board. + panel.width -= step.width * 1.5; + panel.height -= (cardDisplay + 2); + int startX = step.width+(int)(step.width*0.10); + + // Re-Calculate the GameBoard part of the area.. + step = stepSize(panel, 12, 9); + Rectangle city = new Rectangle(step.width * 2, step.height * 2); + + // ------------------------------------------------------------------- + // Draw the City boxes + // bottom left to right, then up, and finally right to left. + // ------------------------------------------------------------------- + int x = startX; + int y = panel.height - city.height - 2; + int xChange = city.width; + int yChange = 0; + char pos='T'; + + //Get best possible font-size using the longest city-name. + int fontsize = getCityFontSize(g, "WASHINGTON 5/3", city.width, city.height); + + for (City c : City.values()) { + g.setColor(c.pnt); + + //The final one is completely different. + if (c == City.SUMMIT) { + g.fillRect(x - step.width, y, city.width + step.width, city.height * 3); + drawCityText(g, x, y, city.width, city.height, c.toString()+" "+c.first+" / "+c.second , pos, fontsize); + } + + else if (c == City.SYDNEY // Corner cities + || c == City.PEKING) // are painted a bit bigger... + { + y -= (step.height / 2); + if (c == City.PEKING) { + x -= (step.width / 2); + pos = 'b'; + } else pos ='t'; + + g.fillRect(x, y, city.width + (step.width / 2), city.height + (step.height / 2)); + drawCityText(g, x, y, city.width, city.height+ (step.height / 2), c.toString()+" "+c.first+" / "+c.second , pos, fontsize); + + if (c == City.SYDNEY) + x += (step.width / 2); + } + else + { + g.fillRect(x, y, city.width, city.height); + drawCityText(g, x, y, city.width, city.height, c.toString()+" "+c.first+" / "+c.second , pos, fontsize); + } + + + // calculate position for the next city. + // change direction at the corner cities. + if (c == City.SYDNEY) { + pos = 'L'; + xChange = 0; + yChange = -city.height; + } // CORNERS + if (c == City.PEKING) { + pos = 'B'; + xChange = -city.width; + yChange = 0; + } // CORNERS + x += xChange; + y += yChange; + } + // ------------------------------------------------------------------- + // Draw the 40 inner stepping squares + // bottom left to right + // then up, then right to left. + // then down, right and up again. + // ------------------------------------------------------------------- + x = startX + city.width - step.width + 1; + y = panel.height - city.height + step.height; + xChange = step.width; + yChange = 0; + g.setColor(Color.black); + + for (long i = 0; i < MAX_Position; i++) { + // Corner cities SIDNEY/PEKING middle steps are a bit bigger + if (i == 10 || i == 17) + { + y -= (step.height / 2); + if (i == 17) + x -= (step.width / 2); + + g.setColor(Color.black); + g.drawRect(x, y, step.width - 2 + (step.width / 2), step.height - 2 + (step.height / 2)); + + if (i == 10) + x += (step.width / 2); + + } + else { + g.setColor(Color.black); + g.drawRect(x, y, step.width - 2, step.height - 2); + } + //------------------------------------------------ + // Check if this square contains player's marker? + //------------------------------------------------ + if (hmPlayerPosition != null && hmPlayerPosition.containsValue(i)) { + Map antal_markers = hmPlayerPosition.values().stream() + .collect(Collectors.groupingBy(progress_val -> progress_val, Collectors.counting())); + + //Found markers will share a circle evenly + if (antal_markers.get(i) >= 1) { + int degrees = 360 / Math.toIntExact(antal_markers.get(i)); + int start_degree = 0; + for (Player u : hmPlayerPosition.keySet()) { + if (u.getPosition() == i) { + g.setColor(u.getColor()); + g.fillArc(x+3, y+3, step.width - 6, step.height - 6, start_degree, degrees); + start_degree += degrees; + } + } + //Make a black contour around the circle + g.setColor(Color.BLACK); + g.drawOval(x+3, y+3, step.width - 6, step.height - 6); + g.drawOval(x+4, y+4, step.width - 8, step.height - 8); + } + + } + //------------------------------------------------ + //Change direction at the corners + //UP + if (i == 10 || i == 36) { + xChange = 0; + yChange = -step.height; + } // CORNERS + + //LEFT + if (i == 17) { + xChange = -step.width; + yChange = 0; + } // CORNERS + + //DOWN + if (i == 29) { + xChange = 0; + yChange = +step.height; + } + //RIGHT + if (i == 34) { + xChange = +step.width; + yChange = 0; + } + x += xChange; + y += yChange; + } + // ------------------------------------------------------------------- + // Paint the other players Report cards for you to choose from + // Will be painted above the board, but only while you choose. + paintRedov(g, this.getWidth(), step.height * 2); + // ------------------------------------------------------------------- + + if (gameStatus != Status.ENDED) { + // ------------------------------------------------------------------- + // Paint top cards of counterfoil + // ------------------------------------------------------------------- + if (top1 != null || top2 != null) { + selectedSecretCard = null; + int x1 = x + (int)(step.width * 1.5); + int y1 = y + (int)(step.height * 1.5); + g.setColor(Color.yellow); + if (top1 != null) { + boolean b = test4Click(top1, x1, y1, step.width * 2, step.height, null); + if (b) g.drawImage(top1.getClickedImage(step.width * 2, step.height), x1, y1, frame); + else { + if(ok4Click().test(top1)) + g.drawImage(top1.getFrontImage (step.width * 2, step.height), x1, y1, frame); + else + g.drawImage(top1.getDisabledImage (step.width * 2, step.height), x1, y1, frame); + } + y1 += step.height; + } + if (top2 != null) { + boolean b = test4Click(top2, x1, y1, step.width * 2, step.height, null); + if (b) g.drawImage(top2.getClickedImage(step.width * 2, step.height), x1, y1, frame); + else { + if(ok4Click().test(top2)) + g.drawImage(top2. getFrontImage(step.width * 2, step.height), x1, y1, frame); + else + g.drawImage(top2.getDisabledImage(step.width * 2, step.height), x1, y1, frame); + } + } + } + // ------------------------------------------------------------------- + // Paint agents in prison + // ------------------------------------------------------------------- + { + int x1 = x + (int)(step.width * 3.5); + int y1 = y + (int)(step.height * 3.5); + int cnt = iPrisonlength; + y1 += 5; + g.setColor(Color.gray); + if(qPrison != null && !qPrison.isEmpty()) + { + for(ActionCard ac : qPrison) + { + g.drawImage(ac.getDisabledFrontImage(step.width, (int)(step.height*2)), x1, y1, frame); + x1 += step.width; + } + cnt -= qPrison.size(); + } + //Draw empty cells if there are any. + while(cnt > 0) + { + cnt--; + g.drawRect(x1, y1, step.width, (int)(step.height*2) ); + x1 += step.width; + } + } + + // ------------------------------------------------------------------- + // Paint the current trick - back or front depending on Spel + // ------------------------------------------------------------------- + if (lTrick != null) { + int x1 = x + (int)(step.width * 3.5); + int y1 = y + (int)(step.height * 1.5); + g.setColor(Color.yellow); + if (state == GuiState.HIDE_GROUP + || state == GuiState.HIDE_FIRST + || state == GuiState.HIDE_SECOND) + for (ActionCard k : lTrick) { + g.drawImage(k.getBackImage(step.width, step.height * 2), x1, y1, frame); + x1 += step.width; + } + else +// if (spel == Spel.SHOW_GROUP +// || spel == Spel.SHOW_FIRST +// || spel == Spel.GRAB_TOP +// || spel == Spel.SHOW_SECOND +// || spel == Spel.GRAB_REPORTS +// || spel == Spel.MINE_REPORT +// || spel == Spel.MINE_DONE +// || spel == Spel.RELEASE) + for (ActionCard k : lTrick) { + if (k != null) + g.drawImage(k.getDisabledFrontImage(step.width, step.height * 2), x1, y1, frame); + x1 += step.width; + } + + } + } + // ------------------------------------------------------------------- + // Print info about the winner + // ------------------------------------------------------------------- + if (gameStatus == Status.ENDED) + { + x += step.width * 2; + y += step.height * 3; + + long maxPos = hmPlayerPosition.values().stream().collect(Collectors.maxBy(Comparator.comparingLong(z -> z))).get(); + + //The winner(s)! + List lUsers = hmPlayerPosition.keySet().stream() + .filter(u -> u.getPosition() == maxPos) + .collect(Collectors.toList()); + + Map antal_markers = hmPlayerPosition.values().stream() + .collect(Collectors.groupingBy(progress_val -> progress_val, Collectors.counting())); + + + + String sFinalMessage=""; + if (antal_markers.get(maxPos) > 1) { + sFinalMessage = "it's a tie!"; + } + else if (antal_markers.get(maxPos) == 1) { + if(lUsers.get(0).getHandledBy() == PlayerHandler.MANUAL) + sFinalMessage = "Congratulations, you won this game!"; + else + sFinalMessage = lUsers.get(0).getName().toString() + " won this game!"; + } + + float fontSize= getCityFontSize(g, sFinalMessage, step.width*6, step.width*6 ); + Font f2 = g.getFont().deriveFont(Font.BOLD, fontSize ); + g.setFont(f2); + g.setColor(Color.yellow); + g.drawString(sFinalMessage, x, y); + + } + // ------------------------------------------------------------------- + // Paint user's hand of cards + // ------------------------------------------------------------------- + if (pManual != null) { + g.setColor(Color.decode("0x008080")); + g.fillRect(0, this.getHeight() - cardDisplay, this.getWidth(), cardDisplay - TOOLTIP); + + long lEventCards = pManual.getAllCards().stream().count(); + long lSecretDocs = pManual.getAllDocs().stream().count(); + + int xx = 0; + int yy = this.getHeight() - cardDisplay; + + if (lEventCards + lSecretDocs > 0) { + int cardw = this.getWidth() / (int) (lEventCards + lSecretDocs); + + List hk = pManual.getAllCards().stream().sorted(Comparator + .comparing(c -> ((ActionCard) c).getType().toString()).thenComparingLong(c -> ((ActionCard) c).getValue())) + .collect(Collectors.toList()); + + List gc = pManual.getAllDocs().stream().sorted(Comparator + .comparing(c -> ((SecretCard) c).getLetter()).thenComparingLong(c -> ((SecretCard) c).getPages())) + .collect(Collectors.toList()); + + for (ActionCard h : hk) { + if (ok2Click().test(h) + && clicked != null + && clicked.x > xx && clicked.x < xx + cardw + && clicked.y > yy && clicked.y < yy + (cardDisplay - 25)) { + selectedActionCard = (ActionCard) h; + } + + if(ok2Click().test(h)) + g.drawImage(h.getFrontImage (cardw - 2, cardDisplay - 25), xx + 1, yy, frame); + else g.drawImage(h.getDisabledFrontImage(cardw - 2, cardDisplay - 25), xx + 1, yy, frame); + xx += cardw; + } + + int mine_xx_fom = xx; + + for (SecretCard c : gc) { + if(cardw > cardDisplay-25) + cardw = cardDisplay-25; + boolean b = test4Click(c, xx + 1, yy, cardw - 2, cardDisplay - 25, pManual.getName()); + if (b) g.drawImage(c.getClickedImage(cardw - 2, cardDisplay - 25), xx + 1, yy, frame); + else{ + if(ok4Click().test(c)) + g.drawImage( c.getFrontImage (cardw - 2, cardDisplay - 25), xx + 1, yy, frame); + else g.drawImage( c.getDisabledImage(cardw - 2, cardDisplay - 25), xx + 1, yy, frame); + } + xx += cardw; + } + + int mine_xx_tom = xx; + + if(state == GuiState.MINE_REPORT) + { + if( myReport != null) + { + if(ReportUtil.isValid(pManual, myReport)) + { + int width = mine_xx_tom - mine_xx_fom; + + g.setColor(Color.decode("0x808080")); + g.fillRect(mine_xx_fom ,yy-40 , width , 40 ); + + float fontSize = getCityFontSize(g, "Click here when you are done!", width, width); + g.setFont( g.getFont().deriveFont(fontSize)); + g.setColor(Color.yellow); + g.drawString("Click here when you are done!", mine_xx_fom , yy-15 ); + + if(clicked != null + && clicked.x > mine_xx_fom && clicked.x < mine_xx_tom + && clicked.y > yy-40 && clicked.y < yy) { + + bIamDone = true; + } + } + } + } + } + } + g.dispose(); + } + +} \ No newline at end of file diff --git a/Programs/Games/Espionage/Espionage.java b/Programs/Games/Espionage/Espionage.java new file mode 100644 index 0000000..0c55116 --- /dev/null +++ b/Programs/Games/Espionage/Espionage.java @@ -0,0 +1,414 @@ +package Espionage; + + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.Collections; +import java.util.Comparator; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JSlider; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import Espionage.Player.AgentName; +import Espionage.Player.PlayerHandler; +import Espionage.ActionCard.CardType; + +/** + * @author Astrid + * A game based on the Rock Paper Scissor idea. + * This is the Application main starting the GUI +**/ + +@SuppressWarnings("serial") +public class Espionage extends JFrame implements ItemListener, ChangeListener { + + public Random random = null;; + private Battle battle = null; + private JFrame frame = null; + private List lPlayers = null; + + public static void main(String[] args) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + JFrame frame = new Espionage(); + frame.setVisible(true); + } + }); + } + + // GUI to handle the game + public Espionage() { + frame = this; + random = new Random(42); + setTitle("Espionage"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setJMenuBar(getJMenuBar()); + setBounds(100, 100, 800, 600); + + // Board is painted on this JPanel. + setContentPane(new Board(this)); + + // Game logic + battle = new Battle(this); + + // Create all the players with default options. + createUsers(); + + setVisible(true); + } + + + + // Menu to change player options. + public JMenuBar getJMenuBar() { + JMenuBar jmb = new JMenuBar(); + JMenu jm = new JMenu("File"); + jm.add(get_MI_PlayerOptions()); + jmb.add(jm); + return jmb; + } + + JMenuItem get_MI_PlayerOptions() { + JMenuItem z = new JMenuItem("Start new Game"); + z.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // --------------------------------------- + Object[] message = { getMessagePanel() }; + String[] buttons = { ("Start Game") }; + + int iReturns = JOptionPane.showOptionDialog(frame, message, "Espionage", + JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, buttons, buttons[0]); + + if(iReturns == JOptionPane.CLOSED_OPTION) { + } else { + if(iReturns == JOptionPane.OK_OPTION) { + + // Exclude non-participants + List lActivePlayers = lPlayers.stream() + .filter(d -> d.getHandledBy() != PlayerHandler.NONE) + .sorted(Comparator.comparing(d -> ((Player) d).getHandledBy())) + .collect(Collectors.toList()); + + dealCards(battle); + battle.startGame(lActivePlayers); + } + } + } + }); + return z; + } + + //GUI for the menu. + public JPanel getMessagePanel() { + JPanel p = new JPanel(); + p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS)); + + JPanel title = new JPanel(); + title.setLayout(new BoxLayout(title, BoxLayout.LINE_AXIS)); + title.add(new JLabel("Select your agency to play:")); + title.add(Box.createHorizontalGlue()); + p.add(title); + p.add(Box.createVerticalStrut(10)); + + ButtonGroup btnGrp = new ButtonGroup(); + lPlayers.stream().forEach(u -> { + p.add(getRadioButton4Player(u, btnGrp)); + }); + p.add(Box.createVerticalStrut(15)); + + p.add(getRadioButton4Autoplay("None", btnGrp)); + + JSlider autodelay = new JSlider(JSlider.HORIZONTAL, 0, 100, battle.getAutoDelay() ); + Dictionary dict = new Hashtable(); + dict.put( 0, new JLabel("Fast")); + dict.put(100, new JLabel("Slow")); + autodelay.setLabelTable(dict); + + autodelay.setMajorTickSpacing(25); + autodelay.setMinorTickSpacing(5); + autodelay.setPaintTicks(true); + autodelay.setPaintLabels(true); + autodelay.addChangeListener(this); + p.add(autodelay); + + + p.add(Box.createVerticalStrut(15)); + + return p; + } + + public JPanel getRadioButton4Autoplay(String a, ButtonGroup bg) { + JPanel p = new JPanel(); + p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS)); + + JRadioButton rb = new JRadioButton("Let the computer play on its own!"); + rb.setName("None"); + + if (lPlayers.stream().filter(u -> u.getHandledBy() == PlayerHandler.MANUAL).count() == 0) + rb.setSelected(true); + + rb.addItemListener(this); + bg.add(rb); + + p.add(rb); + p.add(Box.createHorizontalGlue()); + return p; + } + + public JPanel getRadioButton4Player(Player u, ButtonGroup bg) { + JPanel p = new JPanel(); + p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS)); + + JRadioButton rb = new JRadioButton(u.getName().toString()); + rb.setName(u.getName().toString()); + rb.setSelected(u.getHandledBy() == PlayerHandler.MANUAL); + rb.addItemListener(this); + bg.add(rb); + p.add(rb); + p.add(Box.createHorizontalGlue()); + + JCheckBox cb = new JCheckBox("Excluded"); + cb.setName(u.getName().toString()); + cb.setHorizontalTextPosition(SwingConstants.LEFT); + cb.setSelected(u.getHandledBy() == PlayerHandler.NONE); + cb.addItemListener(this); + p.add(cb); + return p; + } + + //This is called once - from the constructor of this class. + public void createUsers() { + Stream.Builder builder = Stream.builder(); + for (AgentName usr : AgentName.values()) { + builder.add(new Player(usr, this, battle)); + } + Stream stream = builder.build(); + lPlayers = stream.collect(Collectors.toList()); + } + + //This is done every time you start a new game. + public void dealCards(Battle battle) { + + lPlayers.forEach((u) -> { + u.setPosition(0); + u.clearCards(); + }); + //Empty the prison + ((Board) getContentPane()).updatePrison(lPlayers.size(), null ); + + // ----------------------------------------------- + // All bribes have unique amounts! + // first we create them - then we deal them. + // ----------------------------------------------- + Stream.Builder builder = Stream.builder(); + for (int index = 1; index <= (lPlayers.size() * 4); index++) { + long value = index * 100; + builder.add(new ActionCard(CardType.BRIBE, value)); + } + Stream stream = builder.build(); + List lBribes = stream.collect(Collectors.toList()); + + // ----------------------------------------------- + // All agents have unique work-experience. + // ----------------------------------------------- + builder = Stream.builder(); + for (int index = 1; index <= (lPlayers.size() * 2); index++) { + int value = (index <= lPlayers.size()) ? index : index + 3; //values 1-5, 8-12 + builder.add(new ActionCard(CardType.AGENT, value)); + } + stream = builder.build(); + List lAgents = stream.collect(Collectors.toList()); + + // ----------------------------------------------- + // All secret documents have + // a letter (A-F) and a unique amount of pages. + // ----------------------------------------------- + List lSecrets = SecretCards(); + + // ----------------------------------------------- + // All the cards are now instantiated. + // Now deal them to the users. + // An even number of iterations and + // every second iteration in reversed order + // give all users the same total amounts + // Deal: + // 4 Secret documents per USER + // 4 Bribes per USER + // 2 Agents per USER + // 1 per USER of everything else + // ----------------------------------------------- + + for (int i = 0; i < 4; i++) { + int idx = i; + lPlayers.forEach((u) -> { + // Only one card per User of these! + if (idx == 0) { + u.addActionCard(new ActionCard(CardType._1_SECRET_MISSION, 0).setPlayer(u.getName())); + u.addActionCard(new ActionCard(CardType._2_EMBASSY_MEETING, 0).setPlayer(u.getName())); + u.addActionCard(new ActionCard(CardType.REPORT, 0).setPlayer(u.getName())); + u.addActionCard(new ActionCard(CardType.COUNTERESPIONAGE, 0).setPlayer(u.getName())); + } + + // Two cards per User + if (idx < 2) { + ActionCard s = lAgents.get(0); + if (s != null) { + u.addActionCard(s.setPlayer(u.getName())); + lAgents.remove(s); + } + } + + // Four cards per User + ActionCard m = lBribes.get(0); + if (m != null) { + u.addActionCard(m.setPlayer(u.getName())); + lBribes.remove(m); + } + + // Four cards per User + SecretCard secret = lSecrets.get(0); + if (secret != null) { + u.addSecretCard(secret); + lSecrets.remove(secret); + } + + }); + // --------------------------------- + // REVERSE SORT TO MAKE EQUAL TOTALS FOR ALL USERS + // --------------------------------- + Collections.reverse(lPlayers); + } + + // PLACE REMAINING lSecrets IN counterfoil. + battle.init(lSecrets); + // lSecrets should now be empty. + + } + + public static Predicate distinctByKey(Function keyExtractor) { + Set seen = ConcurrentHashMap.newKeySet(); + return t -> seen.add(keyExtractor.apply(t)); + } + + public List SecretCards() { + List lSecretCards; + + Supplier newSecretCard = () -> { + return new SecretCard((char) (random.nextInt(6) + 65), // A-F + random.nextInt(300), // 0-300 + "Something a spy would want..."); // + }; + + Stream.Builder builder = Stream.builder(); + for (int index = 0; index < 120; index++) { + builder.add(newSecretCard.get()); + } + List list = builder.build().collect(Collectors.toList()); + + lSecretCards = list.stream().filter(distinctByKey(SecretCard::getPages)).collect(Collectors.toList()); + + return lSecretCards; + } + + // Listeners------------------------------------------------- + JRadioButton rbOLD = null; + + public void itemStateChanged(ItemEvent e) { + Object o = e.getSource(); + if (o instanceof JCheckBox) { + lPlayers.stream().forEach(u -> { + if (u.getName().toString().equalsIgnoreCase(((JCheckBox) e.getSource()).getName())) { + if (u.getHandledBy() == PlayerHandler.MANUAL) { + if (e.getStateChange() == ItemEvent.SELECTED) + JOptionPane.showMessageDialog(frame, "You can't exclude a manual player!"); + ((JCheckBox) o).setSelected(false); + return; + } + + // Toggle + if (e.getStateChange() == ItemEvent.SELECTED) { + long cnt = lPlayers.stream().filter(p->p.getHandledBy() != PlayerHandler.NONE).count(); + if(cnt < 2) + { + JOptionPane.showMessageDialog(frame, "You can't exclude all the players!"); + } + else + u.setHandledBy(PlayerHandler.NONE); + } + else + u.setHandledBy(PlayerHandler.AUTO); + } + }); + } + if (o instanceof JRadioButton) { + if (e.getStateChange() == ItemEvent.DESELECTED && ((JRadioButton) o).getName().equals("None")) { + rbOLD = ((JRadioButton) o); + return; + } + + lPlayers.stream().forEach(u -> { + if (u.getName().toString().equalsIgnoreCase(((JRadioButton) e.getSource()).getName())) { + if (u.getHandledBy() == PlayerHandler.NONE) { + if (e.getStateChange() == ItemEvent.SELECTED) + JOptionPane.showMessageDialog(frame, "You can't choose an excluded player!"); + + if (rbOLD != null && !rbOLD.getName().equals(((JRadioButton) o).getName())) { + rbOLD.doClick(); + } + return; + } + + if (e.getStateChange() == ItemEvent.DESELECTED && u.getHandledBy() != PlayerHandler.NONE) { + rbOLD = ((JRadioButton) o); + } + + // Toggle + if (e.getStateChange() == ItemEvent.SELECTED) + u.setHandledBy(PlayerHandler.MANUAL); + else + u.setHandledBy(PlayerHandler.AUTO); + + } + }); + + } + + } + @Override + public void stateChanged(ChangeEvent e) { + JSlider source = (JSlider)e.getSource(); + if (!source.getValueIsAdjusting()) { + int fps = (int)source.getValue(); + battle.setAutoDelay(fps); + } + } +} \ No newline at end of file diff --git a/Programs/Games/Espionage/Player.java b/Programs/Games/Espionage/Player.java new file mode 100644 index 0000000..cbd82e5 --- /dev/null +++ b/Programs/Games/Espionage/Player.java @@ -0,0 +1,433 @@ +package Espionage; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +import Espionage.ActionCard.CardType; +import Espionage.Battle.GuiState; + +/** + *@author Astrid + * The Player instance holds the player's current position on the board + * and the current set of ActionCards and SecretCards. +**/ +public class Player { + + static enum AgentName { + MI6 (Color.GREEN), + KGB (Color.RED), + SDECE (Color.MAGENTA), + CIA (Color.BLUE), + CCI (Color.YELLOW); + public final Color color; + private AgentName(Color c) { + color = c; + } + }; + + static enum PlayerHandler { + AUTO, + MANUAL, + NONE, + }; + + private Espionage frame; + + // Player-info + private AgentName name; + private PlayerHandler handledBy; + private Color myColor; + + //Player's hand of cards + private List lmyActionCards; + private List lmySecretCards; + + // Game-info + private Battle battle; + + private long position; + private ActionCard placeholder; + private ActionCard firstSelection; + private ActionCard selectedAction; + private SecretCard selectedSecret; + private HashMap hmStolen; + private Report myReport; + + + public Player(AgentName idx, Espionage f, Battle b) { + name = idx; + frame = f; + battle = b; + + myColor = idx.color; + handledBy = PlayerHandler.AUTO; + position = 0; + lmyActionCards = new ArrayList(); + lmySecretCards = new ArrayList(); + + placeholder = new ActionCard(CardType.PLACEHOLDER, 0); + placeholder.setPlayer(idx); + } + + public Color getColor() { + return myColor; + } + + public void setHandledBy(PlayerHandler sp) { + handledBy = sp; + } + + public void addActionCard(ActionCard sk) { + if (lmyActionCards == null) + lmyActionCards = new ArrayList(); + lmyActionCards.add(sk); + } + + public void addSecretCard(SecretCard gc) { + if (lmySecretCards == null) + lmySecretCards = new ArrayList(); + lmySecretCards.add(gc); + } + + public void delete(ActionCard sk) { + if (lmyActionCards != null) + lmyActionCards.remove(sk); + } + + public void delete(SecretCard gc) { + if (lmySecretCards != null) + lmySecretCards.remove(gc); + } + + public PlayerHandler getHandledBy() { + return handledBy; + } + + public AgentName getName() { + return name; + } + + public void setSecretCard(SecretCard sc, GuiState spel) { + selectedSecret = sc; + } + + public void setStolenCards(HashMap arg) { + hmStolen = arg; + } + + public SecretCard getSelectedSecretCard() { + if (handledBy == PlayerHandler.AUTO) { + int i = frame.random.nextInt(100); + if (i <= 50) + selectedSecret = battle.getTopCard(1); + else + selectedSecret = battle.getTopCard(2); + } + return selectedSecret; + } + + public HashMap getStolen() { + return hmStolen; + } + + // Adds the card for group-selection (1|2) to theTrick + public void addSelectedGroup(List theTrick) { + //first assert that you have at least one card to play + //in the next step if you chose SECRET MISSION at this time. + long cnt = lmyActionCards.stream() + .filter(card -> (card.getType() == CardType.BRIBE + || card.getType() == CardType.AGENT)) + .count(); + + // -------------------------------------------- + // Set the card Enabled or Disabled + ActionCard card_1 = lmyActionCards.stream() + .filter(card -> (card.getType() == CardType._1_SECRET_MISSION)) + .findFirst().orElseThrow(); + + if (cnt == 0) + card_1.setDisabled(true); + else + card_1.setDisabled(false); + // -------------------------------------------- + if (handledBy == PlayerHandler.AUTO) { + List cards4FirstSelection = lmyActionCards.stream() + .filter(card -> (card.getType() == CardType._1_SECRET_MISSION + || card.getType() == CardType._2_EMBASSY_MEETING) + && (card.getDisabled() == false)) + .collect(Collectors.toList()); + + firstSelection = null; + if (!cards4FirstSelection.isEmpty()) { + int i = frame.random.nextInt(cards4FirstSelection.size()); + firstSelection = selectedAction = cards4FirstSelection.get(i); + theTrick.add(selectedAction); + } else { + // we should not get here, ever! + firstSelection = selectedAction = placeholder; + } + } + else { + theTrick.add(placeholder); + } + + } + + public ActionCard getFirstSelection() + { + return firstSelection; + } + + // called from Board on MouseClick in Battle. + public void setActionCard(ActionCard r, GuiState spel) { + selectedAction = r; + + //internal for this.toString() + if (spel == GuiState.HIDE_GROUP) + firstSelection = r; + } + + // Adds the card for the chosen action in Group 1 (Agent|Bribe) to theTrick + // The player can have max 2 Agents (but many bribes) + // Note that the player can run out of both Agents and Bribes! + public void setAction4_G1_inAutoPlayer(List theTrick) { + selectedAction = null; + if (handledBy == PlayerHandler.AUTO) { + List validCards = lmyActionCards.stream().filter( + card -> (card.getType() == CardType.BRIBE) + || (card.getType() == CardType.AGENT)) + .collect(Collectors.toList()); + + selectedAction = null; + if (!validCards.isEmpty()) { + int i = frame.random.nextInt(validCards.size()); + selectedAction = validCards.get(i); + selectedAction.setPlayer(this.name); + theTrick.add(selectedAction); + } else { + // we should not get here, ever! + selectedAction = placeholder; + } + } else { + theTrick.add(placeholder); + } + + } + + // Adds the card for the chosen action in Group 2 (Agent|Counter-espionage|Report) to theTrick + // The player can have max 2 Agents(they might end up in jail). + // To use the Report card the player need to have a valid Report + // Counter-espionage can always be used. + public void setAction4_G2_inAutoPlayer(List theTrick) { + selectedAction = null; + + boolean bValid = ReportUtil.hasValidReport(this); + + //Check if the user has cards enough for a valid Report + //and enable or disable the ActionCard Report. + lmyActionCards.stream() + .filter(c -> c.getType() == CardType.REPORT) + .forEach(c -> c.setDisabled(!bValid)); + + if (handledBy == PlayerHandler.AUTO) { + List lEmbassay; + + lEmbassay = lmyActionCards.stream() + .filter(card -> ( card.getType() == CardType.REPORT + || card.getType() == CardType.AGENT + || card.getType() == CardType.COUNTERESPIONAGE) + && (card.getDisabled() == false)) + .collect(Collectors.toList()); + + selectedAction = null; + if (!lEmbassay.isEmpty()) { + int i = frame.random.nextInt(lEmbassay.size()); + selectedAction = lEmbassay.get(i); + selectedAction.setPlayer(this.name); + theTrick.add(selectedAction); + } else { + // we should not get here, ever! + selectedAction = placeholder; + } + + } else { + + theTrick.add(placeholder); + } + } + + public void setReport(Report r) { + myReport = r; + } + + public Report getReport() { + return myReport; + } + + public void addMyReport(List arg) { + // At least 3 secret cards without gap. + if (handledBy == PlayerHandler.AUTO) { + //Auto always use the best possible Report + Report r = ReportUtil.getBestReport(this); + if (r != null) + arg.add(r); + + } else { + if (myReport != null) + arg.add(myReport); + } + } + + //Autoplayer choose witch card to steal from the Report in the argument + //if there are any cards left to steal. + public SecretCard stealCard(Report r) { + if (r == null || r.getCardList() == null || r.getCardList().isEmpty()) + return null; + + if (handledBy == PlayerHandler.AUTO) { + int i = frame.random.nextInt(r.getCardList().size()); + + SecretCard card = r.getCardList().get(i); + if (card != null) + r.getCardList().remove(card); + + return card; + } else { + //is handled in Battle.mouseEvent for the manual player. + } + return null; + } + + public long getPosition() { + return position; + } + public void setPosition(long l) { + position = l; + } + + public void add2Position(long arg) { + if (position + arg < Board.MAX_Position) + position += arg; + else + position = (Board.MAX_Position - 1); + } + + public ActionCard getSelectedAction() { + if(selectedAction != null) + selectedAction.setPlayer(this.getName()); + return selectedAction; + } + + List getAllCards() { + return lmyActionCards; + } + + List getAllDocs() { + return lmySecretCards; + } + + public void clearCards() { + if (lmyActionCards != null) + lmyActionCards.clear(); + if (lmySecretCards != null) + lmySecretCards.clear(); + } + + public String toString() { + String message = String.format("%-7s", ((name != null) ? name : "No name")); + + if (firstSelection == null && lmyActionCards != null) { + long m = lmyActionCards.stream().filter(card -> (card.getType() == CardType.BRIBE)) + .collect(Collectors.summingLong(s -> s.getValue())); + + long y = lmyActionCards.stream().filter(card -> (card.getType() == CardType.AGENT)) + .collect(Collectors.summingLong(s -> s.getValue())); + + message = message.concat(" has " + lmyActionCards.size() + " actionCards"); + message = message.concat(" with $" + m + " in bribes"); + message = message.concat(" and agents withd a total of " + y + " active years."); + } else if (firstSelection != null) { + message = message.concat(" Attends: " + firstSelection.getType().toString()); + } + + if (selectedAction != null) { + message = message.concat(", selected " + selectedAction.getType().toString()); + } + + return message; + } + + + /** + * A valid Report consist of at least 3 cards with + * the same or adjoining letter(s). + * Reports are compared and valued by + * 1. number of cards. + * 2. highest number of pages(unique). + **/ + class Report { + private AgentName name; + private long cardCount; + private long maxValue; + private List cardList; + + Report(AgentName arg) { + name = arg; + cardCount = 0; + maxValue = 0; + cardList = new ArrayList(); + } + + public void setMaxPages() { + maxValue = cardList.stream() + .collect(Collectors.maxBy(Comparator.comparingInt(SecretCard::pages))) + .orElseThrow().getPages(); + } + + public long getCardCount() { + return cardCount; + } + + public long getMaxValue() { + return maxValue; + } + + public List getCardList() { + return cardList; + } + + public AgentName getName() { + return name; + } + + public void clear() { + cardCount = 0; + maxValue = 0; + cardList.clear(); + }; + + public void add(long cnt, List l) { + cardCount += cnt; + cardList.addAll(l); + setMaxPages(); + }; + + public void add(SecretCard c) { + cardCount++; + cardList.add(c); + setMaxPages(); + }; + + }; + + public Report getEmptyReport() { + return (this.new Report(name)); + } + + + +} \ No newline at end of file diff --git a/Programs/Games/Espionage/ReportUtil.java b/Programs/Games/Espionage/ReportUtil.java new file mode 100644 index 0000000..d6b3243 --- /dev/null +++ b/Programs/Games/Espionage/ReportUtil.java @@ -0,0 +1,105 @@ +package Espionage; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import Espionage.Player.Report; + +/** + * @author Astrid + * Utility to check if a Player's list of SecretCards + * contain a valid Report or not. + * A valid Report consist of at least 3 cards with + * the same or adjoining letter(s). + **/ +class ReportUtil { + + //used for testing of the current Report + static Report obj; + static Player player; + static boolean bHasValidReport; + static List lReports = new ArrayList(); + //Valid Reports if there are any. + + public static boolean hasValidReport(Player p ) { + player = p; + obj = p.getEmptyReport(); + bHasValidReport = false; + lReports.clear(); + check_4_reports(p.getAllDocs()); + return bHasValidReport; + } + + public static boolean isValid(Player p, Report myReport) { + player = p; + obj = p.getEmptyReport(); + bHasValidReport = false; + lReports.clear(); + check_4_reports(myReport.getCardList()); + return bHasValidReport; + } + + //Returns the best Report found + public static Report getBestReport(Player p) { + player = p; + obj = p.getEmptyReport(); + bHasValidReport = false; + lReports.clear(); + check_4_reports(p.getAllDocs()); + + if (lReports.isEmpty()) + return null; + + return lReports.stream() + .collect(Collectors.maxBy(Comparator + .comparingLong (c -> ((Report) c).getCardCount()) + .thenComparingLong(c -> ((Report) c).getMaxValue()))) + .orElseThrow(); + } + + public static void check_4_reports(List cards) { + + // Cards grouped by letter (A-F) + Map> hm = cards.stream() + .collect(Collectors.groupingBy(SecretCard::letter, Collectors.toList())); + + // ================================================= + // Testing is done for every letter (A-F) + // ================================================= + IntStream.range('A', 'G').forEach(c -> { + + if (!hm.containsKey((char) c)) { + // A gap was found. + if (obj.getCardCount() >= 3) { + //This already is a valid report. + bHasValidReport = true; + obj.setMaxPages(); + lReports.add(obj); + + //Start testing for another valid Report + obj = player.getEmptyReport(); + } else { + // not a valid report. + obj.clear(); + } + } else { + // Add to sum until a gap is found. + List kort = hm.get((char) c); + long count = kort.size(); + obj.add(count, kort); + } + }); + + if (obj.getCardCount() >= 3) { + //current report is valid. + bHasValidReport = true; + lReports.add(obj); + obj = null; + } + } +} + + diff --git a/Programs/Games/Espionage/SecretCard.java b/Programs/Games/Espionage/SecretCard.java new file mode 100644 index 0000000..937c851 --- /dev/null +++ b/Programs/Games/Espionage/SecretCard.java @@ -0,0 +1,101 @@ +package Espionage; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +/** + * @author Astrid + * The Agents want to steal these cards + * and they use Bribes to get them. + * This class produces different images of the card. + */ +public record SecretCard(char letter, int pages, String Text) { + int getPages() { + return pages; + } + + char getLetter() { + return letter; + } + + enum State{ + DISABLED, + ENABLED, + CLICKED + } + + //Creates Image to show the SecretCard on the Board. + public BufferedImage createImage(int width, int height, State state) { + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = bufferedImage.createGraphics(); + // --------------------------------------------------------- + g2d.setColor(Color.lightGray); + g2d.fillRect(0, 0, width, height); + + if (state == State.CLICKED) + g2d.setColor(Color.yellow); + else + if(state == State.DISABLED) + g2d.setColor(Color.gray); + else + g2d.setColor(Color.black); + g2d.drawRect(2, 2, width - 4, height - 4); + + Font myFont1 = g2d.getFont().deriveFont(Font.BOLD, height / 2 ); + + FontMetrics qqq = g2d.getFontMetrics(myFont1); + g2d.setFont(myFont1); + + int w = g2d.getFontMetrics().charWidth(letter); + int q = (width - w) / 2; + g2d.drawString(Character.toString(letter), q, qqq.getAscent()); + + Font myFont2 = g2d.getFont().deriveFont(Font.BOLD, height / 6 ); + + qqq = g2d.getFontMetrics(myFont2); + g2d.setFont(myFont2); + + w = g2d.getFontMetrics().stringWidth(Integer.toString(pages)); + q = (width - w) / 2; + g2d.drawString(Integer.toString(pages), q, height - qqq.getDescent()); + + g2d.dispose(); + return bufferedImage; + } + + public BufferedImage getClickedImage(int width, int height) { + if (width > height) { + return rotate( createImage(height, width, State.CLICKED)); + } else return createImage(width, height, State.CLICKED); + } + + public BufferedImage getFrontImage(int width, int height) { + if (width > height) { + return rotate( createImage(height, width, State.ENABLED)); + } else return createImage(width, height, State.ENABLED); + } + + public BufferedImage getDisabledImage(int width, int height) { + if (width > height) { + return rotate( createImage(height, width, State.DISABLED)); + } else return createImage(width, height, State.DISABLED); + } + + public BufferedImage rotate(BufferedImage src) { + double theta = (Math.PI * 2) / 360 * 270; + + int width = src.getWidth(); + int height = src.getHeight(); + + BufferedImage dest = new BufferedImage(height, width, src.getType()); + Graphics2D graphics2D = dest.createGraphics(); + graphics2D.translate((width - height) / 2, (width - height) / 2); + graphics2D.rotate(theta, height / 2, width / 2); + graphics2D.drawRenderedImage(src, null); + return dest; + } + +} From 12af47e1978afd517c896964fd5f75bc30888504 Mon Sep 17 00:00:00 2001 From: astrid Date: Wed, 23 Oct 2024 17:37:13 +0200 Subject: [PATCH 7/9] Espionage --- Programs/Games/Espionage/Battle.java | 56 +++++++++++++++++-------- Programs/Games/Espionage/Espionage.md | 2 +- Programs/Games/Espionage/Espionage.png | Bin 25366 -> 45259 bytes README.md | 2 +- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Programs/Games/Espionage/Battle.java b/Programs/Games/Espionage/Battle.java index 6477808..4653901 100644 --- a/Programs/Games/Espionage/Battle.java +++ b/Programs/Games/Espionage/Battle.java @@ -411,7 +411,7 @@ public void autoSelectGroup() { // A placeholder is added. usr.addSelectedGroup(lTrick); // may disable some cards. board.setCards(usr, spel); // update user's visible cards. - setStatus("Join group 1(secret mission) or 2(embassymeeting)."); + setStatus("Join group 1 (secret mission) or 2 (embassy meeting)."); } else usr.addSelectedGroup(lTrick); } @@ -587,6 +587,7 @@ public void releasePrisoners() { board.setProgress(lPlayers); board.updatePrison(lPlayers.size(), qPrison); board.setTrick(lTrick, spel); + setStatus("click to continue..."); if (AUTOPLAY ) proceed(); @@ -775,15 +776,16 @@ public String doReport(boolean gameOver) { String msg = "Group2: "; int max = sorterad.size(); if (max > 0) { + msg = "Moves due to Report "; Report No1 = sorterad.get(0); Player p1 = lPlayers.stream().filter(p->p.getName() == No1.getName()).findFirst().get(); if(p1.getHandledBy() == PlayerHandler.MANUAL) { - msg += "You had best R and move " + stad.first + " step(s). "; + msg += "(You " + stad.first ; System.out.println("\t* You had the best Report("+No1.getCardCount()+", "+No1.getMaxValue()+") and is moved forward "+stad.first+" step(s)." ); } else { - msg += No1.getName() + " had best R and move " + stad.first + " step(s). "; + msg += "("+No1.getName() + " " + stad.first ; System.out.println("\t* "+No1.getName()+" had the best Report("+No1.getCardCount()+", "+No1.getMaxValue()+") and is moved forward "+stad.first+" step(s)." ); } p1.add2Position(stad.first); @@ -795,19 +797,20 @@ public String doReport(boolean gameOver) { Player p2 = lPlayers.stream().filter(p->p.getName() == No2.getName()).findFirst().get(); if(p2.getHandledBy() == PlayerHandler.MANUAL) { - msg += "and you had 2nd best R, move " + stad.second + " step(s). "; + msg += ", You " + stad.second ; System.out.println("\t* You had the second best Report ("+No2.getCardCount()+", "+No2.getMaxValue()+") and is moved "+stad.second+" step(s)." ); } else { - msg += "and "+No2.getName() + " had 2nd best R, move " + stad.second + " step(s). "; + msg += ", "+No2.getName() + " " + stad.second; System.out.println("\t* "+No2.getName()+" had the second best Report ("+No2.getCardCount()+", "+No2.getMaxValue()+") and is moved "+stad.second+" step(s)." ); } p2.add2Position(stad.second); if(!gameOver) p2.getSelectedAction().setSelected(true); //Highlight the ReportCard - } + } + if (max > 0) msg += ") "; setStatus(msg); @@ -917,26 +920,43 @@ public void run() { } - // All the agents will be imprisoned + // All the agents in the Trick will be imprisoned if (CounterCnt != 0 && AgentCnt != 0) { + if(reportCnt == 0) + statusMsg += "Moves due to Counter...("; + else + statusMsg += ", Counter...("; + lGroupTwo.stream().filter(m -> m.getSelectedAction().getType() == CardType.COUNTERESPIONAGE) .collect(Collectors.toList()).forEach(u -> { - if(u.getHandledBy() == PlayerHandler.MANUAL) - System.out.print("\t* You selected counterespionage and is moved forward. "); - else - System.out.print("\t* " + u.getName() + " selected counterespionage and is moved forward. "); - for (long qqq : lPositions) { - if (qqq == u.getPosition()) { - long idx = lPositions.indexOf(qqq) + 1; - System.out.println(idx + " step(s)."); - u.add2Position(idx); + //lPosition contain all square# with at least one marker. + for (long qqq : lPositions) { + + if (qqq == u.getPosition()) { + long idx = lPositions.indexOf(qqq) + 1; + + if(!statusMsg.endsWith("Counter...(")) + statusMsg += ", "; + + if(u.getHandledBy() == PlayerHandler.MANUAL) { + statusMsg += "you "+idx; + System.out.print("\t* You selected counterespionage and is moved forward "); } + else { + statusMsg += u.getName()+" "+idx; + System.out.print("\t* " + u.getName() + " selected counterespionage and is moved forward "); + } + System.out.println(idx + " step(s)."); + + u.add2Position(idx); } - }); + } + + }); - statusMsg += CounterCnt+" Counter.. moved forward. "; + statusMsg += ") "; statusMsg += "and "+ AgentCnt+" agent(s) was put in jail. "; diff --git a/Programs/Games/Espionage/Espionage.md b/Programs/Games/Espionage/Espionage.md index d376881..549b57a 100644 --- a/Programs/Games/Espionage/Espionage.md +++ b/Programs/Games/Espionage/Espionage.md @@ -56,4 +56,4 @@ and the counter-espionage players will move forward... ## A Screenshot -![Espionage](https://github.com/agrvsk/Java/blob/main/Programs/Games/Espionage/Espionage.png) +![Espionage](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Games/Espionage/Espionage.png) diff --git a/Programs/Games/Espionage/Espionage.png b/Programs/Games/Espionage/Espionage.png index e9cf58dfe502f374c53b2da541566309833ff144..14e2c20dd1d5e25db9459204eb364df051ac50c8 100644 GIT binary patch literal 45259 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 R^ml|c&;{SGx%c#+{{x7IVTS+! diff --git a/README.md b/README.md index bd1e1f2..fedcdb3 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ It is very easy to contribute, you may follow these steps - 99. [RotateLinkedList](https://github.com/PrajaktaSathe/Java/blob/main/Programs/RotateLinkedList.java)-Program to demo rotating a linked list 100. [ReverseString](https://github.com/PrajaktaSathe/Java/blob/main/ReverseString.java) -Program to reverse a String using the java method substring. 101. [Overriding](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Overriding.java)-Program to demo overriding in java -102. [Espionage](https://github.com/agrvsk/Java/blob/main/Programs/Games/Espionage/) - Espionage Game +102. [Espionage](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Games/Espionage/) - Espionage Game # Contributors - ## A big thank you to all our contributors!!! From 33bafd9e4770c9729d7f941692cf73dcf59da976 Mon Sep 17 00:00:00 2001 From: astrid Date: Wed, 23 Oct 2024 18:13:36 +0200 Subject: [PATCH 8/9] Espionage --- Programs/Games/Espionage/Espionage.md | 14 +++++++------- README.md | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Programs/Games/Espionage/Espionage.md b/Programs/Games/Espionage/Espionage.md index 549b57a..7f5dd6a 100644 --- a/Programs/Games/Espionage/Espionage.md +++ b/Programs/Games/Espionage/Espionage.md @@ -25,31 +25,31 @@ and the counter-espionage players will move forward... ## The Code - + - + - + - + - + - + - +
EspionageEspionage Program main w GUI Frame and Menu
PlayerPlayer Keeps track of the player's hand of cards and the current position on the board.
BattleBattle Holds the Game Logic
BoardBoard Consists mainly of a paint method that draws the board and the Player's hand of cards.
ActionCardActionCard Each player has a set of ActionCards used to select next action.
SecretCardSecretCard This is the wanted treasure!
ReportUtilReportUtil Utility to get all possible Reports from the player's hand of SecretCards - returns the best one.
diff --git a/README.md b/README.md index fedcdb3..d471563 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ It is very easy to contribute, you may follow these steps - 99. [RotateLinkedList](https://github.com/PrajaktaSathe/Java/blob/main/Programs/RotateLinkedList.java)-Program to demo rotating a linked list 100. [ReverseString](https://github.com/PrajaktaSathe/Java/blob/main/ReverseString.java) -Program to reverse a String using the java method substring. 101. [Overriding](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Overriding.java)-Program to demo overriding in java -102. [Espionage](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Games/Espionage/) - Espionage Game +102. [Espionage](https://github.com/PrajaktaSathe/Java/blob/main/Programs/Games/Espionage/Espionage.md) - Espionage Game # Contributors - ## A big thank you to all our contributors!!! From 29624292557b9bfef7491c97b1827e16be82bb7e Mon Sep 17 00:00:00 2001 From: astrid Date: Thu, 24 Oct 2024 09:08:08 +0200 Subject: [PATCH 9/9] Espionage --- Programs/Games/Espionage/Espionage.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Programs/Games/Espionage/Espionage.java b/Programs/Games/Espionage/Espionage.java index 0c55116..97f3141 100644 --- a/Programs/Games/Espionage/Espionage.java +++ b/Programs/Games/Espionage/Espionage.java @@ -1,6 +1,7 @@ package Espionage; +import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; @@ -34,6 +35,7 @@ import javax.swing.JSlider; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; +import javax.swing.border.BevelBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -142,6 +144,7 @@ public JPanel getMessagePanel() { ButtonGroup btnGrp = new ButtonGroup(); lPlayers.stream().forEach(u -> { p.add(getRadioButton4Player(u, btnGrp)); + p.add(Box.createVerticalStrut(2)); }); p.add(Box.createVerticalStrut(15)); @@ -187,6 +190,7 @@ public JPanel getRadioButton4Autoplay(String a, ButtonGroup bg) { public JPanel getRadioButton4Player(Player u, ButtonGroup bg) { JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.LINE_AXIS)); + p.setBorder(new BevelBorder(BevelBorder.RAISED, u.getColor(), u.getColor())); JRadioButton rb = new JRadioButton(u.getName().toString()); rb.setName(u.getName().toString());