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^!^Vd&#1MH?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
zcmbtX=YJH}6+KUFSEEruAexGo1cX>A$l$~TgeVrp8?OMf0wM_DVRw)Qt!CD<vw-Y4
zaT3y;UYr=GlOm_v0xdR99H)`QX-@r^KZIWhId^8Z$dG&i{h0UW&3(6=d+vR2U;EFs
zR{#v*?;2`Q8$q3pdNe4soiWZDgIU9#7~FsAjG6Wn8n#-t<!w`_?OS)a5m7Wopy_CW
z&Tj{@#*FDIM05Tmu}eWEB4|-q>}x7`R(5cw>l!mjEAMG&My;q=q@x{+73$N5o5?G5
zB<~<SB$6FEmSUMg%Y-p)jySgGI@zpPY)J0q3T0McWdxl%y3nmqCyUhU7JQ+$<Uvj<
z+kBNP8xg~*2;QXQ%~(y<3uUM}XSjK>p(jV^-vR&4-^yKUseNQRb10#q7wZJJxI$B3
zGC*P|fM`I+Td<z%IoFxad8W%93X!D0(bsgZjt$sYC9(HVf|`>Y{FvUV<88QKq1BI@
zUW^*HF(FPh`%Z<gLmJ+W%@J(Tnar(JCk~fI8#AtPPF4u<^1j5nJEAN}*`{MVb}(`y
zli8WgDy-<Mk{uDq)1KwnL+g%;_yamdz*I-9{BDLf<8$L^Blci#1P|&+;2jI7l$yzV
z<}{_80tpo++j0gExR&juJl8a)hoVR-?AEm5yZ@(QANEIZK*z&4SYqNrbM!qY#<Mp4
z31jtHPj4)Hf@zdE$8;RRVX`W3Jw{fs021vin|JCM$5Dl4)5esLD{Xj3EN_ytyl2>+
z@VN|jwNg>}E*-~lg1RP5fnuRtP;x^NJfg6uQi%!MGnsk~Cvi$gT0Dx<_rpfEU}`XN
zI)Vuulj4$AA*^sqm@6xZUF}dfBYsaQtnEt#*{yaiBuDj96wKM~yU)k4rbXc>Y`q&*
zQ9P=!dE6<)CLAwj^M6{19kcA%q+w_Bt761|!Zp17Kx~FmhHJ*WNi%lNvTf5{CD`Y6
zcqj;XtVqLiSWHX%s*55Kt`9Zg9L`5DqvJ8*d3&Whl|)FONh80{JnxC@yLCK)_mC(y
z7ZjG1wEAd<S=HEep49O^yq}q|^30x<k*2|lE_aW_Q7N#KxS->M_z-QJl^pLsEsmDT
z*Vh?Rg5}?gkLdU)o+71Kyl-H0Xj+s;@o^oWz$a<$v}I?K=7f<IYLLbyZx=ReR^+D@
zHjEL&(`*0^ft(027i^{B8>h0SBp_XIUDNhrUct4uMDbaLZFg75QG8yZSCXA^?6n><
zeAbK^_DscUkbK)Yw?2w5(B9opOVb3NXLMYYBd}E>+i#l(or0ZVJC<)>((&cnzOk80
zPQR+-Yxp|*U3$_?Po<`;9O<}=jhAUICss1hi%UAb8K{xov&V7MW=1y1w{PqCj#PGA
zaAb_Jwe0kJu0mtVny?Lm%N`W3>dWPGb!$~Qmzc3_h~0pN?w^wDq=}6<87gQ^TDG~b
zFn!8&$0UDbchX54*~5lw$$Pk1=S^B{WYN;Orcfh?dz~Cd9LPqhY_tp0V@?oj)HX{;
z&C-PmXL2Q_jE!*%>+%WvLBhn_f<;26JR?0dYUD!O4U$~3re#Ykr7Ht>rs@BRy?p`8
z6L!WtPjJf$xnQMDs%`asDwhLS8hjxMo;})kmN$WFQqZxKQ(*G;Sb|@ZRI%x<mnK0I
z4>*pO_go`4YI>7SCg0kCUu(FI-$d|RX~4fzSY7GumVMTlG6#cWCpb&?7-{w<_JwDv
z52jEsP%7AE&HU=5<4hHDLsjVy&#$VL1slhhj5~-QtCBDEjH;zj#fXv3rr0~#8Gg^U
zF%ndLb|xrK6*LFd{~y`7j;Z6ZSWFSQg!JE$tdY-~`3PQDSaVzScM2+kzbf?ne^I#w
z`UqeZi?oJEa|DfYspG6&ZkRmuW;w6HbDZ(U%6X&QC;gEZMvh8uYW~Rk7)OmO_4qEI
z-{afUs6#EsP4TNx@y>Zf;xD6l{3=@K(Kc`yO9rlB`DOIX;hxJ_!*9Lgl<b>Fe_YLD
z@C9zI!T0&>rD33j>RLH#!xAjQa=LgAom|7W4d}rAbnOR}iUlU|L;Q$uG>#wBb>+{V
zr}H(O58;K-#c95aiyd=Vas~Hw7O`nGeudr@F?>WEsP!Fa@rAmGLO0FzR2k|h8|uKE
zZ>WhVT&80+xWfHnI#_wmH$9Jr(Dc8El%QS^dqwPg7RTqXyZxaeMmYwHscSd_aHV!@
zXSi|+{rucn_sAR}<4(GK>{XmB!YCqh4VEu{L8;kWuZy}YH_u|ROzl8(dyZozv^d=b
zldciTb|SqRYl&wcQXIz-M}{fRGRYq9^}}9Dr+aZ9oeEGbgaBNnmL}Bw8@=iVHfpVm
zk_RS*g$eUaT^+|AVg8drFz)EUOE{}|bo6oZxIz%fwmI~~yK9Sh??veS-7n$;MSS?k
z?5%(FKTjQXenyrOJxOkqSNL9RW=gkU8=oZ#^pX-U(nU$`j?hJseaYu_DKo)}@LSw(
zMeR+rMbI3<x%dsb9?<_9KfhcKWsVMr((R>CYKOb3Q_~Zdx2|$lN?~+`VO*$@)Z7-y
z2qW1=pLa8+T^PpRawJ*^ws2*8Ig(BI$r~b(l~N@9rFat>BT)l42vjAGpO)!&i|Z1H
z6EEUp$$p=JLc9_I+dn0=8}8zl)Ft%sOP9~N{z_=ogp;WLSs`4fOg|G6?sMVzbV$4)
zgBzJ0U_aeBz}dsBtAqR*nqoG`h(Zbv;V}QkaRNti8pmMs?qAAo4@oHm6il2DlX{%N
zD+@3QR!W$#ecVKkU~&Tk+A=2fXXT_0@=aPqz2r_v7W5q{RnWMY4cJ~E8ml1sY8lZJ
zp^}wUGI$*tf&JnvTKLv~ovp8kXDd|~(AQzh&9SdN%EY_;E$&rWS{YgrV%DLiMOrJb
zQG7~49jAxlTep--5ns88X0cPmH)hck%)V9CzuNukdyGZ?IB|Z0I6qlss(YcSB@wFT
zZ7wv`PcvdlRr+y&%TrY<RH&jBKc{F7et}<dY~k!z-29sV`~&{PHHqWT_zV7q75@bw
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