From 27c4377453f0ffa62a0818988addea7427a74a6d Mon Sep 17 00:00:00 2001 From: FrederickPi1969 <pixinyudeyouxiang@gmail.com> Date: Thu, 4 Feb 2021 01:16:13 -0600 Subject: [PATCH] wildDraw4 test passed --- .../sp21-cs242-assignment1/CardManager.class | Bin 3374 -> 3530 bytes .../sp21-cs242-assignment1/CmdUI.class | Bin 4496 -> 4564 bytes .../sp21-cs242-assignment1/Player.class | Bin 4425 -> 4568 bytes .../RuleController.class | Bin 6727 -> 7111 bytes .../CardParserTest.class | Bin 0 -> 583 bytes .../RuleControllerTest.class | Bin 0 -> 4717 bytes sp21-cs242-assignment1.iml | 37 +++- src/Test/CardParserTest.java | 18 ++ src/Test/RuleControllerTest.java | 190 ++++++++++++++++++ src/UNO/CardManager.java | 5 + src/UNO/CmdUI.java | 5 +- src/UNO/Game.java | 2 +- src/UNO/Player.java | 11 +- src/UNO/RuleController.java | 62 ++++-- 14 files changed, 307 insertions(+), 23 deletions(-) create mode 100644 out/test/sp21-cs242-assignment1/CardParserTest.class create mode 100644 out/test/sp21-cs242-assignment1/RuleControllerTest.class create mode 100644 src/Test/CardParserTest.java create mode 100644 src/Test/RuleControllerTest.java diff --git a/out/production/sp21-cs242-assignment1/CardManager.class b/out/production/sp21-cs242-assignment1/CardManager.class index 688ff8e76e90e2dbfd7b94fe66d7016924b47aa2..bc11383ba8d1990ad64464166c8f003d107eeb1e 100644 GIT binary patch delta 229 zcmZ1{bxNA+)W2Q(7#J9=8Rl=~y3Z!aot|3aoLH0+keQRp$RMtvIk}Nlgw2|fK?ls# znf#K?gl`fT!(@gj><m+R7(5uJP1a^V!Z>5{2X-@-*^CUTlP9o?PtIfKV`FES%g7)H z<+4vM=CEPp+`NG!oF#{mp_`$Hfr+64Xt6#6BM>q$uxf2#klg@eFfmjDNj9)xBtsRD x%>z-uP|Z*S<duQd^fE9r^nqFZ3=@Df2T;vKAfC=J6UgHNvSu;NVVK7t2>@(1E@1!w delta 114 zcmX>ly-tej)W2Q(7#J9=8Rl%{y3aP*f!&0!pNnAv!$fw5NjwZ543j4}u^(ZaI@z7W zjB&=~Iu0$CS&R&FlN&kYCZFQ4VdU7%&Kb_4&dksaG=zzvhoKipb1*P6^a1e{hG{?^ O7mzibVJ5?D21x){#T#z` diff --git a/out/production/sp21-cs242-assignment1/CmdUI.class b/out/production/sp21-cs242-assignment1/CmdUI.class index 77e01a48c317fef0d98274cbf4e604c9d13d93e3..ed707a5d848bfe36341a91d099a66097d3c0b42e 100644 GIT binary patch delta 1235 zcma)+>u(fQ7{-4yUAx<Mx7*s=wmaJbtzx!li9v)&m#T;stszB$YK$$lat#OwwB@pp zs_{dKtwYcf5(21eVimiz10O_zY6ZCnrv4u!d^5!Lnb~#YM>E+u=e+04d4KP7p0gv3 zvyCHzqo=Ksa1o_c1*xWHwBMSz6bO`t*1X@-yS1a|z1Mm+Z0ob917r5KqTNZY0E#H* zVXuu*@3jUG@dE~zG;%QYKq7ttBi=lPKR$_nU7FB&D&lD>W+=@?DpUB3DI#7lsP`nb zZs<G>6WXDGAN8)IQ12pq6nCpBp^_kR5w}vtPnxRErsFbKG*V)&YK6hH`f+?29>w$% z@aq#pZARgL$JutEyv@(M`r>DMu=r52Rypbj5haX81u+#}ulF1pnaktMqlNiA$s;V% z*2{Q|<;t^yX4+Z6t6H&!g&tW#=!*#O3o{ZZMgzZcO@+YgIoc9dah>0kJH$)e;3j5J zX;*TK+p2%s9xB<9bY*cBi~1b;#<1MJ!+OhMt7O&e_Nc?I6oskGDa}PR>K|i)*=n66 z9CtXR-;vf-=6;$6cYcx&tc!f?FnpO&2Rk}0qO91RQWu_*qEAcfB~o}P$q3I#kXDJ1 zP{C~qKP&9#S*xPEd4XPDlzi>%<YjjA3j63_zl0cKH7Drwq|iZVk9K}nU8Yve=Z@Ed zlQ}6&t-Y&Q_TXv=Jis&_P-EElf*V`hDpl|<mtU>wYcUhC|J0Z8>dQ$Lu|EnmC)Y~) zbyTrl*}7QF8$8FG;(JTcw-xDDuSd@YHuH{XH}au+N7<4m?$W`!oCOl)lN@IigI*Pe zcHQI=o1WD|`2MELFpThD)EX+%URb(4xkqN&D;Wo5qJvUkP?p+H69=SZQc50{o=3zr zls8O`vi;%Zv?%th;~Hi~-Y`pZhAES^TsxWCsXq6GYx$^a`8o<b%iFQ=;pDIwj*4MK zS{x(7sHQ)ajcsup7sF>__*@Jp@(fjZhPwaB(4^~;rFI#VKBGiA2CHmK>@<GP$k}Ig zUB3|Tm!kfPCrIgBzP8Vn?TCG&72{g*t(5vsSLK}a{a#mXLRL)ME#+-<r*xi<$LL;f P_dg+f<qc*vGWqi#Mq=uC delta 1014 zcma))Sx-|@6ouEl72497S}CQaA_(zTB{4+QAP^<S2@OF&j6*AtAQ(}Gh+wEf^hFKD z6D1fD2h=9cg@Qf^&Z4L|M1O-nz#o9?UYb6elb+jivd>=M-fRELjpRnU2S+_7n-NyH z%vgeq!LIDsl))f=8-}cw>W)xDOJ(T9p3vcAM?|x+GweV*0HYeIeSOH*z7kUK0urWp zYJ<!LD9STPN?-zdMTtXSHwMcDoQc1S$Kf7>JC4k8_+yNgG0okBRPIJBLK=4yTrguP zELZ^>UIJbUYpL-HuNg=YykUsM^;S%$^@iPil*tDkKFETTFEZfc@*|gtRv`z4$j2Jw zp$N-Sf&!E=c?I)qLjb$564i{L6iSIw1OwjTJ&RK_e83FBfSQE53ES}zpQvrYR?Olv zWHV*A;0wM&hdD80YL(og*z8MZp~tf((H2E&bp8f=;1rE!zvL7b%sJsA*0h%87Q>Ep zaAO1MOW4?rBrW4jIdwLn7Ml?yX#)issdtjM?bv}+*ohugq940)9aS2;LQW4W`bH3$ zQ3d#}{R2i4>@s72@J=FTzNNEJ1@sb7MdP<?7=?1FZv-}F621JLD~-<oT`)|epS1*9 zYS^7xT2#mUds#s}Dff|PKW`55bO;AX9O61k>V8t6M-wjdr1n>3tmm$h>3AMUkh##U zaZAkFq%q253|jkIJLqjEd(=fw&#=DJbhn#M_OMUA>{FPXI!lJWq<<OA{8P*C<v^)U zs{U0Z{ac^#&rYXRcV%YEPP~{CRkld@A~i2jbAWXUdK01UAeP|@b+1zM8a0QgIh@pV zB{e<&shP*gT%epIod>#k3hDGP=plmkX5UTdaf^d>o6|o^zB{D6i`BTto=3$Wd#mq0 jBOWl~Av^Pkllqvwd%`(>%9)CZc1L+ioL)_c=ML{bw6(zo diff --git a/out/production/sp21-cs242-assignment1/Player.class b/out/production/sp21-cs242-assignment1/Player.class index c564c36c856a9e56c1b305b4a260500413ed55c3..d3baf62c663311ac8df80a26813c027b722e1778 100644 GIT binary patch delta 656 zcmY+BS!)wf6vuxzNy%iANh7U|B^ZOHDq}?uT(H!ws81qdK;nx`n}F2XN^AuY^}z>U zmHVs+K3KIb*_v9Vpmuj(5x;=nLOnAR1HSz4oOA!nnRA!d|L8JTe$UJTy?iT~I}FP@ zKIRObIpUnlIs?PH&p4)U8+Rj4K7Vwi(C-v=Uu0W+!DNx8Fv~G=tmw;;x%68_vVXi- zER2i|U(B3#E)+5<Gw2la=XV>t*Qd;s`lK(JcIb;Dt*@AAy=Z0!q9|IpFZe)4m?K0` z&ck*cWv6O{?dMpzI;}MlJr&w}7BG9Nthq->RY*%2DYMS6x`n$TC(2DVHruMk){<BS z_1Wm!lN)JcJMHXeHHYY6Qf@MS6pwf;m4xzym<-~6Jtav1SKmqK4_ySq7%D6k`@&>m z0tKP=Qr7d)Y<I;IMlq>MP=J~UT`RvcAsxk(-V<9|Rc}O$H)2aVX-&5M;~VVa856=T z>F?I9EiOACUV9sCgPpvP1l3INJHFyh{8v*k+EBDG#O!|xzvC;atuv~mM-xMWKNAP8 zDqd0+clRw0O0t`6*;Nv$X|7Fi{e-)b01pLC@A8HWc+=Zvhfi*9(_-5D)gZ4t&1-pF Xhzo080^WG|jt`!b;v=8=it79e9j%Cn delta 443 zcmYk2yGuf07{;IPsOdTCDYLv#X%vnIEgCok?OC8pG+DHmP(dyI39c_~H3n8z-cphf zDl4_@J~Xs9)?X04dMsMr@4Y<F?}6`av_7IVzRMK=A-ralfQe>JVbvO0k1Z}w$5x}U zg~SqVn|3KIkEvG*u5n{T&4M}9DJfUQEzKx{qDcv5K>sM<qfgmMO<C<S;#t6>jmo@J zfq(&fT=zL^3wr4I4br69Ef?U*!;^!T*32#;QPMmV^1==u`Y?`u1mHlL)x(+xhdAPi z-8hDYiLEXJCnWAe$da%`eYy6<3<Y^6Nhq+YrPVg6w)TWJEj3%Q!`SF>OBAuD?Z0{x zCUA-rJ4@87?ua5~RQJDY5NDn1yZYg8u_R7f>97olqr&;(FJIeeysz%EDA7SroU6k& g<=5eyy%H{P$*;;?m7R@ty~924TEF;!C%nM@16hn=AOHXW diff --git a/out/production/sp21-cs242-assignment1/RuleController.class b/out/production/sp21-cs242-assignment1/RuleController.class index de13870341e7e8e6003d598eeecd6ecb1d335618..cfcfdeff757385315eabfaa03c3974a8e2ef7467 100644 GIT binary patch literal 7111 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 T{k&Rra3AABEmh0a3M76BQWkz# literal 6727 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 T*Ut_$kNX%GDx(&tg~<L7Hw`gc diff --git a/out/test/sp21-cs242-assignment1/CardParserTest.class b/out/test/sp21-cs242-assignment1/CardParserTest.class new file mode 100644 index 0000000000000000000000000000000000000000..794bde9fda9c4cea84edd5984070d1824519a500 GIT binary patch literal 583 zcmah_%Sr=55Ukm(iFrSa2f>3!AK-pKM34kQSX5Nvd9oQ|ht2LXJDdOVBzW)x{3x+o zf*3sP!1Q!ichwaA`Stz*V1)e!JXC7%Ti8KWp|{j)9mG0W1b4HgiJU_9f)a9<3YFuN zX$`vyow2s_du?-LpG?jp{y3c*g>FcRxh+;R#`P>_WDus2j;Gp^)Em%uFO>6F;kL|3 zp_z%Oz&8_xgNGt<v@%o5iP=|4k~-}uO_+Qbrgjl53wFjaBWG-&GYZ5H3k`pTCMJ(8 zWkOSEQ2tEuTt499F)eIlu1SpUZF@PFHQ)#}-i{ofFYgBmb<P5Ql^~~YP_LYLXmFIa zj5Rs7HhBweu7D1Ay&v)!S2FjHSpP#*EFi=#Uy<$c3-rrH+NC0ca*=+C2(OFXco=>I D?f+m% literal 0 HcmV?d00001 diff --git a/out/test/sp21-cs242-assignment1/RuleControllerTest.class b/out/test/sp21-cs242-assignment1/RuleControllerTest.class new file mode 100644 index 0000000000000000000000000000000000000000..da9badcd08ce0b4609ba10d8fa911d6f7329d88c GIT binary patch literal 4717 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 KZ?d}zZ~Ygq$zAmT literal 0 HcmV?d00001 diff --git a/sp21-cs242-assignment1.iml b/sp21-cs242-assignment1.iml index 1be8078..98ef083 100644 --- a/sp21-cs242-assignment1.iml +++ b/sp21-cs242-assignment1.iml @@ -3,10 +3,45 @@ <component name="NewModuleRootManager" inherit-compiler-output="true"> <exclude-output /> <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/src/Test" type="java-test-resource" /> + <sourceFolder url="file://$MODULE_DIR$/src/Test" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/UNO" isTestSource="false" /> </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="module-library" exported=""> + <library> + <CLASSES> + <root url="jar://$USER_HOME$/.jdks/external/junit-4.13.1.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> + </orderEntry> + <orderEntry type="module-library" exported=""> + <library> + <CLASSES> + <root url="file://$USER_HOME$/.jdks/external" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + <jarDirectory url="file://$USER_HOME$/.jdks/external" recursive="false" /> + </library> + </orderEntry> + <orderEntry type="module-library" scope="TEST"> + <library name="JUnit5.4"> + <CLASSES> + <root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-5.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-api-5.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.jdks/external/apiguardian-api-1.0.0.jar!/" /> + <root url="jar://$USER_HOME$/.jdks/external/opentest4j-1.1.1.jar!/" /> + <root url="jar://$USER_HOME$/.jdks/external/junit-platform-commons-1.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-params-5.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.jdks/external/junit-jupiter-engine-5.4.2.jar!/" /> + <root url="jar://$USER_HOME$/.jdks/external/junit-platform-engine-1.4.2.jar!/" /> + </CLASSES> + <JAVADOC /> + <SOURCES /> + </library> + </orderEntry> </component> </module> \ No newline at end of file diff --git a/src/Test/CardParserTest.java b/src/Test/CardParserTest.java new file mode 100644 index 0000000..9c4a698 --- /dev/null +++ b/src/Test/CardParserTest.java @@ -0,0 +1,18 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class CardParserTest { + + @Test + void parseCardID() { + } + + @Test + void parseCardDescription() { + } + + @Test + void isWildCard() { + } +} \ No newline at end of file diff --git a/src/Test/RuleControllerTest.java b/src/Test/RuleControllerTest.java new file mode 100644 index 0000000..9c28204 --- /dev/null +++ b/src/Test/RuleControllerTest.java @@ -0,0 +1,190 @@ +import com.sun.source.tree.UsesTree; +import org.junit.Rule; +import org.junit.jupiter.api.Test; + +import javax.print.attribute.standard.Finishings; +import java.lang.invoke.VarHandle; +import java.util.ArrayList; +import java.util.Random; + + +// Test for judging whether a play is legal + +class RuleControllerTest { + private static CardParser parser = new CardParser(); + + @Test // if current allowed color is red, player with no red cards can use wild Draw 4 + void test_Player_Red_N_WildDraw4_Y_UseWildDraw4() throws Exception { + Player player = player_Red_N_WildDraw4_Y(); + RuleController ruler = new RuleController(); + + ruler.setNextPlayerSkiplevel(0); + ruler.setAllowedColor("red"); + ruler.setAllowedSymbol("skip"); + assert(ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("red"); + ruler.setAllowedSymbol("reverse"); + assert(ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("blue"); + ruler.setAllowedSymbol("skip"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("blue"); + ruler.setAllowedSymbol("reverse"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("green"); + ruler.setAllowedSymbol("skip"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("green"); + ruler.setAllowedSymbol("reverse"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("yellow"); + assert(!ruler.isValidPlay(player, 105, false)); + + + + } + + @Test // test player with all colors cannot use wildDraw4 anyway + void test_Player_AllColors_CannotUseWildDraw4() throws Exception { + Player player = player_AllColor_Y_WildDraw4_Y(); + RuleController ruler = new RuleController(); + + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setNextPlayerSkiplevel(0); + ruler.setAllowedColor("red"); + ruler.setAllowedSymbol("skip"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("red"); + ruler.setAllowedSymbol("reverse"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("blue"); + ruler.setAllowedSymbol("skip"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("blue"); + ruler.setAllowedSymbol("reverse"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("green"); + ruler.setAllowedSymbol("skip"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("green"); + ruler.setAllowedSymbol("reverse"); + assert(!ruler.isValidPlay(player, 105, false)); + + ruler.setAllowedColor("yellow"); + assert(!ruler.isValidPlay(player, 105, false)); + + + } + + + +// @Test // Last round a red 8 played +// void testRed8() throws Exception { +// RuleController ruler = new RuleController(); +// +// } + + + /** + * + */ + void testInitializer() {} + + /** + * extract all the cards that the ruler think as legal + */ + private ArrayList<Integer> getAllLegalCardsByRuler(RuleController ruler, ArrayList<Integer> cards) { + ArrayList<Integer> validList = new ArrayList<>(); + for (int cardID : cards) { + if (ruler.isValidPlay(null, cardID, false)) { + validList.add(cardID); + } + } + return validList; + } + + /** + * extract all the cards that are indeed legal (ground true generator) + */ + private ArrayList<Integer> groundTruthGenerator(RuleController ruler, + ArrayList<Integer> cards, + String color, String number, + String symbol) { + for (int cardID : cards) { + String cardDescription = parser.parseCardID(cardID); + String[] result = parser.parseCardDescription(cardDescription); + String cardCol = result[0]; + String cardType = result[1]; + String cardContent = result[2]; + + if (ruler.getNextPlayerSkiplevel() == 3) { + continue; // skip card played. any card will be illegal + } else if (ruler.getNextPlayerSkiplevel() == 2) { + // only wildDraw4 if allowed + if (cardContent.equals("wildDraw4") || cardContent.equals("wildDraw2")); + } else if (ruler.getNextPlayerSkiplevel() == 1) { + // both draw 2 and wild draw 4 are allowed + } else { + // cards with any one of color, number or symbol matched are playable + + } + } +// if (ruler.getSkip) + return null; + } + + /** + * construct a player who has no red cards, but a wildDraw4 card + * This player should be able to play wildDraw4 card if current allowed color is red + * @return + */ + private Player player_Red_N_WildDraw4_Y() { + Player player = new Player(0, null); + player.addOneCard(26); // green 1 + player.addOneCard(51); // blue 1 + player.addOneCard(76); // yellow 1 + player.addOneCard(101); // wild + player.addOneCard(105); // wildDraw 4 + return player; + } + + /** + * Construct a player who owns all colors, and also a wildDraw4 card + * This player should not be able to play wildDraw4 card. + * @return + */ + private Player player_AllColor_Y_WildDraw4_Y() { + Player player = new Player(0, null); + player.addOneCard(1); // red 1 + player.addOneCard(26); // green 1 + player.addOneCard(51); // blue 1 + player.addOneCard(76); // yellow 1 + player.addOneCard(101); // wild + player.addOneCard(105); // wildDraw 4 + return player; + } + + /** + * Construct a magic player who own ALL CARDS + * This player should not be able to play wildDraw4 card + */ + private Player playerAllCards() { + Player player = new Player(0, null); + for (int i = 1; i <= 108; i++) { + player.addOneCard(i); + } + return player; + } +} \ No newline at end of file diff --git a/src/UNO/CardManager.java b/src/UNO/CardManager.java index 5d14b79..4dcf7bf 100644 --- a/src/UNO/CardManager.java +++ b/src/UNO/CardManager.java @@ -83,5 +83,10 @@ public class CardManager { */ public int numLeftDiscardPile() { return discardPile.size(); } + /** + * get all the cards currently in card pile as a Array list + */ + public ArrayList<Integer> getCardPile() { return cardPile; } + } diff --git a/src/UNO/CmdUI.java b/src/UNO/CmdUI.java index 9840bb7..75d95c8 100644 --- a/src/UNO/CmdUI.java +++ b/src/UNO/CmdUI.java @@ -8,9 +8,10 @@ public class CmdUI { public CmdUI(Player p) { player = p; - parser = player.parser; gameController = player.gameController; - ruler = gameController.ruler; + parser = (gameController != null) ? player.parser : null; + + ruler = (gameController != null) ? gameController.ruler : null; } diff --git a/src/UNO/Game.java b/src/UNO/Game.java index 59c4676..9009612 100644 --- a/src/UNO/Game.java +++ b/src/UNO/Game.java @@ -43,7 +43,7 @@ public class Game { */ private void decideFirstPlayerID(int playerNum) { Random rand = new Random(); - currentPlayerID = rand.nextInt(playerNum); // -1 to convert to index + currentPlayerID = rand.nextInt(playerNum); } diff --git a/src/UNO/Player.java b/src/UNO/Player.java index a8756a2..cbf50ab 100644 --- a/src/UNO/Player.java +++ b/src/UNO/Player.java @@ -15,8 +15,8 @@ public class Player { playerID = ID; cards = new ArrayList<Integer>(); gameController = game; - ruler = game.ruler; - parser = RuleController.parser; + ruler = (game != null) ? game.ruler : null; // for testing purpose + parser = (game != null) ? RuleController.parser : null; prompterCmd = new CmdUI(this); prompterGUI = null; } @@ -137,6 +137,11 @@ public class Player { } - + /** + * For Test only. Add one card with Given card ID to the player's cards + */ + public void addOneCard(int cardID) { + cards.add(cardID); + } } \ No newline at end of file diff --git a/src/UNO/RuleController.java b/src/UNO/RuleController.java index 06d923b..2c2a08e 100644 --- a/src/UNO/RuleController.java +++ b/src/UNO/RuleController.java @@ -1,4 +1,5 @@ import java.util.ArrayList; +import java.util.Random; public class RuleController { public static CardParser parser = new CardParser(); @@ -6,13 +7,32 @@ public class RuleController { /** IMPORTANT * As long as one of the following three is matchable, the play will be considered as legal */ - private String currentMatchableColor = "all"; - private String currentMatchableNumber = "all"; - private String currentMatchableSymbol = "all"; + private String currentMatchableColor; + private String currentMatchableNumber; + private String currentMatchableSymbol = "all"; // all symbols can be played in the first round private int nextPlayerSkipLevel = 0; private int cumulativePenaltyDraw = 0; private boolean isClockWise = true; // if clockwise, next player will be the element in player list + public RuleController() { + // initialize first matched color and number + boolean chosen = false; + while (!chosen) { + Random rand = new Random(); + int cardID = rand.nextInt(100) + 1; // generate a number from 1 - 100. these are colored cards + String desc = parser.parseCardID(cardID); + String[] result = parser.parseCardDescription(desc); + String color = result[0]; + String type = result[1]; + String content = result[2]; + + if (type.equals("num")) { + currentMatchableColor = color; + currentMatchableNumber = content; + chosen = true; + } + } + } /** * judge whether a pending player should be skipped @@ -49,7 +69,7 @@ public class RuleController { * @return whether the play is valid */ public boolean isValidPlay(Player player, int cardID, boolean updateIfValid) { - + assert(player != null); String cardDescription = parser.parseCardID(cardID); String[] result = parser.parseCardDescription(cardDescription); String color = result[0]; @@ -57,31 +77,37 @@ public class RuleController { String content = result[2]; // pending skip - if (nextPlayerSkipLevel == 4) { + if (nextPlayerSkipLevel == 3) { return false; - } else if (nextPlayerSkipLevel == 3) { - return content.equals("wildDraw4"); // not sure - check draw 4 legal? } else if (nextPlayerSkipLevel == 2) { - return content.equals("wildDraw4") || content.equals("draw2"); + if (content.equals("wildDraw4")) { + return checkDraw4IsLegal(player); + } + } else if (nextPlayerSkipLevel == 1) { + if (content.equals("wildDraw4")) { + return checkDraw4IsLegal(player); + } + return content.equals("draw2"); // draw 2 is always allowed in this case } boolean valid = false; - // if not skipped, first consider wild + // if not skipped, first consider wild card if (content.equals("wild")) { valid = true; // can be used unconditionally } - // then consider wildDraw4 - if (content.equals("wildDraw4")) { - valid = checkDraw4IsLegal(player); - } - // then other colored cards if (checkAttrMatch(currentMatchableColor, color)) valid = true; if (checkAttrMatch(currentMatchableNumber, content) || checkAttrMatch(currentMatchableSymbol, content)) valid = true; + // check wildDraw4 at last + if (content.equals("wildDraw4")) { + valid = checkDraw4IsLegal(player); + } + + if (valid && updateIfValid) { updateRule(color, type, content); } @@ -143,12 +169,17 @@ public class RuleController { * Check whether a player have currently matchable **color** when attempting to play wild draw 4 */ private boolean checkDraw4IsLegal(Player player) { + ArrayList<Integer> cards = player.getCards(); for (int i = 0; i < cards.size(); i++) { int cardID = cards.get(i); String cardDescription = parser.parseCardID(cardID); String color = parser.parseCardDescription(cardDescription)[0]; // color of wild cards are NA - if (color.equals(currentMatchableNumber)) return false; + System.out.println(color); + + if (color.equals(currentMatchableColor)) { + return false; + } } return true; } @@ -246,7 +277,6 @@ public class RuleController { System.out.println("There are " + gameController.gameCardManager.numCardLeft() + " cards in the card pile."); System.out.println("There are " + gameController.gameCardManager.numLeftDiscardPile() + " cards in the discard pile."); } - } -- GitLab