From 959a678ea3f2216e764852a9c2dca5b46cc684f0 Mon Sep 17 00:00:00 2001 From: FrederickPi1969 <pixinyudeyouxiang@gmail.com> Date: Wed, 3 Feb 2021 22:41:21 -0600 Subject: [PATCH] Ready for test --- .../sp21-cs242-assignment1/Card.class | Bin 295 -> 0 bytes .../sp21-cs242-assignment1/CardManager.class | Bin 3274 -> 3374 bytes .../sp21-cs242-assignment1/CmdUI.class | Bin 0 -> 4496 bytes .../FunctionalCard.class | Bin 271 -> 0 bytes .../sp21-cs242-assignment1/GUI.class | Bin 0 -> 378 bytes .../sp21-cs242-assignment1/Game.class | Bin 2947 -> 2670 bytes .../sp21-cs242-assignment1/Main.class | Bin 355 -> 714 bytes .../sp21-cs242-assignment1/NormalCard.class | Bin 348 -> 0 bytes .../sp21-cs242-assignment1/Player.class | Bin 4874 -> 4425 bytes .../sp21-cs242-assignment1/ReverseCard.class | Bin 324 -> 0 bytes .../RuleController.class | Bin 2867 -> 6727 bytes .../sp21-cs242-assignment1/SkipCard.class | Bin 318 -> 0 bytes .../WildDrawFourCard.class | Bin 334 -> 0 bytes .../sp21-cs242-assignment1/WirdCard.class | Bin 318 -> 0 bytes sp21-cs242-assignment1.iml | 3 +- src/Card.java | 51 ---- src/Game.java | 100 ------- src/Main.java | 9 - src/Player.java | 174 ------------ src/RuleController.java | 105 ------- src/{ => UNO}/CardManager.java | 7 +- src/{ => UNO}/CardParser.java | 0 src/UNO/CmdUI.java | 185 +++++++++++++ src/UNO/GUI.java | 16 ++ src/UNO/Game.java | 82 ++++++ src/UNO/Main.java | 15 + src/UNO/Player.java | 142 ++++++++++ src/UNO/RuleController.java | 257 ++++++++++++++++++ 28 files changed, 705 insertions(+), 441 deletions(-) delete mode 100644 out/production/sp21-cs242-assignment1/Card.class create mode 100644 out/production/sp21-cs242-assignment1/CmdUI.class delete mode 100644 out/production/sp21-cs242-assignment1/FunctionalCard.class create mode 100644 out/production/sp21-cs242-assignment1/GUI.class delete mode 100644 out/production/sp21-cs242-assignment1/NormalCard.class delete mode 100644 out/production/sp21-cs242-assignment1/ReverseCard.class delete mode 100644 out/production/sp21-cs242-assignment1/SkipCard.class delete mode 100644 out/production/sp21-cs242-assignment1/WildDrawFourCard.class delete mode 100644 out/production/sp21-cs242-assignment1/WirdCard.class delete mode 100644 src/Card.java delete mode 100644 src/Game.java delete mode 100644 src/Main.java delete mode 100644 src/Player.java delete mode 100644 src/RuleController.java rename src/{ => UNO}/CardManager.java (91%) rename src/{ => UNO}/CardParser.java (100%) create mode 100644 src/UNO/CmdUI.java create mode 100644 src/UNO/GUI.java create mode 100644 src/UNO/Game.java create mode 100644 src/UNO/Main.java create mode 100644 src/UNO/Player.java create mode 100644 src/UNO/RuleController.java diff --git a/out/production/sp21-cs242-assignment1/Card.class b/out/production/sp21-cs242-assignment1/Card.class deleted file mode 100644 index 06ab6b9ad0af4a07908a8de0da93e50ff6186042..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 295 zcmYLDK~BRk5S&e%goZ#%;RD=&19?CZ7b>Jm5gdwocU-Hu3bABT{>2H20}tR)h%q2> z@XXG5XLmop-ai1$a8e>cT0m9EkP9YT{i5qm_nZ2@-C8pU@+;T7;aZTMov#Y)3Dk`a zYe8mw=YwF{{D+o9aQ$Y+lwr?eE|5hG__Y;`8`s;r-BWABgKj%I)5aU!t#oiv|Cwrd zbkCg7#5EjMF8wYTd+TCi6wS-HP@SUS@!(S!p=2f4NA<(J4mtG!RZSLhcJT&zWs%^J V7{7rOV`BB&fC-MMco#9j@i&E8HQN9H diff --git a/out/production/sp21-cs242-assignment1/CardManager.class b/out/production/sp21-cs242-assignment1/CardManager.class index 974ab506a519a9115a45ae055c217c3654e2407b..688ff8e76e90e2dbfd7b94fe66d7016924b47aa2 100644 GIT binary patch delta 1495 zcmZuxT~k|C6kR7b;ojUFXh?t>0)&rZLmCQ{md_NbfJzIr*iu?rl|Vub0wT~>P|I|N zai-Rf;_<WX_)s7E;yAU{P}>>x!KXg@;5g$r{s4XPRcEa0gixyE+`0Fhv(MRU@3q%H z_g>)hV*B3TcfJA8j;pKo*&Gx30{+!M{N*;hFx>E<K%x*u0-i)_emp*xIFy=73KXjI zt^#+v%>$1}1XeEuTY?fL$Pvh$olDIubY+ifh%$+ghOjpLZB(GrM3uxgR4booZS-Qh zL>M&!Mm&)qez<QkekNWw6`wg(cW`VnIlj<dGh$;0q9$r3cA`$56K&OAG)U}1qkx&3 z@0p%mSR_KYX2gv>Xfn|((Sla>i)a+>D&Mi+vlksEIwkhuF*V_63whBc(TyGf=X`33 z#OU1XV?myjcnZDhTgPt8ivtpU=vRL^${Q+hP~wnwu*mXgeCl-4hKZ*o4x^V<nvKuR zCpG!rZVN*KJ!;VCQ1uR%W!n~p1!6SB3=7BAk49LWQ1^|FvS%co)sUW<)6?3wFFCQG zOFJqN$Cx_dY+(`!i6kb}6=zkh7tc$$kP--l`_y?+pni3_c;p3%DNL*1o!i|nV%Ee< z5_77=6|}UP3oP)hVb^QI?_(GpqI*+O^+Qfm-a9rfVb#RDn!8d(=J(=#^|RUJ{76uy zeO8$oHBH0BWwqC8UZ$iFIKx^waF#E-<e{~VJZ#~fMVkvb{JzZ9C=AYk%E%hTU6{w$ z;JyVrau;4seP6*JNn<PD;x96|i~JVT8*sx3jp;!E5~avpW)J0IiCc0V60hLZj8ou2 zxD|$T&{n${pwt-)dZ#``VdP7c25+N0jYo%9gt&hHH*L9%h>mPvGjcv-`rzji;#f_d zQ8Hap<L;;^QJ36>%cW`5U&hc)?Dn;#5#y+#(s=w1o&abuV!^EC8mhQ`lazJ%H1>ao ziZlk&804``8b4{6BV1jFUr&#&Bl?bU+)ORPV(8M?2qNU;#oNZ3G@uLzI1Zv5CsBz6 zs@M<Js>`n5!T!o>u#2PCz{;ld8Rw1+U#$`lR-f2gm&a(+iv3CToE(ROSCOmp8DSpc zMpm$XN_8@L4gL*&iH-<~Ki9AKHNHWP<7+rIP#aBSa`=JiYs?7L-XO3u6M83$3=(ki zGD|cfl!qo(xtWYw_+Mz{g^!^VdMH?310_SAZcm}4hTt)NI<^hA$&v)%YQ?YuWx z28(215WFIrlYb+p{(ol^)!D2IpO<myLOy>DAztAvvPu-GM!9F1&Y7N>-|SDDae#iN zJ&<WfofVLqZAU%3fODCezwy5s_}M7`)!@iOjcsL-3|yq11b-86F@U~UZ}WW*A8=)J L_8~sT6$JhPt;h?o delta 1478 zcmY*Z%~M-d6#v~M<b{_D@=+dzKxp|8NcsLMg-}X?R$6F_6=<<qUrCCgAz~7WR9jpy zF8nNBMXj#tqBD+TYtc~K8OMdI{sHRBz2l7I#*GX0cS9(3@!omo+<SlLch2wJ_f_e` z67%6d_rC|wi%-|grH~0P@+Au37AT0sBFTsyja&&2+VRk-NHnaMcS#iK<(!3hB$nJ> zF;FZ}IA>qBn-`OjX!AfkZZD5U5=j#loY_2AD&a$!fM@M?rPq%N1A8R)qEZFK0gr`h zi5fhqE{Q$fI@B8oNbEy{S{FSv7MdiQ(IQ|(62tQg$z=g&UHx=6+R$#GL!uL1>Mzmm z?iLs}P1Wi+l-JkSXQBta27(fOIH;~UdMYd&k{G~Y0at=$rC~-2SpJa2Fpj979UYSv zo{|{BF)q%AlLAF`BlV-{!lHI;w)y0Rx$sP~*MuLV5@Q<6!#+&f(M7h$z)6WyI3nO( zu;Ynz<3@%&cv{)cW3Fcef+QDodN8T}aMp=4s@QeVKP~aB#_`4$=XF0v!xz~$FP@Wl z9_LlU)y@9c5*IL|He6M7!V+1ysD5?%^DVq65y6~*+YW^WqESYDN2k4rV%|VZ;w3Fs z?v65A6oIUnXxNTxU0#-mYhApdNMh!Z&K8msWMeAps!+eVJ96JO@gA-lSksMqU+pt~ z6d$NRjV{+m0yXNoQLJJ{uG_#T0{)C^sD#H_q2>^{%pN<i#D}>a^G)R939cE8Wx>t& zEA+;>PtX<zHX$CsIJ=4L4VZxx^7s^fod#Rx+u|W08!l)dFXvV=mV+yd$~44EF<!-M z=>r_<4E`#d%m6e79>5~_?r%}z3i|S*pQ9-74N83XP@Y27)T$7-{{3A??x9v^bwXz? zB@mFueEBG3&I;NZ>_P)ChR$peJO{gR71yBFv&&a_Uox40B2}GvUW2C4cmor6(OR%S zg#)x(!T$Rg1Q>A!eVNEjRB`z(TcFvcaP$ZGQ#hW&32sZX{6)iz)4PR2{dsx|v0#F> zbBB6>jRH#eE+ugvs;NdR%5j`_oQ0g@jSQiZ!&9wh&6X9;Wrleht=7boq4Xuc9qD%H z+JM@}n(oQ;T;O$_=Ps@3-;~NlJK_5bIhx@VnTb0Y0mi87S>H_*ZdV*S7@!39xiP&# zr*yLH7d8<((b$l}?9`*sceo_bc!$WYG@B;M0<_R;<p{KKEIKJj7q9Dn)S(+q{MGd% z$SLl_Y5o?Lyp7&6a_r}>Rg|gQ-i9+)W?tW5oHsC2!7?jw5_@lk(!w^SvHz24&}6nI zB{zNGFy~{C%^gzhvPzVxDcR}g;q;Itc81wx9$=KL$J7_Hyw-^~={xWi-lp}i%kS_} P_>i8-uXTKk8z}h?OX(27 diff --git a/out/production/sp21-cs242-assignment1/CmdUI.class b/out/production/sp21-cs242-assignment1/CmdUI.class new file mode 100644 index 0000000000000000000000000000000000000000..77e01a48c317fef0d98274cbf4e604c9d13d93e3 GIT binary patch literal 4496 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 literal 0 HcmV?d00001 diff --git a/out/production/sp21-cs242-assignment1/FunctionalCard.class b/out/production/sp21-cs242-assignment1/FunctionalCard.class deleted file mode 100644 index a4e16eae874d691483e7e1c6a5672e770310e5f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271 zcmY*T%MJlS5UgQX)^mM<BMy83aglJ@xU9JMt_dS+Hd(X&%Sqzk1ALU|!9^dcyQ?bI z{e0aY0Hz3hlu-5{o2Z~FAQzPH1gbM_w4Do-2g9w0nm~J5n8fPLQ2MpVMYdA{olqOK zE>5w^Hx#GL^ujEmbW6E*`;V0Npw9x`@IPkC0m*^PUajb)B1@J7{3t8(L@l*TtGjFC xBV9=L;qkMs9P+zhnWqVN;h514;`)(&MkfOS8jQ`afqM&(K$}%C*I_K7`v$)1Gywnr diff --git a/out/production/sp21-cs242-assignment1/GUI.class b/out/production/sp21-cs242-assignment1/GUI.class new file mode 100644 index 0000000000000000000000000000000000000000..522f938ed17184c57cce32dea7935c3b44d68129 GIT binary patch literal 378 zcmXw!%SyvQ6o&tkyJ<{nz3kn!D)s>?ZUTxBR8Zr3k`8uCOeCg4-^q<D!G#atLy2dm zkzxLG|IW<M@7Fhg8TLb1uzffYTzG`xQoM<2CF-Z?O|g_^NAS*6t-5o9J)Yz~0(LGR zt~mcviM4DAL3V4r8DTK~_a`~QNt?MOB$=w^_3F8h?Y$@}&Wy6A6jd%-rQ<&7bPM%L za5JVeD$)2<wDU*REzCmR&uhcGX4RJRLTOOIg;V`x9Kz?H0K|6-A*;o{iverIQOZ`= z{i9FNarR*vwpnA?tTr4z9uLGE9c)^WV8{^<86+`c2csT%!d5S{?02ouEYD<O!-zK3 Ko<Z0(U3-7$(>jF! literal 0 HcmV?d00001 diff --git a/out/production/sp21-cs242-assignment1/Game.class b/out/production/sp21-cs242-assignment1/Game.class index 7f3e15de9302c0b8df639fe6a9f0d75bd3d619b5..cc388d7240516f9285c00e9039b390411bff60f3 100644 GIT binary patch delta 1400 zcmZ`(O;Z$C6g{tJn1-goIAwu=zyzfjM~8eAg@VLNITDySe5i?tMx?`Zkcd5FcTZ4a z9KX$XqMf8F>nzx0W7O7yN-B%2vQK51Z8pgd$U<^n_W-)^b<OMd?z{J%bI*M}*Bk%c zqW%74`4<5D@ZBA4ur_8FN><(x5ZQaDe-u0R3TVk}Zpb)i?%R1xLl63O`nCzw<ZWXi zW7v7e>s4mUy1=HHl5LxoJ3en*H0|s`4O?(XM-C$b^|Pj%bu#mXnX?OXjwujH?mVF( zjWHeLI4lr#<`zS9R>mFG@fO||h}&kdV7r+x^HJAu=~R<kBNQj|2_45FCcQtDS2daO zq>guR%G(?1D4*6bjhKL5B&9LSJR*yWLtsKfHD+|=<!P;5vepiz{XHGC(jG4r^TZo9 zFRYiOVvd5ys>co6F>MWJ5UF9zypD6Q1Y*U&PRLxw@cN>EH`hI*3dzq>OBQ0g-p^J2 z^|v*Aj89a2Dy#U+tBU<r{z9N7>vlN_tFVv=#Y_lp-I8r}cXwCgD}iC{=`rw}kq8PF ziT%$TnntEs%QEfEyx};eqvCEvpwoLL))`arjX)chZQh{T(8~I#b~6glsbG<71?Tyz z<sM#9ZR)ZEn?qYx+7P2(71}tv-2H<nA7ILRtiD$6SV7O^w$vl^j;3Ewee|Us;N`TB zfr%T6SX%w-9z7!{aqdMO=SIfXp$1!dIhxQ;9y_oNyU~h0NMJu+#4tKAitU)-{uDa# z0i#lk8pb9p-~zMtG3FwfDL@%hSj2~PAt77}O8SWF%}`e97g13y1n?j8Da2T-;W)EI z=oVkW>ywXgU?jD>#Yg5Lh9qAl;9DPfq<Ja2neL^4M<R?`hm4minAOm5nQRn3ymS?* z7U@oO^iz~ZA8&q-ttl>tqSI0(AEQMgE}=Cv<}1dh4>#nC2cq{9XAfoT<1;`?WdtP? zqQXfQABEE1L?ZkuDn!nc2-QMb5=r?u@)O!aBFi`i_~??@(&FR9ujt9`@-ej`MFZOp zWGKZ!Hf<0|yup?YhxiR)<_dn2u2<M4{`27KI)14lgv3{?en3}<uP(y~(S5v2T4rjJ z=h5khP?uK!+^D^oiGV}I&+!6{poJHt9b@Eh>2S~&d6QY)vl?I*1Fo%ekT*b%+7+B( t&)>g~vl2lB&6Yxe+D34lZv{7Slka-2Zt>*vVEz(c2R;IK;Ne>|{SN|@0K5PI delta 1654 zcmZ8hYf}?v6n@@pU^gLhi4-eV3}OXBxJW?}s=Wlu!~&uqH;ZLWR)~ZR>?R=E8e45` z?bW6??ENys7r)rnI3qKie&|eR`Wrgaf6(z;XZoS^c{d1SGnqZ_<(%_8=Q(HhuktI~ zyubf@?`HsA`2L3XNNG{r4kwb)nUT0{2#E39<F`aZl^1O|=tC#E1UxZIUkvM3%oZrC z>y@iM-PETHt1D7JoDI6BI*tmIMAMdKn5lt;zGPUDZsv-3(TH9j`p_@nw&NEFpw!hz z{6rt{;W$oY%aqoA8ioX_2NH&E8-eI_GD(v(xg<~^l?===V^dR;Og8Mp2u8Dg%I?g# z52x?~apkq-G!jouhi7BtTi4s8&l+9z#Mf}zhZiNjKW0SZF{9r&zd=!hPF^Olyoe&E z!tmiNo)RcMr!VNu3EiA(9!yzrb4sAlm{02oTf?+0WhQ=nPQy8Y0;x@_h6G_3<B3=| zw{03s0o5`V49hk&%rQdVsjvjRlInoY3(JdnC>~Nw`>=q;?4Qct&lFi{^O$LzNTy9z zvgIL71$<P;HcXj93S1JMCPhOQJDAc_RJXP+d%a-i;XLWC`eEXk8wHbXG?_?}gunOy z1+vZB*|Zr=#gk_CzPq#d6E8l+vWlCsPoHHw3Vv<*LZC9=-GJB^3Pe)1c3>%)wgRcN zWmc12#54^noX~CCuvL7Wy;vA@e=AUxy;NA0{jIQKf>pBhl{k;15Ln{cg$rD5=NV}I z*y`9;Ji*;X=l&)7MCdPli{PUz<Xr)(_<WhW`%vJf)w7-Iq0Hl}Xd8R%F822~27f|n zshUFv7cGrBJUMdJC05q{xJ_pTm-yU|Eqp%8@G^KvqMS5#VF&hLCqe``fNC7ZZuFpr zBJ9C9_mkL*45NaK>LK0Bc!k*xq86``WX8oS9anIbR<2%iDt(>nGPu_0r>M|`0RCYf z7jYhxG0uDn-O5+-^w?cI+ZPP&a8KqCzJngg*yS)Tc6^#RGtI<qahL@1aSo_t#xnA# z8r8anHyG-YufV!q)7%jsQXh30ewrTlq|_*f=jU!Y+t~Vc^Oym7&GHNmKt%^C_<fLw zzI;M5$jG{7wF*Q9f!=hQCEIk3J6T`*57;F!?%^1aLoK)dL0X9@&vQ8W3)*@cf;o&G z3i3JekN}lT2!v6BZfwI5iufE`)x)n<L{iBhuSWZN3-;3SIy)rj<iT5Ph7{v%yptD0 zc*sc(kKN#>)@PQXg#1&^qWA&!3PwZzxN}zJkR+u%$^3{FaKcv57V^)~C$o&g71V|N zvra%okP+%lsO}ZGl{-*Z;0yVa&YiM3hfN%8P!A7=_zIllRE)5&QM6->^LL8h&j}3U zG~#Tdg)@%ka{k&G@vbv}tYEYMHr~VgPD^au;L7E6Bmm8`wWer@^S4GcIfp8u{KF+j zvOwcdeX!B48b--q(JJOSj`oj8Nxs6FLiqv$UTT-6b>TyNM62=ik&pTK9A7%u0$<@9 Ie24A-0o+_jNdN!< diff --git a/out/production/sp21-cs242-assignment1/Main.class b/out/production/sp21-cs242-assignment1/Main.class index b12c256cfd7b300357d11523dd86ac945017b47a..5d1ffd422a79c99acab364e4815d253e3094eaf1 100644 GIT binary patch literal 714 zcmb7CU279j5Ir~9WV`Fu#*Im|ADVuso79>g5b>o@DQs0pNs&I?q)U2Bc2~9=!JnlM zDJb{@{88eWO`!;R>4lxk%$#%XVRruf{rMX}AFo}MP_|)tsGzD)yV75EZ>p0?@8jqy z8s`etw<a<9JB4!489G>jW5f0E0N#J_!ME!?iit{RBsIc9$fUhbnMv|No<%zDui&9V zc5wgGey`)GJ;-&Ix9`tBa8bh}8@`7+9xK$BcvG;yh|_68^TEP>F$P*U$)w*I+Gr|R zV#GxQPh?<ESqP3hLn&-{*pvx66Cw(yHlDG6q75aj!}KCjSPM-OeVE0gC_B}oDJy=M zj`eh?Gb8zJ(aJB)H76emxleXnh%|%qWyaXo*@XD|k~V+HEJ;O6oKwpkq_b=s9T|Du zkq6$$IIxW^u7aErlq>_|b7no>ig%@Z1NFUVw;81ke%p-R0)QRtGIOwp7pw^R4CO+! z^#iuQI>*{CG(Oj=H)w_XbFAOV`LGDDa=ZAO7@OQLk!~*Nc!^iceEJH|p}0bqc?tXf E0F|(aT>t<8 delta 169 zcmX@b`k0C9)W2Q(7#J9=8AK*>=`*u4a7@l%Y?=I<QL3Jufe9$V03;b1SQ*%WBqxxk z52P7^G^^Hj2F8tGX)YiMl4by6ZXn46Q2?ZQfjmwIJ_dfE2uQOwSPf7ex<*zcjf@Ne R41x>{TtGcSK=n)v!T=cd4VVA` diff --git a/out/production/sp21-cs242-assignment1/NormalCard.class b/out/production/sp21-cs242-assignment1/NormalCard.class deleted file mode 100644 index c0d199f37e0e3d28ce2f7f992f7f3fd0890ee328..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 348 zcmZWkyH3ME5S+CgJ2r-Zc~lfB6CUvg7-*1?BAwD0xxYA8ICSwzhr@qSAyM!Fd=z5O zM53VC-I=@Dnf?0y_ykbkG=T>{LXcvBkPzHUyCQ@)s#V<`!Jka42tz`$Fm@yL?z!D= zmW?IQoNzV~&+=8~TDI%F?5t|n#e7=1U1rq~MnbjCq8B{MrDi4*rk1*rRyn*QgYHSa z5K{4HR1gNW(T0t({~nyFG+SFY56Uf#U9_1?f-xe#3g8Hck@OR<!X7gzqmsMNJ-&Dc wU5fMDHwGT|xn?W@uDD(!#0*2^IACV{E5Hbcj97{z{!9JjEIgi%8F@JQ0Wz~dPXGV_ diff --git a/out/production/sp21-cs242-assignment1/Player.class b/out/production/sp21-cs242-assignment1/Player.class index 78a74895f68428c4acc365e4b6f881ba2a12fb13..c564c36c856a9e56c1b305b4a260500413ed55c3 100644 GIT binary patch literal 4425 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 CSPq~7 literal 4874 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 diff --git a/out/production/sp21-cs242-assignment1/ReverseCard.class b/out/production/sp21-cs242-assignment1/ReverseCard.class deleted file mode 100644 index fc60d312aacd23517ab823ac46b779f96d1751e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 324 zcmZWjy-or_5dH=ZPL3acS}7<&6L|oP4GA<C3o-P=F@Yt=Ub5`*UREX+K7bEJoE1Vy z++t?FzuEaYe0>8L;Wj}9)fiC=HPi{6Nog~03d{MJ-I7p$HrDtTLbX4b$G9Ri-()Xt zCr3RR7fT^rr^d=_xm}2R=S8l}U0P(E&)J!PPh{lRW=CkJ7du9p&em*KGUctzJbO(i zv!ZmFOiWnS2wy#Ic+cn|)`P<fRZoV>It{f`U>-g}AAfS9HORm{np#^&gZ8!}pmPpC UDhj@T!R|$nPC>m^trgt-0u*{S^#A|> diff --git a/out/production/sp21-cs242-assignment1/RuleController.class b/out/production/sp21-cs242-assignment1/RuleController.class index 34888e1961552e77bf1cf5ad04da7afffd917e93..de13870341e7e8e6003d598eeecd6ecb1d335618 100644 GIT binary patch literal 6727 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 T*Ut_$kNX%GDx(&tg~<L7Hw`gc literal 2867 zcmZ`)T~ixX7=D&~>?SM?ga+IeZ0#orSQHDT0kITpi483liY>L;B`mP*lF-ejNUy!s z@xpP2j^6Z!n>wRb=#0)dUU=n?@Gp4pjMnFzT>>fTBy;wh_k6t1`@GM2&!7MO@*995 zJc^?MAr)aA5kwU<-!mVYy^dL2>b*99&nkEdqQiF4_C^$hy3(^6G<HnKi6M?g6}pZl z98hrJdd0EEN=45tIgaHjXf0G+*D89Wj#FB*7RE|WiPmI(_xx$kwTnwb;-F?7E#j1e zwVSS1R^}~NENInnu+D<%^_BUOgwm#?9j_7Ws_B-6e?32Dx(icsG!(}n99GexqZ6+y zi0@7*Xp}pIB{!}h)s;){$0+t6)$s<75o2}zxK%E=_Nr%>iV9A5?cbKZz26pRG$(YN z#3_<iShfoHM?KG-G`+%d{X_O2k)G4gr69IuI}78kxpp>=47yeH=y(%nYI5jvOj@i5 z71Jq;`1YLVXLu+*CqTWW<8AaQXpx}gxw&%QS~4AS)Rmud%yrA<S`B9vG+Z6kFrXk@ zEEO#cgVaQMeMLi-onmDrj$yp3VnoM#xIpjzW(C@k<q4(<q`fQPx#HPQ@2KmV>v_BE zF;y2area*j`?y3INxjsrq1&?k$dZE0iS-jYa`=E_9=|VzL69o)jBQtaxuRz+S#BIx za8<`O;Y+iN-mK|VERpUIy^NI>=p~W2i<U3N8FSvDC7CZ3OlQ_~Z7~jvVQ<-HT+R8~ zn=nN7>@ttF7X%9mnyOsp=F)RQv65N3-{F|HLLf&a#|@R$1=F)~i}DZ!3O6Ohf*Sor zU8`Ji7=CLV(J6=&{0kWN)>j#UTHsaX?c~Hm0gYa!J+p9s(p;6{sJKhqj>!Iwgqq6o zzRr}!glGxF7N`2jO!=a!O%o$;t0juA1F|ypHVp5PW{{qt5uVb_v<79wPXjOEj(TLJ z3M$D<>JF^wS@KCuvXW4BLVz`e$uA*vQm#7LF-0k9mKU<U3m~XtiQUzKMH?<SL7j|G zmnv?-x?~HjwARYuj8Gs8i72~3m|vDH_8LSPm0uP@`DMN1w-IC+QMMm)G|6=ezwMdl zP%=q%3o+RyWSjg^ZoJMm$)kY~+X!7m(F_&SwCMhJ%-{w`3TE+<f3)%!SI24F`U$Cy zZ5Y`wJ4SdLN3szk66(uFjYzmJs~V9=UsekZ#4?$m5i_FOIKF{s*dHehjpN5?7L!Ri z@Fxu|d3qb^4a76u+vpvLrD7Yn(z$`l86%o}M^0(U{!K)TD1$Q8<T+_eW(;i$$xO0; z3yDn_oH#Eh5^{oZb0QgfDuWe)&mzUP1u;_4%Adh^;|Ogh(S|NE-A~IPulIEvCIub% zlrO>}j-teze2!!I636j1PT)K4*u*J(kJEU@@+!z%^a%>cBUQMGTawT%%;C1o=oUW4 z9a0&?Q+&b<hKb<`z1(FY415cdwkQ#OgL(E;die?k_E^#J1s1qB28+I~L3=@<aaH_> z6-7lx#iDH4$xsAFL-S3}z94{CuWFF{Glx?I$0x_nH9_#rr<3;Xq)Ij)qp^osVRqE; zCc=Bz6uJY>$moyyTdL8wV~Mz>8nMh?gTx(0s3mlP4}^G30(XCNr1G2zIvJV_jdb>G zWAq8KJ)PUQ{5!5}V{$;KEk(5%*@)0xgu0WOi&97li7gU(`gus%eDOzEWIN0Zg89<e z_LJKIByf)T9AuE^={buFv|ZvmBr-Qa{~gS#$WoXq4$0g^xb8rZ5tT2M%~?UqL^Z~V zAj1)i;U4ZY4u|vN68V;uAnGQB{)MXIqB8gorxX+^DF4d#@+(M+h(LZ|r$Hk3nH}GA zDI?WOS;T6vd4#J)orq?-c`J6Ww_iOb=qe{qX!BQ9aYyk$=0<^A7fAADAX9aLl<Nc8 zQ)hf2GX!$u6+pZINTn{2*vmlf)CKaeK9GHkm;^Ha3LxU<@sY(^wVEE6tg*)aibJ=a UW9k`Ff?{P)g2EhqCX=@QKO&tcdjJ3c diff --git a/out/production/sp21-cs242-assignment1/SkipCard.class b/out/production/sp21-cs242-assignment1/SkipCard.class deleted file mode 100644 index c02cd7f71a286e5ad19fc39853c9ed34c6c78034..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmZWjJ8r^25Pbs<28VwEZOVKkasUtw5;PW#5&d9RVZp4Cv(CM!B2jRF94g8z5QM}Q zGxL74^YeQ+0_dX^pn#$euZjnh2=#GpVyjcb$%wNhp)}A&+aaO&{4)1ZCX}O%-kn8n zlr9ya5o)8R`F5eQ87~rH+F=@VGUrS?d?7u%(w~GN{9n+QXuM+cp(ealk!35<AWHKr zR%7k<RNOzkHGeUl;LEA*xhls(WSQQjlVe`LLHm;&NOdyM!K2jb*&w|p2&iAfZ-Sif QF4(;Z(j_R@inV~|A4Q=wTL1t6 diff --git a/out/production/sp21-cs242-assignment1/WildDrawFourCard.class b/out/production/sp21-cs242-assignment1/WildDrawFourCard.class deleted file mode 100644 index 9e4b901ea9654b97769f1f8bc75fdb65fca62b70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 334 zcmZWj%}&BV5dM}{iWL!g0uGq?ljsA~c)^rQ!v#{#L%WeRWt*&9eJ)QX9(({E$~Xgr z7~R7+JM;a_Y`#Cg03<k%(LxX*?BWP*g<jg&!kgMsH6~XowC{~I{y`zQyvieV6#5HO zm5+|z(z<awQ8=zkt#FnZtEbI+sok8G6;B3PT~L*iGt%#ep<kI7;r<3C98s*uKIsXq z^~{s!h<L_p3Y{9sJC=R7&-6+dBI48K3G(q^ntyj(l}xTbpx(E1%qTQ4!U<z{C*XR@ Z9nd?NZ@3fPKjXzOquLw!T9&rZ{{eBoI?Vt8 diff --git a/out/production/sp21-cs242-assignment1/WirdCard.class b/out/production/sp21-cs242-assignment1/WirdCard.class deleted file mode 100644 index 4a01bfee7641af2b98a6d1d4dd195e295e5540e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 318 zcmZXOJ8r^25QhH&gNef<$qAA!fRr47hz1E7D-DR$gS`ri%v##4xffL=3J$=b5VO35 z#1`}V|8I77`^^?W56=-wD2E8@sGv${4hxewog2;uY*Rw@OB?O_gz|fP8lpz1{b-w> z#9)x8iqML+QQyUKrtE}gnM_{dJmGB0R{Q=u4BTA*5u*6ApeJZDXY;E@yi{YyPS9wa z7dBBt?e{$Re?AtxV!R@hQ~mQ%j)llleM%-j>HLG%M>&${WeD^rv3@d0Zb%0-uW(m7 S@4ExvZa_MNa;;cPcsc+`hBR#e diff --git a/sp21-cs242-assignment1.iml b/sp21-cs242-assignment1.iml index 9465dd8..1be8078 100644 --- a/sp21-cs242-assignment1.iml +++ b/sp21-cs242-assignment1.iml @@ -3,7 +3,8 @@ <component name="NewModuleRootManager" inherit-compiler-output="true"> <exclude-output /> <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/src/Test" type="java-test-resource" /> + <sourceFolder url="file://$MODULE_DIR$/src/UNO" isTestSource="false" /> </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> diff --git a/src/Card.java b/src/Card.java deleted file mode 100644 index cc897fc..0000000 --- a/src/Card.java +++ /dev/null @@ -1,51 +0,0 @@ -import java.util.*; - -public abstract class Card { - protected String color; - public int cardID; -} - - - - - - - - - - -abstract class FunctionalCard extends Card { - abstract void changeGameState(); - -} - -class SkipCard extends FunctionalCard { - void changeGameState() {}; -} - - -class ReverseCard extends FunctionalCard { - void changeGameState() {}; -} - - -class WirdCard extends FunctionalCard { - void changeGameState() {}; -} - -class WildDrawFourCard extends FunctionalCard { - void changeGameState() {}; -} - - - -class NormalCard extends Card { - protected int number; - public NormalCard(String color, int number) { - color = color; - number = number; - } - - - -} \ No newline at end of file diff --git a/src/Game.java b/src/Game.java deleted file mode 100644 index 23d3a9b..0000000 --- a/src/Game.java +++ /dev/null @@ -1,100 +0,0 @@ -import java.util.*; - - -/** - * The class for recording Game state - * Organize the interactions among all other classes - */ - -public class Game { - private static CardParser parser = new CardParser(); - private static final int INIT_DRAW = 7; // every player get 7 cards at beginning - - public RuleController ruler; - public CardManager gameCardManager; - public ArrayList<Player> players; - private int currentPlayerID; // playerID starts from 0 !!!!! - private boolean isClockWise = true; // if clockwise, next player will be the element in player list - - - /** - * Default constructor for Game object - * @param playerNum - */ - public Game(int playerNum) { - gameCardManager = new CardManager(); - ruler = new RuleController(); - decideFirstPlayerID(playerNum); - - System.out.println("Loading player information..."); - players = new ArrayList<Player>(); - - // playerID starts from 0 !!!!! - for (int i = 0; i < playerNum; i++) { - Player player = new Player(i); - player.drawCards(gameCardManager, INIT_DRAW); - players.add(player); - } - } - - - /** - * Randomly decide the start position of this game - * @param playerNum total number of players - */ - private void decideFirstPlayerID(int playerNum) { - Random rand = new Random(); - currentPlayerID = rand.nextInt(playerNum + 1); - } - - /** - * decide the ID of next player - * @return ID of next player - */ - private int decideNextPlayerID() { - if (isClockWise) { - return (currentPlayerID + 1) % players.size(); - } else { - return (currentPlayerID - 1 + players.size()) % players.size(); - } - } - - /** - * Run one round of UNO - * very import function ! - */ - private void runOneRound() { - System.out.println("Player " + currentPlayerID + 1 + ", It's your turn!"); - System.out.println("Please choose one card to play..."); - Player currentPlayer = players.get(currentPlayerID); - int chosenCardID = currentPlayer.playCardWithCmd(this); - currentPlayerID = decideNextPlayerID(); // update the player for next round - - } - - - - private void changeGameState(String color, String function) { - // change color - if (color.equals("none")) { -// currentAllowedColor = "all"; - } - - // handle function - if (function.equals("skip")) { - currentPlayerID = decideNextPlayerID(); - - } else if (function.equals("draw2")) { - Player nextPlayer = players.get(decideNextPlayerID()); - nextPlayer.drawCards(gameCardManager, 2); - - } else if (function.equals("wildDraw4")) { - - } else if (function.equals("reverse")) { - isClockWise = !isClockWise; // flip - } else if (function.equals("wild")) { - - } - } - -} diff --git a/src/Main.java b/src/Main.java deleted file mode 100644 index 0003900..0000000 --- a/src/Main.java +++ /dev/null @@ -1,9 +0,0 @@ -public class Main { - public static void main(String[] args) { - - - } - - - -} \ No newline at end of file diff --git a/src/Player.java b/src/Player.java deleted file mode 100644 index 6a04fa1..0000000 --- a/src/Player.java +++ /dev/null @@ -1,174 +0,0 @@ -import java.lang.reflect.Array; -import java.util.*; - -public class Player { - private static CardParser parser = new CardParser(); - private ArrayList<Integer> cards; - public int playerID; - - - public Player(int ID) { - playerID = ID; - cards = new ArrayList<Integer>(); - } - - /** - * FOR CMD LINE DEBUGGING - * When it's this player's turn, the player must pick one card to play - * @return the ** cardID ** of the chosen card - */ - public int playCardWithCmd(Game gameController) { - // instruct player to take a move - Scanner inputScanner = new Scanner(System.in); - boolean receivedValidInput = false; - int action = -1; - while (!receivedValidInput) { - promptChooseAction(); - String input = inputScanner.nextLine(); - try { - action = Integer.parseInt(input); - if (action == 1 || action == 2) { - receivedValidInput = true; - } - - } catch (Exception e) { - System.out.println("Please choose action from 1 or 2"); - } - } - - if (action == 1) { - return actionOneCmd(gameController); - } else if (action == 2){ - return actionTwoCmd(gameController); - } - - return -1; // user did not play valid card - } - - private int actionOneCmd(Game gameController) { - - int cardID = -1; - while (true) { - printCardsInHand(); - System.out.println("Which card would you like to play? Please input the corresponding card number..."); - - int chosenCardIndex = -1; - - while (chosenCardIndex < 0) { - chosenCardIndex = getInputtedCardIndex(); - } - cardID = cards.get(chosenCardIndex); - if(gameController.ruler.isValidPlay(this, cardID, true)) { - // maintain list-cards and discardPile - cards.remove(chosenCardIndex); - gameController.gameCardManager.insertOneCardToDiscardPile(cardID); - break; - } - } - - if (parser.isWildCard(cardID)) { - // to implement - } - return cardID; - } - - private int actionTwoCmd (Game gameController) { - drawCards(gameController.gameCardManager, 1); // draw new card and add it to cards in hand - int chosenCardIndex = cards.size() - 1; - int cardID = cards.get(chosenCardIndex); - if(gameController.ruler.isValidPlay(this, cardID, true)) { - cards.remove(chosenCardIndex); - gameController.gameCardManager.insertOneCardToDiscardPile(cardID); - - if (parser.isWildCard(cardID)) { - // to implement - } - return cardID; - } else { - System.out.println("Sorry, the newly drawn card is not playable :("); - return -1; - } - } - - - /** - * helper function for playCardWithCommandLine - * parse the integer inputted by the player - * @return the ** INDEX ** of card in list cards that user chooses - */ - public int getInputtedCardIndex() { - Scanner inputScanner = new Scanner(System.in); - String input = inputScanner.nextLine(); - int decision; - try { - decision = Integer.parseInt(input) - 1; // -1 because we want the index in cards list - } catch (Exception e) { - System.out.println("Please input the number corresponding the card you choose!"); - return -1; - } - - if (decision < 0 || decision >= cards.size()) { - System.out.println("The card you chose does not exist!"); - return -1; - } - return decision; - } - - - /** - * FOR real playing scenarios with GUI - * When it's this player's turn, the player must pick one card to play - */ - public int playCardWithGUI() { - // not implemented yet. - return 0; - } - - /** - * - * @param dealer a cardManager object that is responsible to deal cards - * @param numToDraw number of cards to draw - */ - public void drawCards(CardManager dealer, int numToDraw) { - ArrayList<Integer> newCards = dealer.drawCards(numToDraw); // Initial draw - cards.addAll(newCards); - } - - /** - * print all cards that this user has - */ - public void printCardsInHand() { - if (!cards.isEmpty()) { - System.out.println("\n\n==================================================================="); - System.out.println("Currently have " + cards.size() + " cards:"); - for (int i = 0; i < cards.size(); i++) { - System.out.println("[" + (i + 1) +"] " + parser.parseCardID(cards.get(i))); - } - System.out.println("===================================================================\n\n"); - - } else { - System.out.println("============================================================"); - System.out.println("You got not cards in hands! Congrats, you are the winner!"); - } - } - - /** - * getter for cards (private attribute for tracking all cards owned by a player) - * @return - */ - public ArrayList<Integer> getCards() { - return cards; - } - - - /** - * prompt player to take action current round - */ - private void promptChooseAction() { - printCardsInHand(); - System.out.println("Please choose you action this round:"); - System.out.println("[1] Play a owned card"); - System.out.println("[2] Draw a card and play it if possible"); - } - -} \ No newline at end of file diff --git a/src/RuleController.java b/src/RuleController.java deleted file mode 100644 index 2447ccc..0000000 --- a/src/RuleController.java +++ /dev/null @@ -1,105 +0,0 @@ -import java.util.ArrayList; - -public class RuleController { - private static CardParser parser = new CardParser(); - private String currentAllowedColor = "all"; - private String currentAllowedNumber = "all"; - private String currentAllowedSymbol = "all"; - - - /** - * Given a card played by the user, judge whether this play is valid - * that is, all cards must be played following the rule - * @return whether the play is valid - */ - public boolean isValidPlay(Player player, int cardID, boolean updateIfValid) { - - String cardDescription = parser.parseCardID(cardID); - String[] result = parser.parseCardDescription(cardDescription); - String color = result[0]; - String type = result[1]; - String content = result[2]; - boolean valid = false; - - if (checkAttrMatch(currentAllowedColor, color)) - valid = true; - if (checkAttrMatch(currentAllowedNumber, content) || checkAttrMatch(currentAllowedSymbol, content)) - valid = true; - if (content.equals("wildDraw4")) { - valid = checkDraw4IsLegal(player); - } - - if (valid && updateIfValid) { - currentAllowedColor = color.equals("NA") ? "none" : color; // wildcard played - if (type.equals("sym")) { - currentAllowedSymbol = content; - currentAllowedNumber = "none"; - } else if (type.equals("num")) { - currentAllowedNumber = content; - currentAllowedSymbol = "none"; - } - } - return false; - } - - private boolean checkAttrMatch(String legalString, String stringToCheck) { - return legalString.equals("all") || stringToCheck.equals(legalString); - } - - /** - * Check whether a player have currently allowed 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]; - if (color.equals(currentAllowedNumber)) return false; - } - return true; - } - - /** - * Getter and Setter for Allowed number - */ - - public String getAllowedNumber() { - return currentAllowedNumber; - } - - public void getAllowedNumber(String number) { - currentAllowedColor = number; - } - - /** - * Getter and Setter for Allowed Symbol - */ - - public String getCurrentAllowedSymbol() { - return currentAllowedSymbol; - } - - public void setAllowedSymbol(String symbol) { - currentAllowedSymbol = symbol; - } - - - /** - * Getter and Setter for Allowed Color - */ - - public String getAllowedColor() { - return currentAllowedColor; - } - - public void setAllowedColor(String color) { - currentAllowedColor = color; - } - -} - - - - - diff --git a/src/CardManager.java b/src/UNO/CardManager.java similarity index 91% rename from src/CardManager.java rename to src/UNO/CardManager.java index ee016b5..5d14b79 100644 --- a/src/CardManager.java +++ b/src/UNO/CardManager.java @@ -8,6 +8,7 @@ public class CardManager { public CardManager() { parser = new CardParser(); + discardPile = new ArrayList<>(); initializeCardPile(); printCardPile(); } @@ -76,7 +77,11 @@ public class CardManager { discardPile.add(0, cardID); } -} + /** + * Return number of card left on discard pile + */ + public int numLeftDiscardPile() { return discardPile.size(); } +} diff --git a/src/CardParser.java b/src/UNO/CardParser.java similarity index 100% rename from src/CardParser.java rename to src/UNO/CardParser.java diff --git a/src/UNO/CmdUI.java b/src/UNO/CmdUI.java new file mode 100644 index 0000000..9840bb7 --- /dev/null +++ b/src/UNO/CmdUI.java @@ -0,0 +1,185 @@ +import java.util.Scanner; + +public class CmdUI { + Player player; + CardParser parser; + public static Game gameController; + public static RuleController ruler; + + public CmdUI(Player p) { + player = p; + parser = player.parser; + gameController = player.gameController; + ruler = gameController.ruler; + + } + + /** + * FOR CMD LINE DEBUGGING + * When it's this player's turn, the player must pick one card to play + * @return the ** cardID ** of the chosen card + */ + public int promptTakeAction() { + // instruct player to take a move + Scanner inputScanner = new Scanner(System.in); + boolean receivedValidInput = false; + int action = -1; + while (!receivedValidInput) { + promptChooseAction(); + String input = inputScanner.nextLine(); + try { + action = Integer.parseInt(input); + if (action == 1 || action == 2) { + receivedValidInput = true; + } + + } catch (Exception e) { + System.out.println("Please choose action from 1 or 2"); + } + } + + if (action == 1) { + return actionOne(); + } else if (action == 2){ + return actionTwo(); + } + + return -1; // user did not play valid card + } + + private int actionOne() { + + int cardID = -1; + while (true) { + player.printCardsInHand(); + player.printLegalCards(); + System.out.println("Which card would you like to play? Please input the corresponding card number..."); + + int chosenCardIndex = -1; + + while (chosenCardIndex < 0) { + chosenCardIndex = getInputCardIndex(); + } + cardID = player.getCards().get(chosenCardIndex); + if(gameController.ruler.isValidPlay(player, cardID, true)) { + // maintain list-cards and discardPile + player.getCards().remove(chosenCardIndex); + gameController.gameCardManager.insertOneCardToDiscardPile(cardID); + break; + } + } + + if (parser.isWildCard(cardID)) { + // to implement + int colorChosen = -1; + while (colorChosen < 0) { + promptChooseColor(); + colorChosen = getInputColor(); + } + ruler.setAllowedColor(parser.colorDict.get(colorChosen)); + } + return cardID; + } + + private int actionTwo () { + player.drawCards( 1); // draw new card and add it to cards in hand + int chosenCardIndex = player.getCards().size() - 1; + int cardID = player.getCards().get(chosenCardIndex); + if(ruler.isValidPlay(player, cardID, true)) { + player.getCards().remove(chosenCardIndex); + gameController.gameCardManager.insertOneCardToDiscardPile(cardID); + + if (parser.isWildCard(cardID)) { + // to implement + int colorChosen = -1; + while (colorChosen < 0) { + promptChooseColor(); + colorChosen = getInputColor(); + } + gameController.ruler.setAllowedColor(parser.colorDict.get(colorChosen)); + } + + return cardID; + } else { + System.out.println("Sorry, the newly drawn card is not playable :("); + return -1; + } + } + + + /** + * helper function for playCardWithCommandLine + * parse the integer inputted by the player + * @return the ** INDEX ** of card in list cards that user chooses + */ + private int getInputCardIndex() { + Scanner inputScanner = new Scanner(System.in); + String input = inputScanner.nextLine(); + int decision; + try { + decision = Integer.parseInt(input) - 1; // -1 because we want the index in cards list + } catch (Exception e) { + System.out.println("Please input the number corresponding the card you choose!"); + return -1; + } + + if (decision < 0 || decision >= player.getCards().size()) { + System.out.println("The card you chose does not exist!"); + return -1; + } + return decision; + } + + /** + * helper function for playCardWithCommandLine + * parse the integer inputted by the player + * @return the ** INDEX ** of card in list cards that user chooses + */ + private int getInputColor() { + Scanner inputScanner = new Scanner(System.in); + String input = inputScanner.nextLine(); + int decision; + try { + decision = Integer.parseInt(input); + } catch (Exception e) { + System.out.println("Please input the number corresponding the card you choose!"); + return -1; + } + + if (decision != 1 && decision != 2 && decision != 3 && decision != 4) { + System.out.println("Please choose a valid color (represented by number)!"); + return -1; + } + return decision; + } + + /** + * prompt player to take action current round + */ + private void promptChooseAction() { + player.printCardsInHand(); + System.out.println("The following are playable:"); + player.printLegalCards(); + System.out.println("Please choose you action this round:"); + System.out.println("[1] Play a owned card"); + System.out.println("[2] Draw a card and play it if possible"); + System.out.println("Please input 1 or 2 : "); + } + + private void promptChooseColor() { + player.printCardsInHand(); + System.out.println("Please pick a color for the next rounds:"); + System.out.println("[1] Red"); + System.out.println("[2] Green"); + System.out.println("[3] Blue"); + System.out.println("[4] Yellow"); + System.out.println("Please choose one from above: "); + } + + public void printForcedSkip() { + System.out.println("Sorry, you lost this turn and was forcefully skipped."); + } + + + +} diff --git a/src/UNO/GUI.java b/src/UNO/GUI.java new file mode 100644 index 0000000..db4a776 --- /dev/null +++ b/src/UNO/GUI.java @@ -0,0 +1,16 @@ +public class GUI { + Player player; + public GUI(Player player) { + player = player; + } + + + /** + * FOR real playing scenarios with GUI + * When it's this player's turn, the player must pick one card to play + */ + public int playCardWithGUI() { + // not implemented yet. + return 0; + } +} diff --git a/src/UNO/Game.java b/src/UNO/Game.java new file mode 100644 index 0000000..59c4676 --- /dev/null +++ b/src/UNO/Game.java @@ -0,0 +1,82 @@ +import java.util.*; + + +/** + * The class for recording Game state + * Organize the interactions among all other classes + */ + +public class Game { + private static CardParser parser = new CardParser(); + private static final int INIT_DRAW = 7; // every player get 7 cards at beginning + + private int rounds = 1; + public RuleController ruler; + public CardManager gameCardManager; + public ArrayList<Player> players; + private int currentPlayerID; // playerID starts from 0 !!!!! + + /** + * Default constructor for Game object + * @param playerNum + */ + public Game(int playerNum) { + gameCardManager = new CardManager(); + ruler = new RuleController(); + decideFirstPlayerID(playerNum); + + System.out.println("Loading player information..."); + players = new ArrayList<Player>(); + + // playerID starts from 0 !!!!! + for (int i = 0; i < playerNum; i++) { + Player player = new Player(i, this); + player.drawCards(INIT_DRAW); + players.add(player); + } + } + + + /** + * Randomly decide the start position of this game + * @param playerNum total number of players + */ + private void decideFirstPlayerID(int playerNum) { + Random rand = new Random(); + currentPlayerID = rand.nextInt(playerNum); // -1 to convert to index + } + + + /** + * find the next player in the sequence, regardless whether he or not should be skipped + */ + private void updateNextPlayerID() { + if (ruler.getIsClockwise()) { + currentPlayerID = (currentPlayerID + 1) % players.size(); + } else { + currentPlayerID = (currentPlayerID - 1 + players.size()) % players.size(); + } + + } + + /** + * Run one round of UNO + * very import function ! + */ + private void runOneRound() { + ruler.reportCurrentState(this); + System.out.println("It's now Player " + (currentPlayerID + 1) + "'s turn..."); + Player currentPlayer = players.get(currentPlayerID); + currentPlayer.playOneRound(); + + } + + public void gameStart() { + while (rounds <= 2) { + System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n<<<<<<<<<<<<<<<<<<<<<<<< Round" + rounds + " >>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); + runOneRound(); + updateNextPlayerID(); + rounds++; + } + } +} diff --git a/src/UNO/Main.java b/src/UNO/Main.java new file mode 100644 index 0000000..932aca1 --- /dev/null +++ b/src/UNO/Main.java @@ -0,0 +1,15 @@ +public class Main { + public static void main(String[] args) { +// CardParser parser = new CardParser(); +// String desc = parser.parseCardID(60); +// System.out.println(parser.parseCardDescription(desc)[0]); + System.out.println("--------------------------------------------------- Game Start ---------------------------------------------------"); + Game uno = new Game(6); + uno.gameStart(); + + + } + + + +} \ No newline at end of file diff --git a/src/UNO/Player.java b/src/UNO/Player.java new file mode 100644 index 0000000..a8756a2 --- /dev/null +++ b/src/UNO/Player.java @@ -0,0 +1,142 @@ +import java.lang.reflect.Array; +import java.util.*; + +public class Player { + public static CardParser parser; + private final ArrayList<Integer> cards; + public int playerID; + public static Game gameController; + public static RuleController ruler; + public CmdUI prompterCmd; + public GUI prompterGUI; + + + public Player(int ID, Game game) { + playerID = ID; + cards = new ArrayList<Integer>(); + gameController = game; + ruler = game.ruler; + parser = RuleController.parser; + prompterCmd = new CmdUI(this); + prompterGUI = null; + } + + /** + * @param numToDraw number of cards to draw + */ + public void drawCards(int numToDraw) { + ArrayList<Integer> newCards = gameController.gameCardManager.drawCards(numToDraw); // Initial draw + cards.addAll(newCards); + } + + /** + * print all cards that this user has + */ + public void printCardsInHand() { + if (!cards.isEmpty()) { + System.out.println("\n\n==================================================================="); + System.out.println("Currently have " + cards.size() + " cards:"); + for (int i = 0; i < cards.size(); i++) { + System.out.println("[" + (i + 1) +"] " + parser.parseCardID(cards.get(i))); + } + System.out.println("===================================================================\n\n"); + + } else { + System.out.println("============================================================"); + System.out.println("You got not cards in hands! Congrats, you are the winner!"); + } + } + + /** + * iterate through cards and see if any of the player's cards are playable + * @return an array list of legal cards + */ + public ArrayList<Integer> findLegalCard() { + ArrayList<Integer> legalCards = new ArrayList<>(); + for (int cardID : cards) { + if (ruler.isValidPlay(this, cardID, false)) legalCards.add(cardID); + } + return legalCards; + } + + /** + * iterate through cards and see if any of the player's cards are playable + * @return an array list of the **indices** of legal cards from all cards + */ + public ArrayList<Integer> findLegalCardIndex() { + ArrayList<Integer> legalCardIndices = new ArrayList<>(); + for (int i = 0; i < cards.size(); i++) { + if (ruler.isValidPlay(this, cards.get(i), false)) legalCardIndices.add(i); + } + return legalCardIndices; + } + + + /** + * print all cards that this user has + */ + public void printLegalCards() { + ArrayList<Integer> legals = findLegalCard(); + if (!legals.isEmpty()) { + System.out.println("\n\n==================================================================="); + System.out.println("The following cards are playable in current turn:"); + for (int i = 0; i < legals.size(); i++) { + System.out.println("[" + (i + 1) +"] " + parser.parseCardID(legals.get(i))); + } + System.out.println("===================================================================\n\n"); + + } else { + System.out.println("\n\n============================================================"); + System.out.println("You don't have any playable cards now."); + System.out.println("============================================================\n\n"); + } + } + + + + /** + * getter for cards (private attribute for tracking all cards owned by a player) + * @return the cards of the player + */ + public ArrayList<Integer> getCards() { + return cards; + } + + + /** + * Caller for player to play one round + * skip, draw, play ... all behavior will be handled by this function + */ + public void playOneRound() { + if (prompterGUI != null) { + playOneRoundGUI(); + } else if (prompterCmd != null) { + playOneRoundCmd(); + } + } + + /** + * Playing with cmd as UI + */ + public void playOneRoundCmd() { + if (ruler.checkSkipandDraw(this)) { + prompterCmd.printForcedSkip(); + } else { + prompterCmd.promptTakeAction(); + } + + } + + /** + * TO BE IMPLEMENTED... + */ + public void playOneRoundGUI() { +// if (ruler.shoudPlayerBeSkipped(this)) { +// prompterGUI +// } else {} + + } + + + +} \ No newline at end of file diff --git a/src/UNO/RuleController.java b/src/UNO/RuleController.java new file mode 100644 index 0000000..06d923b --- /dev/null +++ b/src/UNO/RuleController.java @@ -0,0 +1,257 @@ +import java.util.ArrayList; + +public class RuleController { + public static CardParser parser = new CardParser(); + + /** 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 int nextPlayerSkipLevel = 0; + private int cumulativePenaltyDraw = 0; + private boolean isClockWise = true; // if clockwise, next player will be the element in player list + + + /** + * judge whether a pending player should be skipped + * @param player the pending player + * @return bool + */ + public boolean checkSkipandDraw(Player player) { + if (nextPlayerSkipLevel == 3) { + assert cumulativePenaltyDraw == 0; + nextPlayerSkipLevel = 0; // the next player should no longer be skipped + return true; + + } else if (nextPlayerSkipLevel != 0) { + // player will be skipped and forced to draw cards + // unless they have draw2 / wildDraw4 cards + assert cumulativePenaltyDraw != 0; + boolean toSkip = player.findLegalCard().isEmpty(); + if (toSkip) { + nextPlayerSkipLevel = 0; + player.drawCards(cumulativePenaltyDraw); + resetPenaltyDraw(); + } + return toSkip; + } else { + return false; + } + } + + + + /** + * Given a card played by the user, judge whether this play is valid + * that is, all cards must be played following the rule + * @return whether the play is valid + */ + public boolean isValidPlay(Player player, int cardID, boolean updateIfValid) { + + String cardDescription = parser.parseCardID(cardID); + String[] result = parser.parseCardDescription(cardDescription); + String color = result[0]; + String type = result[1]; + String content = result[2]; + + // pending skip + if (nextPlayerSkipLevel == 4) { + 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"); + } + + boolean valid = false; + // if not skipped, first consider wild + 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; + + if (valid && updateIfValid) { + updateRule(color, type, content); + } + + return valid; + } + + private void updateRule(String color, String type, String content) { + setAllowedColor(color); // wildcard "NA" - this will be updated later by player declaring the color + + if (type.equals("sym")) { + if (content.equals("skip")) { + setNextPlayerSkiplevel(3); + // the states after the skip.. (supposed skipping is done) + currentMatchableSymbol = content; //?? + currentMatchableNumber = "all"; //?? + + } else if (content.equals("draw2")) { + // next round match by either COL or SYM + setNextPlayerSkiplevel(1); + increasePenaltyDraw(2); + currentMatchableSymbol = content; + currentMatchableNumber = "none"; + + } else if (content.equals("wildDraw4")) { + // next round match only by COL + setNextPlayerSkiplevel(2); + increasePenaltyDraw(4); + currentMatchableSymbol = "none"; + currentMatchableNumber = "none"; // color will be declared by player later + + } else if (content.equals("reverse")) { + // next round match by either COL or SYM + changeGameOrder(); + setNextPlayerSkiplevel(0); + currentMatchableSymbol = content; + currentMatchableNumber = "none"; + + } else if (content.equals("wild")) { + // next round can only match by COL + currentMatchableSymbol = "none"; + currentMatchableNumber = "none"; + } + + } else if (type.equals("num")) { + // next round match by either COL or NUM + setNextPlayerSkiplevel(0); + currentMatchableNumber = content; + currentMatchableSymbol = "none"; + } + } + + private boolean checkAttrMatch(String legalString, String stringToCheck) { + return legalString.equals("all") || stringToCheck.equals(legalString); + } + + + /** + * 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; + } + return true; + } + + /** + * Getter and Setter for Allowed number + */ + + public String getMatchableNumber() { + return currentMatchableNumber; + } + + public void getAllowedNumber(String number) { + currentMatchableColor = number; + } + + /** + * Getter and Setter for Allowed Symbol + */ + + public String getCurrentMatchableSymbol() { + return currentMatchableSymbol; + } + + public void setAllowedSymbol(String symbol) { + currentMatchableSymbol = symbol; + } + + + /** + * Getter and Setter for Allowed Color + */ + + public String getMatchableColor() { + return currentMatchableColor; + } + + public void setAllowedColor(String color) { + currentMatchableColor = color; + } + + /** + * Getter and setter for nextPlayerIsSkipped + * level 0: next player won't be skipped + * level 1: next player can play a either a draw2 card or a wildDraw4 card to avoid being skipped + * level 2: next player can only play a wildDraw4 card of any color to avoid being skipped + * level 3: next player will be skipped anyway. + */ + + public int getNextPlayerSkiplevel() { return nextPlayerSkipLevel; } + + public void setNextPlayerSkiplevel(int level) { nextPlayerSkipLevel = level; } + + private String descSkipLevel() { + if (nextPlayerSkipLevel == 0) { + return("level 0: player won't be skipped"); + } else if (nextPlayerSkipLevel == 1) { + return("level 1: player can play a either a draw2 card or a wildDraw4 card to avoid being skipped"); + } else if (nextPlayerSkipLevel == 2) { + return("level 2: next player can only play a wildDraw4 card of any color to avoid being skipped"); + } else { + return("level 3: next player will be skipped anyway."); + } + } + + /** + * Getter and setter for cumulativePenaltyDraw + * @return + */ + + public int getPenaltyDraw() { return cumulativePenaltyDraw; } + + public void resetPenaltyDraw() { cumulativePenaltyDraw = 0; } + + public void increasePenaltyDraw(int num) { cumulativePenaltyDraw += num; } + + /** + * Getter and setter for isClockwise + * @return + */ + + public boolean getIsClockwise() { return isClockWise; } + + public void changeGameOrder() { isClockWise = !isClockWise; } + + + public void reportCurrentState(Game gameController) { + System.out.println("============================= Game State Report ========================================"); + System.out.println("Current matchable color : " + getMatchableColor()); + System.out.println("Current matchable number : " + getMatchableNumber()); + System.out.println("Current matchable symbol : " + getCurrentMatchableSymbol()); + System.out.println("Game order : " + (getIsClockwise() ? "clockwise" : "counterclockwise")); + System.out.println("Player skip level is " + descSkipLevel()); + System.out.println("Player will be forced to draw " + cumulativePenaltyDraw + " cards"); + 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