From 1f29b1660d9b071ddf5146a9a49960c38eaecb33 Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Sun, 19 Jun 2022 22:51:57 +0430 Subject: [PATCH 01/39] Initial Python file for Life for 2 on new branch. --- 56_Life_for_Two/python/lifefortwo.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 56_Life_for_Two/python/lifefortwo.py diff --git a/56_Life_for_Two/python/lifefortwo.py b/56_Life_for_Two/python/lifefortwo.py new file mode 100644 index 00000000..e69de29b From 53457bfb9f4e086c7326877d0e1ff963e1975359 Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Sun, 19 Jun 2022 22:53:40 +0430 Subject: [PATCH 02/39] Initial Python file for Life for 2 on new branch. --- 56_Life_for_Two/python/lifefortwo.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/56_Life_for_Two/python/lifefortwo.py b/56_Life_for_Two/python/lifefortwo.py index e69de29b..600d0a33 100644 --- a/56_Life_for_Two/python/lifefortwo.py +++ b/56_Life_for_Two/python/lifefortwo.py @@ -0,0 +1,5 @@ +// LIFE FOR TWO +// +// Converted from BASIC to Python by Sajid Al Sanai. +// + From d4a020728b9bab954258f6442a4a703be3a482a8 Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Sun, 19 Jun 2022 23:23:26 +0430 Subject: [PATCH 03/39] Initial Python file for Life for 2 on new branch. --- 56_Life_for_Two/python/lifefortwo.py | 57 ++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/56_Life_for_Two/python/lifefortwo.py b/56_Life_for_Two/python/lifefortwo.py index 600d0a33..9328d803 100644 --- a/56_Life_for_Two/python/lifefortwo.py +++ b/56_Life_for_Two/python/lifefortwo.py @@ -1,5 +1,54 @@ -// LIFE FOR TWO -// -// Converted from BASIC to Python by Sajid Al Sanai. -// +""" +Life for Two +From: BASIC Computer Games (1978), + Edited by David H. Ahl. + +BASIC program written by Brian Wyvill of Bradford University in Yorkshire, England. + +Python port created by Sajid Al Sanai, 2022. +""" + +def tab(spaces): + out = "" + for i in range(spaces): + out += " " + return out + +na = [] +ka = [, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] +aa = [, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] +xa = [] +ya = [] +j, k, m2, m3 = 0, 0, 0, 0 + +def main(): + print(tab(33) + "LIFE2\n") + print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n") + print("\n\n\n") + print(tab(10) + "U.B. LIFE GAME\n") + m2 = 0 + m3 = 0 + for j in range(7): + na[j] = [] + for k in range(7): + na[j].append(0) + for b in range(1, 3): + p1 = 30 if (b == 2) else 3 + print("\n") + print("PLAYER {} - 3 LIVE PIECES.\n".format(b)) + for k1 in range(1, 4): + while 1: + print("X,Y\n") + str_ = input() + ya[b] = int(str_) + xa[b] = #int(str_.substr() + 1) + if xa[b] > 0 and xa[b] < 6 and ya[b] > 0 and ya[b] < 5 and na[xa[b]][ya[b]] == 0: + break + print("ILLEGAL COORDS. RETYPE\n") + if b != 1: + if xa[1] == xa[2] and ya[1] == ya[2]: + print("SAME COORD. SET TO 0\n") + na[xa[b] + 1][ya[b] + 1] = 0 + b = 99 + na[xa[b]][ya[b]] = p1 From 77d5a8dde6ecb8c96f6c5d4ca8c52a9cd5eb1e96 Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Sun, 19 Jun 2022 23:33:30 +0430 Subject: [PATCH 04/39] Initial Python file for Life for 2 on new branch. --- 56_Life_for_Two/python/lifefortwo.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/56_Life_for_Two/python/lifefortwo.py b/56_Life_for_Two/python/lifefortwo.py index 9328d803..69bb548f 100644 --- a/56_Life_for_Two/python/lifefortwo.py +++ b/56_Life_for_Two/python/lifefortwo.py @@ -52,3 +52,6 @@ def main(): na[xa[b] + 1][ya[b] + 1] = 0 b = 99 na[xa[b]][ya[b]] = p1 + +if __name__ == "__main__": + main() From 08888ef90f79df2ecfa19d52a8821d95d251db52 Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Mon, 27 Jun 2022 21:03:34 +0430 Subject: [PATCH 05/39] First draft of Python port source code. --- 55_Life/.life.bas.swp | Bin 0 -> 12288 bytes 55_Life/python/.life.py.swp | Bin 0 -> 16384 bytes 56_Life_for_Two/.lifefortwo.bas.swp | Bin 0 -> 12288 bytes 56_Life_for_Two/python/LIFE2.py | 136 ++++++++++++++++++ 56_Life_for_Two/python/lifefortwo.py | 197 +++++++++++++++++++-------- 5 files changed, 276 insertions(+), 57 deletions(-) create mode 100644 55_Life/.life.bas.swp create mode 100644 55_Life/python/.life.py.swp create mode 100644 56_Life_for_Two/.lifefortwo.bas.swp create mode 100644 56_Life_for_Two/python/LIFE2.py diff --git a/55_Life/.life.bas.swp b/55_Life/.life.bas.swp new file mode 100644 index 0000000000000000000000000000000000000000..e905a787d5fa2194d6184b5cafad82fb02210a1c GIT binary patch literal 12288 zcmeI2O>7%Q6vtnSgi2`x0*Q|k(`^r4V#hnPUdMK_M$UTUZnRlju9NP906C38X;U>M z;o}51xWSEkB?K3wN=RHlNJw0exO1dJLPCfG7cSiR&&MWdrCxfgG?xBe&&Qj2@Auxb z6vbQKX0py&3xe=^n&|BG&er>1o}s@ZqJ!!6o$Z6^{*BqbTz%l{z3J|3e`of<^>X3E z69?A&vx6IlxAy8=(}SIBwQIL-?!9|B+poPny*WFm2f>@^&RetkF5VWfqddVrEdfj5 z;R&24UvN*_Uvw_8XP?=4_@k_)C143y0+xU!U^1HA!_pcRNi&qKeTC;Aoo1^O1+g;Hn* zdI>rQoreB7NAxpv8~Ox#2YL;Pp*r*;GzUEf-F=eiN9YUaW9T}RLVc(PJqOJ}|D7fJ z1Ns5_2Koy66xxPfh1Q`3=pyt2^ecr4EP z)NFWcFq{mT{P|bY4_MB_oY#1#;9()3xd?MHkFf{~Jh8`PS)5N;PEBDx7S!Y(OIBGF z`fPGJ&RDOKR|_}vJEL$UjXZM;OekmvOiu@GZME#P;h06;#y!TOqdkK$1ueDH9P8N`Uy}bgtORX~~RyuZ>7OJQt-qh3Gb0`hL)CwmL~WtjS%0 zTIIl?-~qjVwC2mTTy%x;9QhF9XqBtgBTFQ&v=r^O%BA0db(l9gOlA}#naBnSB*AzL zPo>8KTSns~n{>+j3Z%!RT9lXz5{N+t(=AN8ibg1Bn`(BsD1-3TY(qKN&CTAt5$4z{ z)a-I@_U68t<@$a$>8(@>cgcC#S;F2EiC^x*Q(0bcheV)mEGtbfm=W*jnr?DzQv}U| zfmqg&*``iAPOMHV2~>vyLc)}UOs`HZ2~qOXGqP3g$A_93gag!p;OHwq1mVID7rhQB zU^lo)8`KAS&xGy_;w&EbCdn}CI7@@7Ga8OI(sDdn>PT=&TL-J0V@{H7_R^$(LDE7U z>KvYUCywSZdF01=_aOR~|%L~lkW;2kG~*~ic5dlk{BE_!YiCy9njsx@T^0Ep^O z*?eeB6k@BaggBeT_@WtZjM=C+!DmziHOm^)`PCz87#rC*JV56};}|uw8MA1(4xf^2 kz}Wh5JWj4mhF7yH&|hV1@%TzyI3!LO`wbYU$!hG-|9k7G5C8xG literal 0 HcmV?d00001 diff --git a/55_Life/python/.life.py.swp b/55_Life/python/.life.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..9f5dd3c294f95c5c6117d7c4b7be74b18adbda1a GIT binary patch literal 16384 zcmeI3UyK_^9ml6h)24+ML_kFX#KZ^G&Ry`m=m zcXyq$6)q)hRSAg~Dg+X=4S%E-!9!K?P@qx;FMUC3U*NGq4JiD1q2hr*rAT~#GqXEu z=MJhqftam6+1;7n{AT96znQt6b=N1)7nb?a@o9$RgN)tjys-Z0b9>p7_cInc7u|a3 z1P_aVa(6r~IV};mV#oYA<4Vfm#G(ivj{MHVx)Zv!gEhb1=|&NEUvePv>S? zT!5^5gVsG`-P6{Id56#O$>eT?w_H!~naN|&Bz3qRe$C?6VOtKmVjxSkVU8a;nk2g$ zx@E_aYFbAA{+%P)uQ@(5;72Cj&u8Af8)(u)L#L+){K(YfNPYK?P&GNasXaX|+mpDD z74Sqas>&OarTe6^=*DE}b|$5ICQH|xl|~szxbd zmghfLJ)JL{I$chMjDG6V#}04jHj^2@=(}E)BBR=J!zedYJJp!VR_9W6y_F6LX-%I)L?PRZY#E3EWl(tO=lHOJNYv@AeKxR;jxbZdLi(GGL z3{a-P&#|~u>8+82{d0V3Fwo-iu>}lRoED!4T+AWzws)~(6UdM8Z$@?OKh;2Z9~ueU z%`#?&nM#EVxl81NR+S9TtnmXfwk{MF%cogfA)U92&Efe;)kAX=)$<>Vr$bvlPNP$U zkEWGXvs>bDAWDrsNiq%h;be+OB-6l=ouj#Q$e|81Gq$8nVx$z<$ehX-^Q-ga!b)+L zUv6xDAu6qu&Mn0Woh^PDvtu=kg00L@fa-LL%S_@{v_fGz&T*v73dQsDONGV##vBh{ zPrjteC5D1pt46sTQ${wjMSD6L9IBnUs@pYWYqADYquG zQe(jcP;O1t6)!DGp(Oe!hr-pAF?hDrKYeQbw{{ z)ZIY`YH}Y)Q_qDa1S||xLash?g7CU+5Xq@0 zuZM;%h`fe~s`@To7iIjSv{M&BHnUVXna7B#3;MGJOF@nwJkE>0htXr^n%ZDAYloE@ zEe6yB*)!@L9kNRpjQDR<-c+V$*O<)0KZtBHs7#_PjK&euN!|z#Bd70r4Jb06O6_`{ zsEH6iEAC7EO7bVZV|*PUN_sZ2?)rgSb6VV~)w+RG!-DBX_l7ASvQ?Wd9<#&ie#8;b zbvJa@G0Z96G2kN+cAT0(8v?h}K`X|28J@YDcB87+!=vttkb8bah5{{Vwfs$Ly+aov z@B3Y<27L-5?xfoC!2H?5g7&fLcUyH;C-vi{L%B-5OnD$ew#;q z3R3R2J3iuzL}o05C9s5BQRnM@zUW}CUJ?uVp?oCp&g_wKOSGY<6S=-e0r#Na^!S4B zZ94sXL*DT_-If#ZnrOA;h0~4vwiEdtV>DC93h4d+7Q9dQ0lojn-}i6e{hi+Xp9IU` zGhh#(_xM-9HQ)hyhd&BF0X`1y0QBzuEATS-4)`{>2A%*^PY>9`Dqt0`3RnfK0#*U5 zfK|XMU=^?m{NE@*Z?tNYhT(m`TJ`WhK3A*qoxh52E7;kp(sqh`^HsL=1x)Tr$uD7M zk1^gLQ)lcfn=*QTOl?l4w{zoNF?CMo=uN;QGee(9s10=Nuo-&u9<4G@@6(&_RB@jC z4v?++T`!_fO*xJYAboqBAJRK#v2psmLn~qv^KHO<(~9%x48>KY+kbmNcH#kBC1$5K z?IXTcjs`a48f*O_ QH2w%0Tg7MHdF%rH3;FJ)4gdfE literal 0 HcmV?d00001 diff --git a/56_Life_for_Two/.lifefortwo.bas.swp b/56_Life_for_Two/.lifefortwo.bas.swp new file mode 100644 index 0000000000000000000000000000000000000000..a40819f1e2893bdd7fbb962d8605cf8bcd162b7d GIT binary patch literal 12288 zcmeI2zi%8x6vtnXfDjTuq(Gt?Hc@no&*zz0@7@pRg6@19`+n}}ZXNpyWL=UAI6rW( z4XFrC3M3>dLKi6w2th#+{sBZoh0@SaQBcrQK!?J2e%vpM6e%NS<i`vyLk7jqjYbLXn%Nh=koq=@7icjy?yNU;qdxsZ)fz__v070 zX96zOM*G(ec5g0S9PaO2TD-J-_F&f&wYH@;K$a!A`!q@g&a9)+yi=a0)mDoB~b(r+`zyDc}@% z$`v@cd4xX39GdXea7@FTbnJ_7H7w?PZM z1(tyi9vvfk2p)hhz^C9gxC+*R4~~IhFd-YDryn3q@uT@%XHA#B4 zevb9xbkL2x5?f2sgylJ>{IX!3%vPrAFNo|wH-4FyShZX%mX!TQuLGk=#D1k6n{YYC z`fv2c*3{=lx(u1Ismt4K6mW8nzk0*2plb6oQ zKYNZF6U>hCg4-FW2VOAItNz(?I5S$+pZJInX3?yV&2ipG$uRNZ1^5W7->5QG7GXY|GoQ8d>U}i|+pKpw@GR+CDrl$WLrxV|>s2=AOaikCVL=TdRoZP? zwrg80BTF3)!=Qi!5NR`h}Qv>+x#b&v_Jz;^AcxWdzjQ zK$_+2q6gWDyvd+}ThxSF>n3hPB-+R}u}$$HOkyT4Xoj7k7QHd);Gq_{q_v@NQmkpE zni1Sz@iubR9CAD#vo-8(j{+3YcmP{0%wvpsC=k0pgD9NdD&2HCs8bXwmY^LhKsckm)z(JPVa@OHZe#LzhJ^n#mwl3Z(H1Sz(R`YmY%-5!lep`OtdXHV=iK znuPGwTemSA8xP~yTv-@}nrd?=EFx%N3fDZ_`k^9cFws?Fii;D9&x(TmZ8br8A^nM- zX3l2QLvU;h9lSZ+6?QPaI3X6r9y?0V str: + t = "" + while len(t) < number: + t += " " + return t + +def display_header() -> None: + print("{}LIFE2\n".format(tab(33))) + print("{}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n\n".format(tab(15))) + print("{}U.B. LIFE GAME".format(tab(10))) + +# Board Functions +def setup_board() -> None: + # Players add symbols to initially setup the board + for b in range(1, 3): + p1 = 30 if b == 2 else 3 + print("\n\nPLAYER {} - 3 LIVE PIECES.".format(b)) + for k1 in range(1, 3): + query_player(b) + gn[gx[b]][gy[b]] = p1 + +def modify_board() -> None: + # Players take turns to add symbols and modify the board + for b in range(1, 3): + print("\n\nPLAYER {} ".format(b)) + query_player(b) + if b == 99: + break + if b <= 2: + gn[gx[1]][gy[1]] = 100 + gn[gx[2]][gy[2]] = 1000 + +def simulate_board() -> None: + # Simulate the board for one step + for j in range(1, 6): + for k in range(1, 6): + if gn[j][k] > 99: + b = 1 if gn[j][k] <= 999 else 10 + for o1 in range(1, 16, 2): + gn[j + ga[o1]][k + ga[o1 + 1]] = gn[j + ga[o1]][k + ga[o1 + 1]] + b + +def display_board() -> None: + # Draws the board with all symbols + m2, m3 = 0, 0 + for j in range(7): + print("\n") + for k in range(7): + if j == 0 or j == 6: + if k != 6: + print(" " + str(k) + " ") + else: + print(" 0 ") + if k == 0 or k == 6: + if j != 6: + print(" " + str(j) + " ") + else: + print(" 0\n") + else: + if gn[j][k] < 3: + gn[j][k] = 0 + print(" ") + else: + for o1 in range(19): + if gn[j][k] == gk[o1]: + if o1 > 9: + gn[j][k] = 1000 + m3 += 1 + print(" # ") + else: + gn[j, k] = 100 + m2 += 1 + print(" * ") + gn[j][k] = 0 + print(" ") + +# Player Functions +def query_player(b) -> None: + # Query player for symbol placement coordinates + while True: + print("X,Y\nXXXXXX\n$$$$$$\n&&&&&&\n") + x_ = input("") + y_ = input(" ") + x_ = [int(num) for num in x_.split() if num.isdigit()][0] + y_ = [int(num) for num in y_.split() if num.isdigit()][0] + gx[b], gy[b] = x_, y_ + if gx[b] in range(1, 6) and gy[b] in range(1, 6) and gn[gx[b]][gy[b]] != 0: + break + print("ILLEGAL COORDS. RETYPE\n") + if b != 1: + if gx[1] == gx[2] and gy[1] == gy[2]: + print("SAME COORD. SET TO 0") + gn[gx[b] + 1][gy[b] + 1] = 0 + b = 99 + +# Game Functions +def check_winner(m2, m3) -> None: + # Check if the game has been won + if m2 == 0 and m3 == 0: + print("\nA DRAW\n") + return + if m3 == 0: + print("\nPLAYER 1 IS THE WINNER\n") + return + if m2 == 0: + print("\nPLAYER 2 IS THE WINNER\n") + return + +# Program Flow +def main() -> None: + display_header() + + setup_board() + display_board() + + while True: + print("\n") + simulate_board() + display_board() + check_winner() + modify_board() + +if __name__ == "__main__": + main() diff --git a/56_Life_for_Two/python/lifefortwo.py b/56_Life_for_Two/python/lifefortwo.py index 69bb548f..f2c5f824 100644 --- a/56_Life_for_Two/python/lifefortwo.py +++ b/56_Life_for_Two/python/lifefortwo.py @@ -1,57 +1,140 @@ -""" -Life for Two - -From: BASIC Computer Games (1978), - Edited by David H. Ahl. - -BASIC program written by Brian Wyvill of Bradford University in Yorkshire, England. - -Python port created by Sajid Al Sanai, 2022. -""" - -def tab(spaces): - out = "" - for i in range(spaces): - out += " " - return out - -na = [] -ka = [, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] -aa = [, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] -xa = [] -ya = [] -j, k, m2, m3 = 0, 0, 0, 0 - -def main(): - print(tab(33) + "LIFE2\n") - print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n") - print("\n\n\n") - print(tab(10) + "U.B. LIFE GAME\n") - m2 = 0 - m3 = 0 - for j in range(7): - na[j] = [] - for k in range(7): - na[j].append(0) - for b in range(1, 3): - p1 = 30 if (b == 2) else 3 - print("\n") - print("PLAYER {} - 3 LIVE PIECES.\n".format(b)) - for k1 in range(1, 4): - while 1: - print("X,Y\n") - str_ = input() - ya[b] = int(str_) - xa[b] = #int(str_.substr() + 1) - if xa[b] > 0 and xa[b] < 6 and ya[b] > 0 and ya[b] < 5 and na[xa[b]][ya[b]] == 0: - break - print("ILLEGAL COORDS. RETYPE\n") - if b != 1: - if xa[1] == xa[2] and ya[1] == ya[2]: - print("SAME COORD. SET TO 0\n") - na[xa[b] + 1][ya[b] + 1] = 0 - b = 99 - na[xa[b]][ya[b]] = p1 - -if __name__ == "__main__": - main() +# Variable Initialisation +gn, gk, ga, gx, gy = [], [], [], [], [] +gk = [3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] +ga = [-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] +m2, m3 = 0, 0 + +# Initialise the board +for j in range(6): + gn.append([]) + for k in range(6): + gn[j].append(0) + +for i in range(3): + gx.append(0) + gy.append(0) + +# Helper Functions +def tab(number) -> str: + t = "" + while len(t) < number: + t += " " + return t + +def display_header() -> None: + print("{}LIFE2".format(tab(33))) + print("{}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n".format(tab(15))) + print("{}U.B. LIFE GAME".format(tab(10))) + +# Board Functions +def setup_board() -> None: + # Players add symbols to initially setup the board + for b in range(1, 3): + p1 = 30 if b == 2 else 3 + print("\nPLAYER {} - 3 LIVE PIECES.".format(b)) + for k1 in range(1, 3): + query_player(b) + gn[gx[b]][gy[b]] = p1 + +def modify_board() -> None: + # Players take turns to add symbols and modify the board + for b in range(1, 3): + print("\n\nPLAYER {} ".format(b)) + query_player(b) + if b == 99: + break + if b <= 2: + gn[gx[1]][gy[1]] = 100 + gn[gx[2]][gy[2]] = 1000 + +def simulate_board() -> None: + # Simulate the board for one step + for j in range(1, 6): + for k in range(1, 6): + if gn[j][k] > 99: + b = 1 if gn[j][k] <= 999 else 10 + for o1 in range(1, 16, 2): + gn[j + ga[o1]][k + ga[o1 + 1]] = gn[j + ga[o1]][k + ga[o1 + 1]] + b + +def display_board() -> None: + # Draws the board with all symbols + m2, m3 = 0, 0 + for j in range(7): + print("\n") + for k in range(7): + if j == 0 or j == 6: + if k != 6: + print(" " + str(k) + " ") + else: + print(" 0 ") + if k == 0 or k == 6: + if j != 6: + print(" " + str(j) + " ") + else: + print(" 0\n") + else: + if gn[j][k] < 3: + gn[j][k] = 0 + print(" ") + else: + for o1 in range(19): + if gn[j][k] == gk[o1]: + if o1 > 9: + gn[j][k] = 1000 + m3 += 1 + print(" # ") + else: + gn[j, k] = 100 + m2 += 1 + print(" * ") + gn[j][k] = 0 + print(" ") + +# Player Functions +def query_player(b) -> None: + # Query player for symbol placement coordinates + while True: + print("X,Y\nXXXXXX\n$$$$$$\n&&&&&&") + x_ = input("??") + y_ = input("???") + x_ = [int(num) for num in x_.split() if num.isdigit()][0] + y_ = [int(num) for num in y_.split() if num.isdigit()][0] + gx[b], gy[b] = y_, x_ + if gx[b] in range(1, 6) and gy[b] in range(1, 6) and gn[gx[b]][gy[b]] != 0: + break + print("ILLEGAL COORDS. RETYPE") + if b != 1: + if gx[1] == gx[2] and gy[1] == gy[2]: + print("SAME COORD. SET TO 0") + gn[gx[b] + 1][gy[b] + 1] = 0 + b = 99 + +# Game Functions +def check_winner(m2, m3) -> None: + # Check if the game has been won + if m2 == 0 and m3 == 0: + print("\nA DRAW\n") + return + if m3 == 0: + print("\nPLAYER 1 IS THE WINNER\n") + return + if m2 == 0: + print("\nPLAYER 2 IS THE WINNER\n") + return + +# Program Flow +def main() -> None: + display_header() + + setup_board() + display_board() + + while True: + print("\n") + simulate_board() + display_board() + check_winner() + modify_board() + +if __name__ == "__main__": + main() From 8fc885a39cdf9b00b01418eeabc37dd647c5290c Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Tue, 28 Jun 2022 03:08:26 +0430 Subject: [PATCH 06/39] Bug fixes. --- .../javascript/.lifefortwo.js.swp | Bin 16384 -> 16384 bytes 56_Life_for_Two/python/lifefortwo.py | 46 ++++++++++-------- 2 files changed, 25 insertions(+), 21 deletions(-) rename 55_Life/python/.life.py.swp => 56_Life_for_Two/javascript/.lifefortwo.js.swp (54%) diff --git a/55_Life/python/.life.py.swp b/56_Life_for_Two/javascript/.lifefortwo.js.swp similarity index 54% rename from 55_Life/python/.life.py.swp rename to 56_Life_for_Two/javascript/.lifefortwo.js.swp index 9f5dd3c294f95c5c6117d7c4b7be74b18adbda1a..da1d2172cb000d9fea57256771784d04a82f0c5f 100644 GIT binary patch literal 16384 zcmeI2TWlj&8OIOZrG(O!Ev1475NF*|9O5{>DA8uKVaa;EsjDQ8Y;V(Tu%fYjk~ofM zteMHhO_yD%4^;b50pg+6_5o?31sTCa0g4Lk_jqzZ{#??`(5V; zR|!jm8VEHIY9Q1=sDV%ep$0+?gc=An@PDHLvvmu*gwfn$kLXc5d`nk&#QwfyhkIT5 z_SY~7H4thb)Ig|#Py?X`LJfo(2sIFDAk;vpflvdX2L1;%pwt+<19II(4gmcA@7(`y zypyrNf-iv2gU^9af+xW=m;xukF!&HS2L62~W3Pc;Lo=)_B_}EkAR2463BoVFb3WOj(}I+&e-3;4e$r>HED?&G|9ld-j-OwACtK-BPP&T~m2e zsjJapHa5oR5#udgTho;$dSM)ov99f`)D%;R4o_JLGMTd6Snyl#6iQW<Vy$TUw4^F8L2^oA8Gp9r>A zU*%B}6VjFWNBHFAS12|dCl6Nw(GataQVnF>0R zeR!~Bse?(@e-yNc^m{eghXJh$cROHP7G}Z=5*){o$85?sl7HD$p#ZJ%_sar zwMC+A7!d40{@7#OicNG&@AT&MM1qoqJ*=QT$JY_0OU{n`mVow1JXWD&0uwNOWaB1$ zCXi&e<#zScv5Tl<*+tZ`?IM+LreQMeZPrY=aWb?>_Lxr3dyKJdMMu>s8Kz{2^+?GZ zGH5GkVYw{7?0UZ_)|c35GM0!D2`7pa{8=AXh&bw#l=4X>V`)@Lr0BznB~c`SWSELH zeWdV_Oxc|_WIvp8C<7tYq>5A}i8QL8idkZ-j)?XvK^Nwhu5!cFT@mnw<8_F&Ak%i% z>zjf{jh0dsqoa7yCFHszHBea;MM;kiO{F4BciueC*gWCIKCci@kv`EkQIqv)azL^! z3~h5;MC&U4IduhNKD6wCg*%|<9@(;qH!n&}t8O)gYR1=uncWl=J=4zBq7iMsbn zaa}aEZIQwB*X*GSS?5JC(^wj!ozZH7%wIBK zvpp^NJ6CG8ELESY8>Uc&9*v-#nzo}xV($4@_R!CgqHXWsw$z$ft*fHecSwE-Rxufd zb9DB|=|l%lmeOhowRWJ%@{3>ybH+6FdIkS~9gS=XbG1a+buy2 zm|_>JsjnjJEpggAe97s|Hg2le;fuP~tQ#WQ zIU+~xJx%jzbxPJu_R=wiZj!x9eOAsY>>jQ=67}6q-WlqYmhzXNq6MtmDA^XM%41BW zdMF*2-Z8pAkoqvw!l{U{CRg9>lZHk)4XXA8JQMKwi zt_5_5qju(U=d%1z|X*!!By}n@F-9~3VZqBo#Nw^<7m>> zqBU6il1R-uk8Ew4w-ntFIk*yWs)-w06$DnajzjZqel;42MTTio=p^LSbwb&%zl|Qn z&?Kf&*-`4IJk|9&TieQeICdeZDf`kJm;$@b;@r%IYyo#HU&<{kWD9Rl4q5=@AHfdruDt{HojiQs@Y5W! z?-_o!Ftc>}E0*$03o*WsUE&XB3&pJG-R26IhHnf4k_R9q<@yh?>E4Y1 literal 16384 zcmeI3UyK_^9ml6h)24+ML_kFX#KZ^G&Ry`m=m zcXyq$6)q)hRSAg~Dg+X=4S%E-!9!K?P@qx;FMUC3U*NGq4JiD1q2hr*rAT~#GqXEu z=MJhqftam6+1;7n{AT96znQt6b=N1)7nb?a@o9$RgN)tjys-Z0b9>p7_cInc7u|a3 z1P_aVa(6r~IV};mV#oYA<4Vfm#G(ivj{MHVx)Zv!gEhb1=|&NEUvePv>S? zT!5^5gVsG`-P6{Id56#O$>eT?w_H!~naN|&Bz3qRe$C?6VOtKmVjxSkVU8a;nk2g$ zx@E_aYFbAA{+%P)uQ@(5;72Cj&u8Af8)(u)L#L+){K(YfNPYK?P&GNasXaX|+mpDD z74Sqas>&OarTe6^=*DE}b|$5ICQH|xl|~szxbd zmghfLJ)JL{I$chMjDG6V#}04jHj^2@=(}E)BBR=J!zedYJJp!VR_9W6y_F6LX-%I)L?PRZY#E3EWl(tO=lHOJNYv@AeKxR;jxbZdLi(GGL z3{a-P&#|~u>8+82{d0V3Fwo-iu>}lRoED!4T+AWzws)~(6UdM8Z$@?OKh;2Z9~ueU z%`#?&nM#EVxl81NR+S9TtnmXfwk{MF%cogfA)U92&Efe;)kAX=)$<>Vr$bvlPNP$U zkEWGXvs>bDAWDrsNiq%h;be+OB-6l=ouj#Q$e|81Gq$8nVx$z<$ehX-^Q-ga!b)+L zUv6xDAu6qu&Mn0Woh^PDvtu=kg00L@fa-LL%S_@{v_fGz&T*v73dQsDONGV##vBh{ zPrjteC5D1pt46sTQ${wjMSD6L9IBnUs@pYWYqADYquG zQe(jcP;O1t6)!DGp(Oe!hr-pAF?hDrKYeQbw{{ z)ZIY`YH}Y)Q_qDa1S||xLash?g7CU+5Xq@0 zuZM;%h`fe~s`@To7iIjSv{M&BHnUVXna7B#3;MGJOF@nwJkE>0htXr^n%ZDAYloE@ zEe6yB*)!@L9kNRpjQDR<-c+V$*O<)0KZtBHs7#_PjK&euN!|z#Bd70r4Jb06O6_`{ zsEH6iEAC7EO7bVZV|*PUN_sZ2?)rgSb6VV~)w+RG!-DBX_l7ASvQ?Wd9<#&ie#8;b zbvJa@G0Z96G2kN+cAT0(8v?h}K`X|28J@YDcB87+!=vttkb8bah5{{Vwfs$Ly+aov z@B3Y<27L-5?xfoC!2H?5g7&fLcUyH;C-vi{L%B-5OnD$ew#;q z3R3R2J3iuzL}o05C9s5BQRnM@zUW}CUJ?uVp?oCp&g_wKOSGY<6S=-e0r#Na^!S4B zZ94sXL*DT_-If#ZnrOA;h0~4vwiEdtV>DC93h4d+7Q9dQ0lojn-}i6e{hi+Xp9IU` zGhh#(_xM-9HQ)hyhd&BF0X`1y0QBzuEATS-4)`{>2A%*^PY>9`Dqt0`3RnfK0#*U5 zfK|XMU=^?m{NE@*Z?tNYhT(m`TJ`WhK3A*qoxh52E7;kp(sqh`^HsL=1x)Tr$uD7M zk1^gLQ)lcfn=*QTOl?l4w{zoNF?CMo=uN;QGee(9s10=Nuo-&u9<4G@@6(&_RB@jC z4v?++T`!_fO*xJYAboqBAJRK#v2psmLn~qv^KHO<(~9%x48>KY+kbmNcH#kBC1$5K z?IXTcjs`a48f*O_ QH2w%0Tg7MHdF%rH3;FJ)4gdfE diff --git a/56_Life_for_Two/python/lifefortwo.py b/56_Life_for_Two/python/lifefortwo.py index f2c5f824..f8b3e3aa 100644 --- a/56_Life_for_Two/python/lifefortwo.py +++ b/56_Life_for_Two/python/lifefortwo.py @@ -30,9 +30,9 @@ def display_header() -> None: def setup_board() -> None: # Players add symbols to initially setup the board for b in range(1, 3): - p1 = 30 if b == 2 else 3 + p1 = 3 if b != 2 else 30 print("\nPLAYER {} - 3 LIVE PIECES.".format(b)) - for k1 in range(1, 3): + for k1 in range(1, 4): query_player(b) gn[gx[b]][gy[b]] = p1 @@ -53,42 +53,46 @@ def simulate_board() -> None: for k in range(1, 6): if gn[j][k] > 99: b = 1 if gn[j][k] <= 999 else 10 - for o1 in range(1, 16, 2): + for o1 in range(0, 15, 2): + #print("{} {} {} {}".format(j, k, b, o1)) gn[j + ga[o1]][k + ga[o1 + 1]] = gn[j + ga[o1]][k + ga[o1 + 1]] + b def display_board() -> None: # Draws the board with all symbols m2, m3 = 0, 0 for j in range(7): - print("\n") + print("") for k in range(7): if j == 0 or j == 6: if k != 6: - print(" " + str(k) + " ") + print(" " + str(k) + " ", end="") else: - print(" 0 ") - if k == 0 or k == 6: + print(" 0 ", end="") + elif k == 0 or k == 6: if j != 6: - print(" " + str(j) + " ") + print(" " + str(j) + " ", end="") else: print(" 0\n") else: if gn[j][k] < 3: gn[j][k] = 0 - print(" ") + print(" ", end="") else: - for o1 in range(19): + for o1 in range(18): if gn[j][k] == gk[o1]: - if o1 > 9: - gn[j][k] = 1000 - m3 += 1 - print(" # ") - else: - gn[j, k] = 100 - m2 += 1 - print(" * ") - gn[j][k] = 0 - print(" ") + break + if o1 <= 18: + if o1 > 9: + gn[j][k] = 1000 + m3 += 1 + print(" # ", end="") + else: + gn[j][k] = 100 + m2 += 1 + print(" * ", end="") + else: + gn[j][k] = 0 + print(" ", end="") # Player Functions def query_player(b) -> None: @@ -100,7 +104,7 @@ def query_player(b) -> None: x_ = [int(num) for num in x_.split() if num.isdigit()][0] y_ = [int(num) for num in y_.split() if num.isdigit()][0] gx[b], gy[b] = y_, x_ - if gx[b] in range(1, 6) and gy[b] in range(1, 6) and gn[gx[b]][gy[b]] != 0: + if gx[b] in range(1, 6) and gy[b] in range(1, 6) and gn[gx[b]][gy[b]] == 0: break print("ILLEGAL COORDS. RETYPE") if b != 1: From e0c790b6b9934802c7994be84820d84c2368a40d Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Tue, 28 Jun 2022 16:23:09 +0430 Subject: [PATCH 07/39] First pass of functional port with various errors. --- 55_Life/.life.bas.swp | Bin 12288 -> 0 bytes 56_Life_for_Two/.lifefortwo.bas.swp | Bin 12288 -> 0 bytes 56_Life_for_Two/javascript/.lifefortwo.js.swp | Bin 16384 -> 0 bytes 56_Life_for_Two/python/LIFE2.py | 136 ------------------ .../python/{lifefortwo.py => life_for_two.py} | 39 ++--- 5 files changed, 23 insertions(+), 152 deletions(-) delete mode 100644 55_Life/.life.bas.swp delete mode 100644 56_Life_for_Two/.lifefortwo.bas.swp delete mode 100644 56_Life_for_Two/javascript/.lifefortwo.js.swp delete mode 100644 56_Life_for_Two/python/LIFE2.py rename 56_Life_for_Two/python/{lifefortwo.py => life_for_two.py} (77%) diff --git a/55_Life/.life.bas.swp b/55_Life/.life.bas.swp deleted file mode 100644 index e905a787d5fa2194d6184b5cafad82fb02210a1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O>7%Q6vtnSgi2`x0*Q|k(`^r4V#hnPUdMK_M$UTUZnRlju9NP906C38X;U>M z;o}51xWSEkB?K3wN=RHlNJw0exO1dJLPCfG7cSiR&&MWdrCxfgG?xBe&&Qj2@Auxb z6vbQKX0py&3xe=^n&|BG&er>1o}s@ZqJ!!6o$Z6^{*BqbTz%l{z3J|3e`of<^>X3E z69?A&vx6IlxAy8=(}SIBwQIL-?!9|B+poPny*WFm2f>@^&RetkF5VWfqddVrEdfj5 z;R&24UvN*_Uvw_8XP?=4_@k_)C143y0+xU!U^1HA!_pcRNi&qKeTC;Aoo1^O1+g;Hn* zdI>rQoreB7NAxpv8~Ox#2YL;Pp*r*;GzUEf-F=eiN9YUaW9T}RLVc(PJqOJ}|D7fJ z1Ns5_2Koy66xxPfh1Q`3=pyt2^ecr4EP z)NFWcFq{mT{P|bY4_MB_oY#1#;9()3xd?MHkFf{~Jh8`PS)5N;PEBDx7S!Y(OIBGF z`fPGJ&RDOKR|_}vJEL$UjXZM;OekmvOiu@GZME#P;h06;#y!TOqdkK$1ueDH9P8N`Uy}bgtORX~~RyuZ>7OJQt-qh3Gb0`hL)CwmL~WtjS%0 zTIIl?-~qjVwC2mTTy%x;9QhF9XqBtgBTFQ&v=r^O%BA0db(l9gOlA}#naBnSB*AzL zPo>8KTSns~n{>+j3Z%!RT9lXz5{N+t(=AN8ibg1Bn`(BsD1-3TY(qKN&CTAt5$4z{ z)a-I@_U68t<@$a$>8(@>cgcC#S;F2EiC^x*Q(0bcheV)mEGtbfm=W*jnr?DzQv}U| zfmqg&*``iAPOMHV2~>vyLc)}UOs`HZ2~qOXGqP3g$A_93gag!p;OHwq1mVID7rhQB zU^lo)8`KAS&xGy_;w&EbCdn}CI7@@7Ga8OI(sDdn>PT=&TL-J0V@{H7_R^$(LDE7U z>KvYUCywSZdF01=_aOR~|%L~lkW;2kG~*~ic5dlk{BE_!YiCy9njsx@T^0Ep^O z*?eeB6k@BaggBeT_@WtZjM=C+!DmziHOm^)`PCz87#rC*JV56};}|uw8MA1(4xf^2 kz}Wh5JWj4mhF7yH&|hV1@%TzyI3!LO`wbYU$!hG-|9k7G5C8xG diff --git a/56_Life_for_Two/.lifefortwo.bas.swp b/56_Life_for_Two/.lifefortwo.bas.swp deleted file mode 100644 index a40819f1e2893bdd7fbb962d8605cf8bcd162b7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2zi%8x6vtnXfDjTuq(Gt?Hc@no&*zz0@7@pRg6@19`+n}}ZXNpyWL=UAI6rW( z4XFrC3M3>dLKi6w2th#+{sBZoh0@SaQBcrQK!?J2e%vpM6e%NS<i`vyLk7jqjYbLXn%Nh=koq=@7icjy?yNU;qdxsZ)fz__v070 zX96zOM*G(ec5g0S9PaO2TD-J-_F&f&wYH@;K$a!A`!q@g&a9)+yi=a0)mDoB~b(r+`zyDc}@% z$`v@cd4xX39GdXea7@FTbnJ_7H7w?PZM z1(tyi9vvfk2p)hhz^C9gxC+*R4~~IhFd-YDryn3q@uT@%XHA#B4 zevb9xbkL2x5?f2sgylJ>{IX!3%vPrAFNo|wH-4FyShZX%mX!TQuLGk=#D1k6n{YYC z`fv2c*3{=lx(u1Ismt4K6mW8nzk0*2plb6oQ zKYNZF6U>hCg4-FW2VOAItNz(?I5S$+pZJInX3?yV&2ipG$uRNZ1^5W7->5QG7GXY|GoQ8d>U}i|+pKpw@GR+CDrl$WLrxV|>s2=AOaikCVL=TdRoZP? zwrg80BTF3)!=Qi!5NR`h}Qv>+x#b&v_Jz;^AcxWdzjQ zK$_+2q6gWDyvd+}ThxSF>n3hPB-+R}u}$$HOkyT4Xoj7k7QHd);Gq_{q_v@NQmkpE zni1Sz@iubR9CAD#vo-8(j{+3YcmP{0%wvpsC=k0pgD9NdD&2HCs8bXwmY^LhKsckm)z(JPVa@OHZe#LzhJ^n#mwl3Z(H1Sz(R`YmY%-5!lep`OtdXHV=iK znuPGwTemSA8xP~yTv-@}nrd?=EFx%N3fDZ_`k^9cFws?Fii;D9&x(TmZ8br8A^nM- zX3l2QLvU;h9lSZ+6?QPaI3X6r9y?0VDA8uKVaa;EsjDQ8Y;V(Tu%fYjk~ofM zteMHhO_yD%4^;b50pg+6_5o?31sTCa0g4Lk_jqzZ{#??`(5V; zR|!jm8VEHIY9Q1=sDV%ep$0+?gc=An@PDHLvvmu*gwfn$kLXc5d`nk&#QwfyhkIT5 z_SY~7H4thb)Ig|#Py?X`LJfo(2sIFDAk;vpflvdX2L1;%pwt+<19II(4gmcA@7(`y zypyrNf-iv2gU^9af+xW=m;xukF!&HS2L62~W3Pc;Lo=)_B_}EkAR2463BoVFb3WOj(}I+&e-3;4e$r>HED?&G|9ld-j-OwACtK-BPP&T~m2e zsjJapHa5oR5#udgTho;$dSM)ov99f`)D%;R4o_JLGMTd6Snyl#6iQW<Vy$TUw4^F8L2^oA8Gp9r>A zU*%B}6VjFWNBHFAS12|dCl6Nw(GataQVnF>0R zeR!~Bse?(@e-yNc^m{eghXJh$cROHP7G}Z=5*){o$85?sl7HD$p#ZJ%_sar zwMC+A7!d40{@7#OicNG&@AT&MM1qoqJ*=QT$JY_0OU{n`mVow1JXWD&0uwNOWaB1$ zCXi&e<#zScv5Tl<*+tZ`?IM+LreQMeZPrY=aWb?>_Lxr3dyKJdMMu>s8Kz{2^+?GZ zGH5GkVYw{7?0UZ_)|c35GM0!D2`7pa{8=AXh&bw#l=4X>V`)@Lr0BznB~c`SWSELH zeWdV_Oxc|_WIvp8C<7tYq>5A}i8QL8idkZ-j)?XvK^Nwhu5!cFT@mnw<8_F&Ak%i% z>zjf{jh0dsqoa7yCFHszHBea;MM;kiO{F4BciueC*gWCIKCci@kv`EkQIqv)azL^! z3~h5;MC&U4IduhNKD6wCg*%|<9@(;qH!n&}t8O)gYR1=uncWl=J=4zBq7iMsbn zaa}aEZIQwB*X*GSS?5JC(^wj!ozZH7%wIBK zvpp^NJ6CG8ELESY8>Uc&9*v-#nzo}xV($4@_R!CgqHXWsw$z$ft*fHecSwE-Rxufd zb9DB|=|l%lmeOhowRWJ%@{3>ybH+6FdIkS~9gS=XbG1a+buy2 zm|_>JsjnjJEpggAe97s|Hg2le;fuP~tQ#WQ zIU+~xJx%jzbxPJu_R=wiZj!x9eOAsY>>jQ=67}6q-WlqYmhzXNq6MtmDA^XM%41BW zdMF*2-Z8pAkoqvw!l{U{CRg9>lZHk)4XXA8JQMKwi zt_5_5qju(U=d%1z|X*!!By}n@F-9~3VZqBo#Nw^<7m>> zqBU6il1R-uk8Ew4w-ntFIk*yWs)-w06$DnajzjZqel;42MTTio=p^LSbwb&%zl|Qn z&?Kf&*-`4IJk|9&TieQeICdeZDf`kJm;$@b;@r%IYyo#HU&<{kWD9Rl4q5=@AHfdruDt{HojiQs@Y5W! z?-_o!Ftc>}E0*$03o*WsUE&XB3&pJG-R26IhHnf4k_R9q<@yh?>E4Y1 diff --git a/56_Life_for_Two/python/LIFE2.py b/56_Life_for_Two/python/LIFE2.py deleted file mode 100644 index a15a9b2f..00000000 --- a/56_Life_for_Two/python/LIFE2.py +++ /dev/null @@ -1,136 +0,0 @@ -# Variable Initialisation -gn, gk, ga, gx, gy = [], [], [], [], [] -gk = [3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] -ga = [-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] -m2, m3 = 0, 0 - -# Initialise the board -for j in range(6): - gn[j] = [] - for k in range(6): - gn[j][k] = 0 - -# Helper Functions -def tab(number) -> str: - t = "" - while len(t) < number: - t += " " - return t - -def display_header() -> None: - print("{}LIFE2\n".format(tab(33))) - print("{}CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n\n\n\n".format(tab(15))) - print("{}U.B. LIFE GAME".format(tab(10))) - -# Board Functions -def setup_board() -> None: - # Players add symbols to initially setup the board - for b in range(1, 3): - p1 = 30 if b == 2 else 3 - print("\n\nPLAYER {} - 3 LIVE PIECES.".format(b)) - for k1 in range(1, 3): - query_player(b) - gn[gx[b]][gy[b]] = p1 - -def modify_board() -> None: - # Players take turns to add symbols and modify the board - for b in range(1, 3): - print("\n\nPLAYER {} ".format(b)) - query_player(b) - if b == 99: - break - if b <= 2: - gn[gx[1]][gy[1]] = 100 - gn[gx[2]][gy[2]] = 1000 - -def simulate_board() -> None: - # Simulate the board for one step - for j in range(1, 6): - for k in range(1, 6): - if gn[j][k] > 99: - b = 1 if gn[j][k] <= 999 else 10 - for o1 in range(1, 16, 2): - gn[j + ga[o1]][k + ga[o1 + 1]] = gn[j + ga[o1]][k + ga[o1 + 1]] + b - -def display_board() -> None: - # Draws the board with all symbols - m2, m3 = 0, 0 - for j in range(7): - print("\n") - for k in range(7): - if j == 0 or j == 6: - if k != 6: - print(" " + str(k) + " ") - else: - print(" 0 ") - if k == 0 or k == 6: - if j != 6: - print(" " + str(j) + " ") - else: - print(" 0\n") - else: - if gn[j][k] < 3: - gn[j][k] = 0 - print(" ") - else: - for o1 in range(19): - if gn[j][k] == gk[o1]: - if o1 > 9: - gn[j][k] = 1000 - m3 += 1 - print(" # ") - else: - gn[j, k] = 100 - m2 += 1 - print(" * ") - gn[j][k] = 0 - print(" ") - -# Player Functions -def query_player(b) -> None: - # Query player for symbol placement coordinates - while True: - print("X,Y\nXXXXXX\n$$$$$$\n&&&&&&\n") - x_ = input("") - y_ = input(" ") - x_ = [int(num) for num in x_.split() if num.isdigit()][0] - y_ = [int(num) for num in y_.split() if num.isdigit()][0] - gx[b], gy[b] = x_, y_ - if gx[b] in range(1, 6) and gy[b] in range(1, 6) and gn[gx[b]][gy[b]] != 0: - break - print("ILLEGAL COORDS. RETYPE\n") - if b != 1: - if gx[1] == gx[2] and gy[1] == gy[2]: - print("SAME COORD. SET TO 0") - gn[gx[b] + 1][gy[b] + 1] = 0 - b = 99 - -# Game Functions -def check_winner(m2, m3) -> None: - # Check if the game has been won - if m2 == 0 and m3 == 0: - print("\nA DRAW\n") - return - if m3 == 0: - print("\nPLAYER 1 IS THE WINNER\n") - return - if m2 == 0: - print("\nPLAYER 2 IS THE WINNER\n") - return - -# Program Flow -def main() -> None: - display_header() - - setup_board() - display_board() - - while True: - print("\n") - simulate_board() - display_board() - check_winner() - modify_board() - -if __name__ == "__main__": - main() diff --git a/56_Life_for_Two/python/lifefortwo.py b/56_Life_for_Two/python/life_for_two.py similarity index 77% rename from 56_Life_for_Two/python/lifefortwo.py rename to 56_Life_for_Two/python/life_for_two.py index f8b3e3aa..a7ebbe5a 100644 --- a/56_Life_for_Two/python/lifefortwo.py +++ b/56_Life_for_Two/python/life_for_two.py @@ -1,7 +1,15 @@ -# Variable Initialisation +''' +LIFE FOR TWO + +Competitive Game of Life (two or more players). + +Ported by Sajid Sarker (2022). +''' + +# Global Variable Initialisation gn, gk, ga, gx, gy = [], [], [], [], [] -gk = [3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] -ga = [-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] +gk = [-999, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] +ga = [-999, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] m2, m3 = 0, 0 # Initialise the board @@ -15,7 +23,7 @@ for i in range(3): gy.append(0) # Helper Functions -def tab(number) -> str: +def tab(number : int) -> str: t = "" while len(t) < number: t += " " @@ -39,7 +47,7 @@ def setup_board() -> None: def modify_board() -> None: # Players take turns to add symbols and modify the board for b in range(1, 3): - print("\n\nPLAYER {} ".format(b)) + print("PLAYER {} ".format(b)) query_player(b) if b == 99: break @@ -53,9 +61,8 @@ def simulate_board() -> None: for k in range(1, 6): if gn[j][k] > 99: b = 1 if gn[j][k] <= 999 else 10 - for o1 in range(0, 15, 2): - #print("{} {} {} {}".format(j, k, b, o1)) - gn[j + ga[o1]][k + ga[o1 + 1]] = gn[j + ga[o1]][k + ga[o1 + 1]] + b + for o1 in range(1, 16, 2): + gn[j + ga[o1] - 1][k + ga[o1 + 1] - 1] = gn[j + ga[o1] - 1][k + ga[o1 + 1] - 1] + b def display_board() -> None: # Draws the board with all symbols @@ -78,7 +85,7 @@ def display_board() -> None: gn[j][k] = 0 print(" ", end="") else: - for o1 in range(18): + for o1 in range(1, 19): if gn[j][k] == gk[o1]: break if o1 <= 18: @@ -101,9 +108,11 @@ def query_player(b) -> None: print("X,Y\nXXXXXX\n$$$$$$\n&&&&&&") x_ = input("??") y_ = input("???") - x_ = [int(num) for num in x_.split() if num.isdigit()][0] - y_ = [int(num) for num in y_.split() if num.isdigit()][0] - gx[b], gy[b] = y_, x_ + x_ = [int(num) for num in x_.split() if num.isdigit()] + y_ = [int(num) for num in y_.split() if num.isdigit()] + x_ = [0] if len(x_) == 0 else x_ + y_ = [0] if len(y_) == 0 else y_ + gx[b], gy[b] = y_[0], x_[0] if gx[b] in range(1, 6) and gy[b] in range(1, 6) and gn[gx[b]][gy[b]] == 0: break print("ILLEGAL COORDS. RETYPE") @@ -114,7 +123,7 @@ def query_player(b) -> None: b = 99 # Game Functions -def check_winner(m2, m3) -> None: +def check_winner(m2 : int, m3 : int) -> None: # Check if the game has been won if m2 == 0 and m3 == 0: print("\nA DRAW\n") @@ -129,15 +138,13 @@ def check_winner(m2, m3) -> None: # Program Flow def main() -> None: display_header() - setup_board() display_board() - while True: print("\n") simulate_board() display_board() - check_winner() + check_winner(m2, m3) modify_board() if __name__ == "__main__": From 45a1f12896f11721f8b18292933f2a7e769e9b8c Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Wed, 29 Jun 2022 02:13:19 +0430 Subject: [PATCH 08/39] Bugged version. --- 56_Life_for_Two/python/life_for_two.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/56_Life_for_Two/python/life_for_two.py b/56_Life_for_Two/python/life_for_two.py index a7ebbe5a..088dac37 100644 --- a/56_Life_for_Two/python/life_for_two.py +++ b/56_Life_for_Two/python/life_for_two.py @@ -8,8 +8,8 @@ Ported by Sajid Sarker (2022). # Global Variable Initialisation gn, gk, ga, gx, gy = [], [], [], [], [] -gk = [-999, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] -ga = [-999, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] +gk = [0, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] +ga = [0, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] m2, m3 = 0, 0 # Initialise the board @@ -63,6 +63,7 @@ def simulate_board() -> None: b = 1 if gn[j][k] <= 999 else 10 for o1 in range(1, 16, 2): gn[j + ga[o1] - 1][k + ga[o1 + 1] - 1] = gn[j + ga[o1] - 1][k + ga[o1 + 1] - 1] + b + #gn[j + ga[o1]][k + ga[o1 + 1]] = gn[j + ga[o1]][k + ga[o1 + 1]] + b def display_board() -> None: # Draws the board with all symbols From 83bb9bd55838c9b7119e73cb09c0e58dc41c9c6c Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Wed, 29 Jun 2022 02:36:44 +0430 Subject: [PATCH 09/39] Complete with bug. --- 56_Life_for_Two/python/life_for_two.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/56_Life_for_Two/python/life_for_two.py b/56_Life_for_Two/python/life_for_two.py index 088dac37..b79cf77c 100644 --- a/56_Life_for_Two/python/life_for_two.py +++ b/56_Life_for_Two/python/life_for_two.py @@ -7,10 +7,13 @@ Ported by Sajid Sarker (2022). ''' # Global Variable Initialisation -gn, gk, ga, gx, gy = [], [], [], [], [] -gk = [0, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] -ga = [0, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] -m2, m3 = 0, 0 +gn: List[int] = [] +gx: List[int] = [] +gy: List[int] = [] +gk: List[int] = [0, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] +ga: List[int] = [0, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] +m2: int = 0 +m3: int = 0 # Initialise the board for j in range(6): @@ -107,13 +110,14 @@ def query_player(b) -> None: # Query player for symbol placement coordinates while True: print("X,Y\nXXXXXX\n$$$$$$\n&&&&&&") - x_ = input("??") - y_ = input("???") - x_ = [int(num) for num in x_.split() if num.isdigit()] - y_ = [int(num) for num in y_.split() if num.isdigit()] + a_: List[str] = input("??") + b_: List[str] = input("???") + x_: List[int] = [int(num) for num in a_.split() if num.isdigit()] + y_: List[int] = [int(num) for num in b_.split() if num.isdigit()] x_ = [0] if len(x_) == 0 else x_ y_ = [0] if len(y_) == 0 else y_ - gx[b], gy[b] = y_[0], x_[0] + gx[b] = y_[0] + gy[b] = x_[0] if gx[b] in range(1, 6) and gy[b] in range(1, 6) and gn[gx[b]][gy[b]] == 0: break print("ILLEGAL COORDS. RETYPE") From b5aa8823ce0082495ee376c801b8d82e9455216b Mon Sep 17 00:00:00 2001 From: sajidsarker Date: Fri, 15 Jul 2022 16:26:38 +0430 Subject: [PATCH 10/39] Fix for python validation check. --- 56_Life_for_Two/python/life_for_two.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/56_Life_for_Two/python/life_for_two.py b/56_Life_for_Two/python/life_for_two.py index b79cf77c..fffabc19 100644 --- a/56_Life_for_Two/python/life_for_two.py +++ b/56_Life_for_Two/python/life_for_two.py @@ -6,6 +6,8 @@ Competitive Game of Life (two or more players). Ported by Sajid Sarker (2022). ''' +from typing import List + # Global Variable Initialisation gn: List[int] = [] gx: List[int] = [] From da137fe6d02b9a73e77a7660a8fcc8640cca8782 Mon Sep 17 00:00:00 2001 From: Aldrin Misquitta Date: Thu, 21 Jul 2022 16:55:40 +0530 Subject: [PATCH 11/39] Ported 56 Life for Two to Java --- 56_Life_for_Two/README.md | 6 +- 56_Life_for_Two/java/LifeForTwo.java | 305 +++++++++++++++++++++++++++ 2 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 56_Life_for_Two/java/LifeForTwo.java diff --git a/56_Life_for_Two/README.md b/56_Life_for_Two/README.md index 3cc22c9e..3d906342 100644 --- a/56_Life_for_Two/README.md +++ b/56_Life_for_Two/README.md @@ -6,6 +6,7 @@ There are two players; the game is played on a 5x5 board and each player has a s The # and * are regarded as the same except when deciding whether to generate a live cell. An empty cell having two `#` and one `*` for neighbors will generate a `#`, i.e. the live cell generated belongs to the player who has the majority of the 3 live cells surrounding the empty cell where life is to be generated, for example: +``` | | 1 | 2 | 3 | 4 | 5 | |:-:|:-:|:-:|:-:|:-:|:-:| | 1 | | | | | | @@ -13,9 +14,10 @@ The # and * are regarded as the same except when deciding whether to generate a | 3 | | | | # | | | 4 | | | # | | | | 5 | | | | | | +``` A new cell will be generated at (3,3) which will be a `#` since there are two `#` and one `*` surrounding. The board will then become: - +``` | | 1 | 2 | 3 | 4 | 5 | |:-:|:-:|:-:|:-:|:-:|:-:| | 1 | | | | | | @@ -23,7 +25,7 @@ A new cell will be generated at (3,3) which will be a `#` since there are two `# | 3 | | | # | # | | | 4 | | | | | | | 5 | | | | | | - +``` On the first most each player positions 3 pieces of life on the board by typing in the co-ordinates of the pieces. (In the event of the same cell being chosen by both players that cell is left empty.) The board is then adjusted to the next generation and printed out. diff --git a/56_Life_for_Two/java/LifeForTwo.java b/56_Life_for_Two/java/LifeForTwo.java new file mode 100644 index 00000000..1f68e794 --- /dev/null +++ b/56_Life_for_Two/java/LifeForTwo.java @@ -0,0 +1,305 @@ +import java.util.*; +import java.util.stream.IntStream; + +/** + * Life for Two + *

+ * The original BASIC program uses a grid with an extras border of cells all around, + * probably to simplify calculations and manipulations. This java program has the exact + * grid size and instead uses boundary check conditions in the logic. + *

+ * Converted from BASIC to Java by Aldrin Misquitta (@aldrinm) + */ +public class LifeForTwo { + + final static int GRID_SIZE = 5; + + //Pair of offset which when added to the current cell's coordinates, + // give the coordinates of the neighbours + final static int[] neighbourCellOffsets = { + -1, 0, + 1, 0, + 0, -1, + 0, 1, + -1, -1, + 1, -1, + -1, 1, + 1, 1 + }; + + //The best term that I could come with to describe these numbers was 'masks' + //They act like indicators to decide which player won the cell. The value is the score of the cell after all the + // generation calculations. + final static List maskPlayer1 = List.of(3, 102, 103, 120, 130, 121, 112, 111, 12); + final static List maskPlayer2 = List.of(21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012); + + public static void main(String[] args) { + printIntro(); + Scanner scan = new Scanner(System.in); + scan.useDelimiter("\\D"); + + int[][] grid = new int[GRID_SIZE][GRID_SIZE]; + + initializeGrid(grid); + + //Read the initial 3 moves for each player + for (int b = 1; b <= 2; b++) { + System.out.printf("\nPLAYER %d - 3 LIVE PIECES.%n", b); + for (int k1 = 1; k1 <= 3; k1++) { + var player1Coordinates = readUntilValidCoordinates(scan, grid); + grid[player1Coordinates.x - 1][player1Coordinates.y - 1] = (b == 1 ? 3 : 30); + } + } + + printGrid(grid); + + calculatePlayersScore(grid); //Convert 3, 30 to 100, 1000 + + resetGridForNextGen(grid); + computeCellScoresForOneGen(grid); + + var playerScores = calculatePlayersScore(grid); + resetGridForNextGen(grid); + + boolean gameOver = false; + while (!gameOver) { + printGrid(grid); + if (playerScores.getPlayer1Score() == 0 && playerScores.getPlayer2Score() == 0) { + System.out.println("\nA DRAW"); + gameOver = true; + } else if (playerScores.getPlayer2Score() == 0) { + System.out.println("\nPLAYER 1 IS THE WINNER"); + gameOver = true; + } else if (playerScores.getPlayer1Score() == 0) { + System.out.println("\nPLAYER 2 IS THE WINNER"); + gameOver = true; + } else { + System.out.print("PLAYER 1 "); + Coordinate player1Move = readCoordinate(scan); + System.out.print("PLAYER 2 "); + Coordinate player2Move = readCoordinate(scan); + if (!player1Move.equals(player2Move)) { + grid[player1Move.x - 1][player1Move.y - 1] = 100; + grid[player2Move.x - 1][player2Move.y - 1] = 1000; + } + //In the original, B is assigned 99 when both players choose the same cell + //and that is used to control the flow + computeCellScoresForOneGen(grid); + playerScores = calculatePlayersScore(grid); + resetGridForNextGen(grid); + } + } + + } + + private static void initializeGrid(int[][] grid) { + for (int[] row : grid) { + Arrays.fill(row, 0); + } + } + + private static void computeCellScoresForOneGen(int[][] grid) { + for (int i = 0; i < GRID_SIZE; i++) { + for (int j = 0; j < GRID_SIZE; j++) { + if (grid[i][j] >= 100) { + calculateScoreForOccupiedCell(grid, i, j); + } + } + } + } + + private static Scores calculatePlayersScore(int[][] grid) { + int m2 = 0; + int m3 = 0; + for (int i = 0; i < GRID_SIZE; i++) { + for (int j = 0; j < GRID_SIZE; j++) { + if (grid[i][j] < 3) { + grid[i][j] = 0; + } else { + if (maskPlayer1.contains(grid[i][j])) { + m2++; + } else if (maskPlayer2.contains(grid[i][j])) { + m3++; + } + } + } + } + return new Scores(m2, m3); + } + + private static void resetGridForNextGen(int[][] grid) { + for (int i = 0; i < GRID_SIZE; i++) { + for (int j = 0; j < GRID_SIZE; j++) { + if (grid[i][j] < 3) { + grid[i][j] = 0; + } else { + if (maskPlayer1.contains(grid[i][j])) { + grid[i][j] = 100; + } else if (maskPlayer2.contains(grid[i][j])) { + grid[i][j] = 1000; + } else { + grid[i][j] = 0; + } + } + } + } + } + + private static void calculateScoreForOccupiedCell(int[][] grid, int i, int j) { + var b = 1; + if (grid[i][j] > 999) { + b = 10; + } + for (int k = 0; k < 15; k += 2) { + //check bounds + var neighbourX = i + neighbourCellOffsets[k]; + var neighbourY = j + neighbourCellOffsets[k + 1]; + if (neighbourX >= 0 && neighbourX < GRID_SIZE && + neighbourY >= 0 && neighbourY < GRID_SIZE) { + grid[neighbourX][neighbourY] = grid[neighbourX][neighbourY] + b; + } + + } + } + + private static void printGrid(int[][] grid) { + System.out.println(); + printRowEdge(); + System.out.println(); + for (int i = 0; i < grid.length; i++) { + System.out.printf("%d ", i + 1); + for (int j = 0; j < grid[i].length; j++) { + System.out.printf(" %c ", mapChar(grid[i][j])); + } + System.out.printf(" %d", i + 1); + System.out.println(); + } + printRowEdge(); + System.out.println(); + } + + private static void printRowEdge() { + System.out.print("0 "); + IntStream.range(1, GRID_SIZE + 1).forEach(i -> System.out.printf(" %s ", i)); + System.out.print(" 0"); + } + + private static char mapChar(int i) { + if (i == 3 || i == 100) { + return '*'; + } + if (i == 30 || i == 1000) { + return '#'; + } + return ' '; + } + + private static Coordinate readUntilValidCoordinates(Scanner scanner, int[][] grid) { + boolean coordinateInRange = false; + Coordinate coordinate = null; + while (!coordinateInRange) { + coordinate = readCoordinate(scanner); + if (coordinate.x <= 0 || coordinate.x > GRID_SIZE + || coordinate.y <= 0 || coordinate.y > GRID_SIZE + || grid[coordinate.x - 1][coordinate.y - 1] != 0) { + System.out.println("ILLEGAL COORDS. RETYPE"); + } else { + coordinateInRange = true; + } + } + return coordinate; + } + + private static Coordinate readCoordinate(Scanner scanner) { + Coordinate coordinate = null; + int x, y; + boolean valid = false; + + System.out.println("X,Y"); + System.out.print("XXXXXX\r"); + System.out.print("$$$$$$\r"); + System.out.print("&&&&&&\r"); + + while (!valid) { + try { + System.out.print("? "); + y = scanner.nextInt(); + x = scanner.nextInt(); + valid = true; + coordinate = new Coordinate(x, y); + } catch (InputMismatchException e) { + System.out.println("!NUMBER EXPECTED - RETRY INPUT LINE"); + valid = false; + } finally { + scanner.nextLine(); + } + } + return coordinate; + } + + private static void printIntro() { + System.out.println(" LIFE2"); + System.out.println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"); + System.out.println("\n\n"); + + System.out.println("\tU.B. LIFE GAME"); + } + + private static class Coordinate { + private final int x, y; + + public Coordinate(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + @Override + public String toString() { + return "Coordinate{" + + "x=" + x + + ", y=" + y + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Coordinate that = (Coordinate) o; + return x == that.x && y == that.y; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } + } + + private static class Scores { + private final int player1Score; + private final int player2Score; + + public Scores(int player1Score, int player2Score) { + this.player1Score = player1Score; + this.player2Score = player2Score; + } + + public int getPlayer1Score() { + return player1Score; + } + + public int getPlayer2Score() { + return player2Score; + } + } + + +} From 961085be483541e6c23a1679e6d08c893d8f1fa5 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 23 Jul 2022 10:00:57 +1000 Subject: [PATCH 12/39] Add text resources --- 30_Cube/csharp/Cube.csproj | 8 ++++ 30_Cube/csharp/Resources/Balance.txt | 1 + 30_Cube/csharp/Resources/Bang.txt | 4 ++ 30_Cube/csharp/Resources/BetAgain.txt | 1 + 30_Cube/csharp/Resources/Bust.txt | 1 + 30_Cube/csharp/Resources/Congratulations.txt | 1 + 30_Cube/csharp/Resources/Goodbye.txt | 3 ++ 30_Cube/csharp/Resources/HowMuch.txt | 1 + 30_Cube/csharp/Resources/IllegalMove.txt | 2 + 30_Cube/csharp/Resources/Instructions.txt | 24 +++++++++++ 30_Cube/csharp/Resources/Introduction.txt | 6 +++ 30_Cube/csharp/Resources/NextMove.txt | 1 + 30_Cube/csharp/Resources/Resource.cs | 44 ++++++++++++++++++++ 30_Cube/csharp/Resources/TryAgain.txt | 1 + 30_Cube/csharp/Resources/Wager.txt | 1 + 30_Cube/csharp/Resources/YourMove.txt | 2 + 16 files changed, 101 insertions(+) create mode 100644 30_Cube/csharp/Resources/Balance.txt create mode 100644 30_Cube/csharp/Resources/Bang.txt create mode 100644 30_Cube/csharp/Resources/BetAgain.txt create mode 100644 30_Cube/csharp/Resources/Bust.txt create mode 100644 30_Cube/csharp/Resources/Congratulations.txt create mode 100644 30_Cube/csharp/Resources/Goodbye.txt create mode 100644 30_Cube/csharp/Resources/HowMuch.txt create mode 100644 30_Cube/csharp/Resources/IllegalMove.txt create mode 100644 30_Cube/csharp/Resources/Instructions.txt create mode 100644 30_Cube/csharp/Resources/Introduction.txt create mode 100644 30_Cube/csharp/Resources/NextMove.txt create mode 100644 30_Cube/csharp/Resources/Resource.cs create mode 100644 30_Cube/csharp/Resources/TryAgain.txt create mode 100644 30_Cube/csharp/Resources/Wager.txt create mode 100644 30_Cube/csharp/Resources/YourMove.txt diff --git a/30_Cube/csharp/Cube.csproj b/30_Cube/csharp/Cube.csproj index d3fe4757..3870320c 100644 --- a/30_Cube/csharp/Cube.csproj +++ b/30_Cube/csharp/Cube.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/30_Cube/csharp/Resources/Balance.txt b/30_Cube/csharp/Resources/Balance.txt new file mode 100644 index 00000000..1f6adffd --- /dev/null +++ b/30_Cube/csharp/Resources/Balance.txt @@ -0,0 +1 @@ +You now have {0} dollars. \ No newline at end of file diff --git a/30_Cube/csharp/Resources/Bang.txt b/30_Cube/csharp/Resources/Bang.txt new file mode 100644 index 00000000..1d924788 --- /dev/null +++ b/30_Cube/csharp/Resources/Bang.txt @@ -0,0 +1,4 @@ +******BANG****** +You lose! + + diff --git a/30_Cube/csharp/Resources/BetAgain.txt b/30_Cube/csharp/Resources/BetAgain.txt new file mode 100644 index 00000000..47c9fb8c --- /dev/null +++ b/30_Cube/csharp/Resources/BetAgain.txt @@ -0,0 +1 @@ +Tried to fool me; bet again \ No newline at end of file diff --git a/30_Cube/csharp/Resources/Bust.txt b/30_Cube/csharp/Resources/Bust.txt new file mode 100644 index 00000000..cd753d98 --- /dev/null +++ b/30_Cube/csharp/Resources/Bust.txt @@ -0,0 +1 @@ +You bust. diff --git a/30_Cube/csharp/Resources/Congratulations.txt b/30_Cube/csharp/Resources/Congratulations.txt new file mode 100644 index 00000000..3319c833 --- /dev/null +++ b/30_Cube/csharp/Resources/Congratulations.txt @@ -0,0 +1 @@ +Congratulations! diff --git a/30_Cube/csharp/Resources/Goodbye.txt b/30_Cube/csharp/Resources/Goodbye.txt new file mode 100644 index 00000000..0aa64192 --- /dev/null +++ b/30_Cube/csharp/Resources/Goodbye.txt @@ -0,0 +1,3 @@ +Tough luck! + +Goodbye. diff --git a/30_Cube/csharp/Resources/HowMuch.txt b/30_Cube/csharp/Resources/HowMuch.txt new file mode 100644 index 00000000..ff2bea20 --- /dev/null +++ b/30_Cube/csharp/Resources/HowMuch.txt @@ -0,0 +1 @@ +How much \ No newline at end of file diff --git a/30_Cube/csharp/Resources/IllegalMove.txt b/30_Cube/csharp/Resources/IllegalMove.txt new file mode 100644 index 00000000..ca8f96ba --- /dev/null +++ b/30_Cube/csharp/Resources/IllegalMove.txt @@ -0,0 +1,2 @@ + +Illegal move. You lose. diff --git a/30_Cube/csharp/Resources/Instructions.txt b/30_Cube/csharp/Resources/Instructions.txt new file mode 100644 index 00000000..e82ae51e --- /dev/null +++ b/30_Cube/csharp/Resources/Instructions.txt @@ -0,0 +1,24 @@ +This is a game in which you will be playing against the +random decision od the computer. The field of play is a +cube of side 3. Any of the 27 locations can be designated +by inputing three numbers such as 2,3,1. At the start, +you are automatically at location 1,1,1. The object of +the game is to get to location 3,3,3. One minor detail: +the computer will pick, at random, 5 locations at which +it will play land mines. If you hit one of these locations +you lose. One other details: you may move only one space +in one direction each move. For example: from 1,1,2 you +may move to 2,1,2 or 1,1,3. You may not change +two of the numbers on the same move. If you make an illegal +move, you lose and the computer takes the money you may +have bet on that round. + + +All Yes or No questions will be answered by a 1 for Yes +or a 0 (zero) for no. + +When stating the amount of a wager, print only the number +of dollars (example: 250) You are automatically started with +500 dollars in your account. + +Good luck! diff --git a/30_Cube/csharp/Resources/Introduction.txt b/30_Cube/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..6299d19b --- /dev/null +++ b/30_Cube/csharp/Resources/Introduction.txt @@ -0,0 +1,6 @@ + Cube + Creative Computing Morristown, New Jersey + + + +Do you want to see the instructions? (Yes--1,No--0) diff --git a/30_Cube/csharp/Resources/NextMove.txt b/30_Cube/csharp/Resources/NextMove.txt new file mode 100644 index 00000000..4cbe5496 --- /dev/null +++ b/30_Cube/csharp/Resources/NextMove.txt @@ -0,0 +1 @@ +Next move: \ No newline at end of file diff --git a/30_Cube/csharp/Resources/Resource.cs b/30_Cube/csharp/Resources/Resource.cs new file mode 100644 index 00000000..c3ed10c7 --- /dev/null +++ b/30_Cube/csharp/Resources/Resource.cs @@ -0,0 +1,44 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Cube.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + public static Stream Instructions => GetStream(); + public static Stream Wager => GetStream(); + public static Stream IllegalMove => GetStream(); + public static Stream Bang => GetStream(); + public static Stream Bust => GetStream(); + public static Stream Congratulations => GetStream(); + public static Stream Goodbye => GetStream(); + } + + internal static class Prompts + { + public static string HowMuch => GetString(); + public static string BetAgain => GetString(); + public static string YourMove => GetString(); + public static string NextMove => GetString(); + public static string TryAgain => GetString(); + } + + internal static class Formats + { + public static string Balance => GetString(); + } + + private static string GetString([CallerMemberName] string? name = null) + { + using var stream = GetStream(name); + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + + private static Stream GetStream([CallerMemberName] string? name = null) => + Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file diff --git a/30_Cube/csharp/Resources/TryAgain.txt b/30_Cube/csharp/Resources/TryAgain.txt new file mode 100644 index 00000000..9ccf358a --- /dev/null +++ b/30_Cube/csharp/Resources/TryAgain.txt @@ -0,0 +1 @@ +Do you want to try again \ No newline at end of file diff --git a/30_Cube/csharp/Resources/Wager.txt b/30_Cube/csharp/Resources/Wager.txt new file mode 100644 index 00000000..04720a7a --- /dev/null +++ b/30_Cube/csharp/Resources/Wager.txt @@ -0,0 +1 @@ +Want to make a wager diff --git a/30_Cube/csharp/Resources/YourMove.txt b/30_Cube/csharp/Resources/YourMove.txt new file mode 100644 index 00000000..5ea0c544 --- /dev/null +++ b/30_Cube/csharp/Resources/YourMove.txt @@ -0,0 +1,2 @@ + +It's your move: \ No newline at end of file From dbeeae81545afb9dbd2d4a27e94445617f8381ee Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 23 Jul 2022 18:31:51 +1000 Subject: [PATCH 13/39] Update readmes --- 30_Cube/README.md | 24 ++++++++++++++++++++++++ 30_Cube/csharp/README.md | 9 +++++++++ 2 files changed, 33 insertions(+) diff --git a/30_Cube/README.md b/30_Cube/README.md index f99366a2..c220c8d4 100644 --- a/30_Cube/README.md +++ b/30_Cube/README.md @@ -16,3 +16,27 @@ http://www.vintage-basic.net/games.html #### Porting Notes (please note any difficulties or challenges in porting here) + +##### Randomization Logic + +The BASIC code uses an interesting technique for choosing the random coordinates for the mines. The first coordinate is +chosen like this: + +```basic +380 LET A=INT(3*(RND(X))) +390 IF A<>0 THEN 410 +400 LET A=3 +``` + +where line 410 is the start of a similar block of code for the next coordinate. The behaviour of `RND(X)` depends on the +value of `X`. If `X` is greater than zero then it returns a random value between 0 and 1. If `X` is zero it returns the +last random value generated, or 0 if no value has yet been generated. + +If `X` is 1, therefore, the first line above set `A` to 0, 1, or 2. The next 2 lines replace a 0 with a 3. The +replacement values varies for the different coordinates with the result that the random selection is biased towards a +specific set of points. If `X` is 0, the `RND` calls all return 0, so the coordinates are the known. It appears that +this technique was probably used to allow testing the game with a well-known set of locations for the mines. However, in +the code as it comes to us, the value of `X` is never set and is thus 0, so the mine locations are never randomized. + +The C# port implements the biased randomized mine locations, as seems to be the original intent, but includes a +command-line switch to enable the deterministic execution as well. diff --git a/30_Cube/csharp/README.md b/30_Cube/csharp/README.md index 4daabb5c..9100e6f8 100644 --- a/30_Cube/csharp/README.md +++ b/30_Cube/csharp/README.md @@ -1,3 +1,12 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) Conversion to [Microsoft C#](https://docs.microsoft.com/en-us/dotnet/csharp/) + +#### Execution + +As noted in the main Readme file, the randomization code in the BASIC program has a switch (the variable `X`) that +allows the game to be run in a deterministic (non-random) mode. + +Running the C# port without command-line parameters will play the game with random mine locations. + +Running the port with a `-d` command-line switch will run the game with non-random mine locations. From d1cf340e9fe626e67ad939e9d8ddb95abc42d285 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 23 Jul 2022 18:42:03 +1000 Subject: [PATCH 14/39] Add Program and Game class --- 30_Cube/csharp/Game.cs | 18 ++++++++++++++++++ 30_Cube/csharp/Program.cs | 8 ++++++++ 2 files changed, 26 insertions(+) create mode 100644 30_Cube/csharp/Game.cs create mode 100644 30_Cube/csharp/Program.cs diff --git a/30_Cube/csharp/Game.cs b/30_Cube/csharp/Game.cs new file mode 100644 index 00000000..f02fa07e --- /dev/null +++ b/30_Cube/csharp/Game.cs @@ -0,0 +1,18 @@ +namespace Cube; + +internal class Game +{ + private readonly IReadWrite _io; + private readonly IRandom _random; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _random = random; + } + + public void Play() + { + _io.Write(Streams.Introduction); + } +} \ No newline at end of file diff --git a/30_Cube/csharp/Program.cs b/30_Cube/csharp/Program.cs new file mode 100644 index 00000000..f22208ac --- /dev/null +++ b/30_Cube/csharp/Program.cs @@ -0,0 +1,8 @@ +global using Games.Common.IO; +global using Games.Common.Randomness; + +global using static Cube.Resources.Resource; + +using Cube; + +new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); From 311eaed39751b20eb49f92bdcbf433b92db4c406 Mon Sep 17 00:00:00 2001 From: Aldrin Misquitta Date: Sun, 24 Jul 2022 07:56:44 +0530 Subject: [PATCH 15/39] Fixes #779 --- 84_Super_Star_Trek/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/84_Super_Star_Trek/README.md b/84_Super_Star_Trek/README.md index 1edeb869..07da653f 100644 --- a/84_Super_Star_Trek/README.md +++ b/84_Super_Star_Trek/README.md @@ -72,7 +72,7 @@ The relation between the Historical and Standard nomenclatures is shown in the s - If you don’t zap a Klingon hard enough (relative to his shield strength) you won’t damage him at all. Your sensors will tell the story. - Damage control will let you know when out-of-commission devices have been completely repaired. -9. Your engines will automatically shit down if you should attempt to leave the galaxy, or if you should try to maneuver through a star, or Starbase, or—heaven help you—a Klingon warship. +9. Your engines will automatically shut down if you should attempt to leave the galaxy, or if you should try to maneuver through a star, or Starbase, or—heaven help you—a Klingon warship. 10. In a pinch, or if you should miscalculate slightly, some shield control energy will be automatically diverted to warp engine control (if your shield are operational!). From ddb120e9cf61d7297c270b5aff0f9ddcdf789dc4 Mon Sep 17 00:00:00 2001 From: Sajid Sarker Date: Sun, 24 Jul 2022 10:00:32 +0430 Subject: [PATCH 16/39] Update life_for_two.py to remove type hinting --- 56_Life_for_Two/python/life_for_two.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/56_Life_for_Two/python/life_for_two.py b/56_Life_for_Two/python/life_for_two.py index fffabc19..dac0bdfc 100644 --- a/56_Life_for_Two/python/life_for_two.py +++ b/56_Life_for_Two/python/life_for_two.py @@ -5,17 +5,14 @@ Competitive Game of Life (two or more players). Ported by Sajid Sarker (2022). ''' - -from typing import List - # Global Variable Initialisation -gn: List[int] = [] -gx: List[int] = [] -gy: List[int] = [] -gk: List[int] = [0, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] -ga: List[int] = [0, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] -m2: int = 0 -m3: int = 0 +gn = [] +gx = [] +gy = [] +gk = [0, 3, 102, 103, 120, 130, 121, 112, 111, 12, 21, 30, 1020, 1030, 1011, 1021, 1003, 1002, 1012] +ga = [0, -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, -1, -1, 1, 1, 1] +m2 = 0 +m3 = 0 # Initialise the board for j in range(6): From 06386a6d5f5dc30d25a07b02b2f35bf18681221c Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sun, 24 Jul 2022 16:36:48 +1000 Subject: [PATCH 17/39] Add command-line switch --- 30_Cube/csharp/Program.cs | 4 +++- 30_Cube/csharp/README.md | 2 +- 30_Cube/csharp/ZerosGenerator.cs | 10 ++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 30_Cube/csharp/ZerosGenerator.cs diff --git a/30_Cube/csharp/Program.cs b/30_Cube/csharp/Program.cs index f22208ac..803a569a 100644 --- a/30_Cube/csharp/Program.cs +++ b/30_Cube/csharp/Program.cs @@ -5,4 +5,6 @@ global using static Cube.Resources.Resource; using Cube; -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); +IRandom random = args.Contains("--non-random") ? new ZerosGenerator() : new RandomNumberGenerator(); + +new Game(new ConsoleIO(), random).Play(); diff --git a/30_Cube/csharp/README.md b/30_Cube/csharp/README.md index 9100e6f8..7bea3d88 100644 --- a/30_Cube/csharp/README.md +++ b/30_Cube/csharp/README.md @@ -9,4 +9,4 @@ allows the game to be run in a deterministic (non-random) mode. Running the C# port without command-line parameters will play the game with random mine locations. -Running the port with a `-d` command-line switch will run the game with non-random mine locations. +Running the port with a `--non-random` command-line switch will run the game with non-random mine locations. diff --git a/30_Cube/csharp/ZerosGenerator.cs b/30_Cube/csharp/ZerosGenerator.cs new file mode 100644 index 00000000..4490f606 --- /dev/null +++ b/30_Cube/csharp/ZerosGenerator.cs @@ -0,0 +1,10 @@ +namespace Cube; + +internal class ZerosGenerator : IRandom +{ + public float NextFloat() => 0; + + public float PreviousFloat() => 0; + + public void Reseed(int seed) { } +} \ No newline at end of file From e6d03771069fa0fb55241ca5cca4ececca226782 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sun, 24 Jul 2022 17:29:26 +1000 Subject: [PATCH 18/39] Add game loops and betting --- 30_Cube/csharp/Game.cs | 40 ++++++++++++++++++++++++++- 30_Cube/csharp/IOExtensions.cs | 20 ++++++++++++++ 30_Cube/csharp/Resources/NextMove.txt | 2 +- 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 30_Cube/csharp/IOExtensions.cs diff --git a/30_Cube/csharp/Game.cs b/30_Cube/csharp/Game.cs index f02fa07e..70ada599 100644 --- a/30_Cube/csharp/Game.cs +++ b/30_Cube/csharp/Game.cs @@ -2,6 +2,7 @@ namespace Cube; internal class Game { + private const int _initialBalance = 500; private readonly IReadWrite _io; private readonly IRandom _random; @@ -14,5 +15,42 @@ internal class Game public void Play() { _io.Write(Streams.Introduction); + + if (_io.ReadNumber("") != 0) + { + _io.Write(Streams.Instructions); + } + + PlaySeries(_initialBalance); + + _io.Write(Streams.Goodbye); } -} \ No newline at end of file + + private void PlaySeries(float balance) + { + while (true) + { + var wager = _io.ReadWager(balance); + + var gameWon = PlayGame(); + + if (wager.HasValue) + { + balance = gameWon ? (balance + wager.Value) : (balance - wager.Value); + if (balance <= 0) + { + _io.Write(Streams.Bust); + return; + } + _io.WriteLine(Formats.Balance, balance); + } + + if (_io.ReadNumber(Prompts.TryAgain) != 1) { return; } + } + } + + private bool PlayGame() + { + return true; + } +} diff --git a/30_Cube/csharp/IOExtensions.cs b/30_Cube/csharp/IOExtensions.cs new file mode 100644 index 00000000..a221ca5d --- /dev/null +++ b/30_Cube/csharp/IOExtensions.cs @@ -0,0 +1,20 @@ +namespace Cube; + +internal static class IOExtensions +{ + internal static float? ReadWager(this IReadWrite io, float balance) + { + io.Write(Streams.Wager); + if (io.ReadNumber("") == 0) { return null; } + + var prompt = Prompts.HowMuch; + + while(true) + { + var wager = io.ReadNumber(prompt); + if (wager <= balance) { return wager; } + + prompt = Prompts.BetAgain; + } + } +} \ No newline at end of file diff --git a/30_Cube/csharp/Resources/NextMove.txt b/30_Cube/csharp/Resources/NextMove.txt index 4cbe5496..2c3c0611 100644 --- a/30_Cube/csharp/Resources/NextMove.txt +++ b/30_Cube/csharp/Resources/NextMove.txt @@ -1 +1 @@ -Next move: \ No newline at end of file +Next move: \ No newline at end of file From 57b1dd099372de195b4fc3a49a1196eb58862dd7 Mon Sep 17 00:00:00 2001 From: Sajid Sarker Date: Sun, 24 Jul 2022 12:35:46 +0430 Subject: [PATCH 19/39] Update life_for_two.py to remove type hinting --- 56_Life_for_Two/python/life_for_two.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/56_Life_for_Two/python/life_for_two.py b/56_Life_for_Two/python/life_for_two.py index dac0bdfc..a4599526 100644 --- a/56_Life_for_Two/python/life_for_two.py +++ b/56_Life_for_Two/python/life_for_two.py @@ -25,7 +25,7 @@ for i in range(3): gy.append(0) # Helper Functions -def tab(number : int) -> str: +def tab(number) -> str: t = "" while len(t) < number: t += " " @@ -127,7 +127,7 @@ def query_player(b) -> None: b = 99 # Game Functions -def check_winner(m2 : int, m3 : int) -> None: +def check_winner(m2, m3) -> None: # Check if the game has been won if m2 == 0 and m3 == 0: print("\nA DRAW\n") From d899b156f49ff7e0954ab406760bf4aff0638313 Mon Sep 17 00:00:00 2001 From: Sajid Sarker Date: Sun, 24 Jul 2022 12:36:50 +0430 Subject: [PATCH 20/39] Update life_for_two.py to remove type hinting --- 56_Life_for_Two/python/life_for_two.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/56_Life_for_Two/python/life_for_two.py b/56_Life_for_Two/python/life_for_two.py index a4599526..a79be546 100644 --- a/56_Life_for_Two/python/life_for_two.py +++ b/56_Life_for_Two/python/life_for_two.py @@ -109,10 +109,10 @@ def query_player(b) -> None: # Query player for symbol placement coordinates while True: print("X,Y\nXXXXXX\n$$$$$$\n&&&&&&") - a_: List[str] = input("??") - b_: List[str] = input("???") - x_: List[int] = [int(num) for num in a_.split() if num.isdigit()] - y_: List[int] = [int(num) for num in b_.split() if num.isdigit()] + a_ = input("??") + b_ = input("???") + x_ = [int(num) for num in a_.split() if num.isdigit()] + y_ = [int(num) for num in b_.split() if num.isdigit()] x_ = [0] if len(x_) == 0 else x_ y_ = [0] if len(y_) == 0 else y_ gx[b] = y_[0] From 7ffa89da08957fabdd96fd0ff6557295dca9a31e Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sun, 24 Jul 2022 18:17:04 +1000 Subject: [PATCH 21/39] Add main game logic --- 30_Cube/csharp/Game.cs | 48 +++++++++++++++++++++++++++ 30_Cube/csharp/IOExtensions.cs | 2 +- 30_Cube/csharp/RandomExtensions.cs | 14 ++++++++ 30_Cube/csharp/Resources/NextMove.txt | 2 +- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 30_Cube/csharp/RandomExtensions.cs diff --git a/30_Cube/csharp/Game.cs b/30_Cube/csharp/Game.cs index 70ada599..a06ec565 100644 --- a/30_Cube/csharp/Game.cs +++ b/30_Cube/csharp/Game.cs @@ -3,6 +3,13 @@ namespace Cube; internal class Game { private const int _initialBalance = 500; + private readonly IEnumerable<(int, int, int)> _seeds = new List<(int, int, int)> + { + (3, 2, 3), (1, 3, 3), (3, 3, 2), (3, 2, 3), (3, 1, 3) + }; + private readonly (float, float, float) _startLocation = (1, 1, 1); + private readonly (float, float, float) _goalLocation = (3, 3, 3); + private readonly IReadWrite _io; private readonly IRandom _random; @@ -51,6 +58,47 @@ internal class Game private bool PlayGame() { + var mineLocations = _seeds.Select(seed => _random.NextLocation(seed)).ToHashSet(); + var currentLocation = _startLocation; + var prompt = Prompts.YourMove; + + while (true) + { + var newLocation = _io.Read3Numbers(prompt); + + if (!MoveIsLegal(currentLocation, newLocation)) { return Lose(Streams.IllegalMove); } + + currentLocation = newLocation; + + if (currentLocation == _goalLocation) { return Win(Streams.Congratulations); } + + if (mineLocations.Contains(currentLocation)) { return Lose(Streams.Bang); } + + prompt = Prompts.NextMove; + } + } + + private bool Lose(Stream text) + { + _io.Write(text); + return false; + } + + private bool Win(Stream text) + { + _io.Write(text); return true; } + + private bool MoveIsLegal((float, float, float) from, (float, float, float) to) + => (to.Item1 - from.Item1, to.Item2 - from.Item2, to.Item3 - from.Item3) switch + { + ( > 1, _, _) => false, + (_, > 1, _) => false, + (_, _, > 1) => false, + (1, 1, _) => false, + (1, _, 1) => false, + (_, 1, 1) => false, + _ => true + }; } diff --git a/30_Cube/csharp/IOExtensions.cs b/30_Cube/csharp/IOExtensions.cs index a221ca5d..14f2a85e 100644 --- a/30_Cube/csharp/IOExtensions.cs +++ b/30_Cube/csharp/IOExtensions.cs @@ -17,4 +17,4 @@ internal static class IOExtensions prompt = Prompts.BetAgain; } } -} \ No newline at end of file +} diff --git a/30_Cube/csharp/RandomExtensions.cs b/30_Cube/csharp/RandomExtensions.cs new file mode 100644 index 00000000..ac05108e --- /dev/null +++ b/30_Cube/csharp/RandomExtensions.cs @@ -0,0 +1,14 @@ +namespace Cube; + +internal static class RandomExtensions +{ + internal static (float, float, float) NextLocation(this IRandom random, (int, int, int) bias) + => (random.NextCoordinate(bias.Item1), random.NextCoordinate(bias.Item2), random.NextCoordinate(bias.Item3)); + + private static float NextCoordinate(this IRandom random, int bias) + { + var value = random.Next(3); + if (value == 0) { value = bias; } + return value; + } +} \ No newline at end of file diff --git a/30_Cube/csharp/Resources/NextMove.txt b/30_Cube/csharp/Resources/NextMove.txt index 2c3c0611..4cbe5496 100644 --- a/30_Cube/csharp/Resources/NextMove.txt +++ b/30_Cube/csharp/Resources/NextMove.txt @@ -1 +1 @@ -Next move: \ No newline at end of file +Next move: \ No newline at end of file From 842f749db5c67879b2df2f99cb9a155b75bdce04 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sun, 24 Jul 2022 21:33:10 +1000 Subject: [PATCH 22/39] Add string resources --- 32_Diamond/csharp/Diamond.csproj | 8 ++++++ 32_Diamond/csharp/Resources/Introduction.txt | 5 ++++ 32_Diamond/csharp/Resources/Resource.cs | 29 ++++++++++++++++++++ 32_Diamond/csharp/Resources/Rules.txt | 22 +++++++++++++++ 32_Diamond/csharp/Resources/TypeNumber.txt | 2 ++ 5 files changed, 66 insertions(+) create mode 100644 32_Diamond/csharp/Resources/Introduction.txt create mode 100644 32_Diamond/csharp/Resources/Resource.cs create mode 100644 32_Diamond/csharp/Resources/Rules.txt create mode 100644 32_Diamond/csharp/Resources/TypeNumber.txt diff --git a/32_Diamond/csharp/Diamond.csproj b/32_Diamond/csharp/Diamond.csproj index d3fe4757..3870320c 100644 --- a/32_Diamond/csharp/Diamond.csproj +++ b/32_Diamond/csharp/Diamond.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/32_Diamond/csharp/Resources/Introduction.txt b/32_Diamond/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..e983fc9f --- /dev/null +++ b/32_Diamond/csharp/Resources/Introduction.txt @@ -0,0 +1,5 @@ + Diamond + Creative Computing Morristown, New Jersey + + + diff --git a/32_Diamond/csharp/Resources/Resource.cs b/32_Diamond/csharp/Resources/Resource.cs new file mode 100644 index 00000000..d7051f5c --- /dev/null +++ b/32_Diamond/csharp/Resources/Resource.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Diamond.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + } + + internal static class Prompts + { + public static string TypeNumber => GetString(); + } + + private static string GetString([CallerMemberName] string? name = null) + { + using var stream = GetStream(name); + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + + + private static Stream GetStream([CallerMemberName] string? name = null) => + Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file diff --git a/32_Diamond/csharp/Resources/Rules.txt b/32_Diamond/csharp/Resources/Rules.txt new file mode 100644 index 00000000..2fd9177f --- /dev/null +++ b/32_Diamond/csharp/Resources/Rules.txt @@ -0,0 +1,22 @@ +Chomp is for 1 or more players (humans only). + +Here's how a board looks (this one is 5 by 7): + + 1 2 3 4 5 6 7 8 9 + 1 P * * * * * * + 2 * * * * * * * + 3 * * * * * * * + 4 * * * * * * * + 5 * * * * * * * + + +The board is a big cookie - R rows high and C columns +wide. You input R and C at the start. In the upper left +corner of the cookie is a poison square (P). The one who +chomps the poison square loses. To take a chomp, type the +row and column of one of the squares on the cookie. +All of the squares below and to the right of that square +(including that square, too) disappear -- Chomp!! +No fair chomping on squares that have already been chomped, +or that are outside the original dimensions of the cookie. + diff --git a/32_Diamond/csharp/Resources/TypeNumber.txt b/32_Diamond/csharp/Resources/TypeNumber.txt new file mode 100644 index 00000000..d74d21fd --- /dev/null +++ b/32_Diamond/csharp/Resources/TypeNumber.txt @@ -0,0 +1,2 @@ +For a pretty diamond pattern, +type in an odd number between 5 and 21 \ No newline at end of file From 13e0e260b7d858b4a25ba429381fe6a4ec131f67 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sun, 24 Jul 2022 22:30:35 +1000 Subject: [PATCH 23/39] Add progam logic --- 32_Diamond/csharp/Pattern.cs | 57 ++++++++++++++++++++ 32_Diamond/csharp/Program.cs | 4 ++ 32_Diamond/csharp/StringBuilderExtensions.cs | 9 ++++ 3 files changed, 70 insertions(+) create mode 100644 32_Diamond/csharp/Pattern.cs create mode 100644 32_Diamond/csharp/Program.cs create mode 100644 32_Diamond/csharp/StringBuilderExtensions.cs diff --git a/32_Diamond/csharp/Pattern.cs b/32_Diamond/csharp/Pattern.cs new file mode 100644 index 00000000..ce6d493a --- /dev/null +++ b/32_Diamond/csharp/Pattern.cs @@ -0,0 +1,57 @@ +using System.Text; +using static Diamond.Resources.Resource; + +namespace Diamond; + +internal class Pattern +{ + private readonly IReadWrite _io; + + public Pattern(IReadWrite io) + { + _io = io; + io.Write(Streams.Introduction); + } + + public void Draw() + { + var diamondSize = _io.ReadNumber(Prompts.TypeNumber); + _io.WriteLine(); + + var diamondCount = (int)(60 / diamondSize); + + var diamondLines = new List(GetDiamondLines(diamondSize)).AsReadOnly(); + + for (int patternRow = 0; patternRow < diamondCount; patternRow++) + { + for (int diamondRow = 0; diamondRow < diamondLines.Count; diamondRow++) + { + var line = new StringBuilder(); + for (int patternColumn = 0; patternColumn < diamondCount; patternColumn++) + { + line.PadToLength((int)(patternColumn * diamondSize)).Append(diamondLines[diamondRow]); + } + _io.WriteLine(line); + } + } + } + + public static IEnumerable GetDiamondLines(float size) + { + for (var i = 1; i <= size; i += 2) + { + yield return GetLine(i); + } + + for (var i = size - 2; i >= 1; i -= 2) + { + yield return GetLine(i); + } + + string GetLine(float i) => + string.Concat( + new string(' ', (int)(size - i) / 2), + new string('C', Math.Min((int)i, 2)), + new string('!', Math.Max(0, (int)i - 2))); + } +} diff --git a/32_Diamond/csharp/Program.cs b/32_Diamond/csharp/Program.cs new file mode 100644 index 00000000..46dd67c5 --- /dev/null +++ b/32_Diamond/csharp/Program.cs @@ -0,0 +1,4 @@ +global using Games.Common.IO; +using Diamond; + +new Pattern(new ConsoleIO()).Draw(); diff --git a/32_Diamond/csharp/StringBuilderExtensions.cs b/32_Diamond/csharp/StringBuilderExtensions.cs new file mode 100644 index 00000000..3ada4146 --- /dev/null +++ b/32_Diamond/csharp/StringBuilderExtensions.cs @@ -0,0 +1,9 @@ +using System.Text; + +namespace Diamond; + +internal static class StringBuilderExtensions +{ + internal static StringBuilder PadToLength(this StringBuilder builder, int length) => + builder.Append(' ', length - builder.Length); +} \ No newline at end of file From a2dc514955804336f0ebbe0839ac5e9617f9c287 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 28 Jul 2022 22:09:57 +1000 Subject: [PATCH 24/39] Add text resources --- 34_Digits/csharp/Digits.csproj | 8 ++++ .../csharp/Resources/ForInstructions.txt | 1 + 34_Digits/csharp/Resources/Headings.txt | 1 + 34_Digits/csharp/Resources/IWin.txt | 3 ++ 34_Digits/csharp/Resources/Instructions.txt | 11 +++++ 34_Digits/csharp/Resources/Introduction.txt | 6 +++ 34_Digits/csharp/Resources/ItsATie.txt | 3 ++ 34_Digits/csharp/Resources/Resource.cs | 44 +++++++++++++++++++ 34_Digits/csharp/Resources/TenNumbers.txt | 1 + 34_Digits/csharp/Resources/Thanks.txt | 2 + 34_Digits/csharp/Resources/TryAgain.txt | 2 + 34_Digits/csharp/Resources/WantToTryAgain.txt | 1 + 34_Digits/csharp/Resources/YouWin.txt | 3 ++ 13 files changed, 86 insertions(+) create mode 100644 34_Digits/csharp/Resources/ForInstructions.txt create mode 100644 34_Digits/csharp/Resources/Headings.txt create mode 100644 34_Digits/csharp/Resources/IWin.txt create mode 100644 34_Digits/csharp/Resources/Instructions.txt create mode 100644 34_Digits/csharp/Resources/Introduction.txt create mode 100644 34_Digits/csharp/Resources/ItsATie.txt create mode 100644 34_Digits/csharp/Resources/Resource.cs create mode 100644 34_Digits/csharp/Resources/TenNumbers.txt create mode 100644 34_Digits/csharp/Resources/Thanks.txt create mode 100644 34_Digits/csharp/Resources/TryAgain.txt create mode 100644 34_Digits/csharp/Resources/WantToTryAgain.txt create mode 100644 34_Digits/csharp/Resources/YouWin.txt diff --git a/34_Digits/csharp/Digits.csproj b/34_Digits/csharp/Digits.csproj index d3fe4757..3870320c 100644 --- a/34_Digits/csharp/Digits.csproj +++ b/34_Digits/csharp/Digits.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/34_Digits/csharp/Resources/ForInstructions.txt b/34_Digits/csharp/Resources/ForInstructions.txt new file mode 100644 index 00000000..1c16d5f4 --- /dev/null +++ b/34_Digits/csharp/Resources/ForInstructions.txt @@ -0,0 +1 @@ +For instructions, type '1', else type '0' \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Headings.txt b/34_Digits/csharp/Resources/Headings.txt new file mode 100644 index 00000000..b9ece8ff --- /dev/null +++ b/34_Digits/csharp/Resources/Headings.txt @@ -0,0 +1 @@ +My guess Your no. Result No. right diff --git a/34_Digits/csharp/Resources/IWin.txt b/34_Digits/csharp/Resources/IWin.txt new file mode 100644 index 00000000..d810c60f --- /dev/null +++ b/34_Digits/csharp/Resources/IWin.txt @@ -0,0 +1,3 @@ +I guessed more than 1/3 of your numbers. +I win. + diff --git a/34_Digits/csharp/Resources/Instructions.txt b/34_Digits/csharp/Resources/Instructions.txt new file mode 100644 index 00000000..f9ff2a16 --- /dev/null +++ b/34_Digits/csharp/Resources/Instructions.txt @@ -0,0 +1,11 @@ + +Please take a piece of paper and write down +the digits '0', '1', or '2' thirty times at random. +Arrange them in three lines of ten digits each. +I will ask for then ten at a time. +I will always guess them first and then look at your +next number to see if I was right. By pure luck, +I ought to be right ten times. But I hope to do better +than that ***** + + diff --git a/34_Digits/csharp/Resources/Introduction.txt b/34_Digits/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..e4d2d93e --- /dev/null +++ b/34_Digits/csharp/Resources/Introduction.txt @@ -0,0 +1,6 @@ + Digits + Creative Computing Morristown, New Jersey + + + +This is a game of guessing. diff --git a/34_Digits/csharp/Resources/ItsATie.txt b/34_Digits/csharp/Resources/ItsATie.txt new file mode 100644 index 00000000..e80525f8 --- /dev/null +++ b/34_Digits/csharp/Resources/ItsATie.txt @@ -0,0 +1,3 @@ +I guessed exactly 1/3 of your numbers. +It's a tie game. + diff --git a/34_Digits/csharp/Resources/Resource.cs b/34_Digits/csharp/Resources/Resource.cs new file mode 100644 index 00000000..7252c817 --- /dev/null +++ b/34_Digits/csharp/Resources/Resource.cs @@ -0,0 +1,44 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Chomp.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + public static Stream Instructions => GetStream(); + public static Stream TryAgain => GetStream(); + public static Stream ItsATie => GetStream(); + public static Stream IWin => GetStream(); + public static Stream YouWin => GetStream(); + public static Stream Thanks => GetStream(); + public static Stream Headings => GetStream(); + } + + internal static class Prompts + { + public static string ForInstructions => GetString(); + public static string TenNumbers => GetString(); + public static string WantToTryAgain => GetString(); + } + + internal static class Strings + { + public static string TooManyColumns => GetString(); + public static string TooManyRows => GetString(); + } + + private static string GetString([CallerMemberName] string? name = null) + { + using var stream = GetStream(name); + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + + + private static Stream GetStream([CallerMemberName] string? name = null) => + Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file diff --git a/34_Digits/csharp/Resources/TenNumbers.txt b/34_Digits/csharp/Resources/TenNumbers.txt new file mode 100644 index 00000000..5286066b --- /dev/null +++ b/34_Digits/csharp/Resources/TenNumbers.txt @@ -0,0 +1 @@ +Ten numbers, please \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Thanks.txt b/34_Digits/csharp/Resources/Thanks.txt new file mode 100644 index 00000000..15d42e1b --- /dev/null +++ b/34_Digits/csharp/Resources/Thanks.txt @@ -0,0 +1,2 @@ + +Thanks for the game diff --git a/34_Digits/csharp/Resources/TryAgain.txt b/34_Digits/csharp/Resources/TryAgain.txt new file mode 100644 index 00000000..74bdca68 --- /dev/null +++ b/34_Digits/csharp/Resources/TryAgain.txt @@ -0,0 +1,2 @@ +Only use the digits '0', '1', or '2'. +Let's try again. diff --git a/34_Digits/csharp/Resources/WantToTryAgain.txt b/34_Digits/csharp/Resources/WantToTryAgain.txt new file mode 100644 index 00000000..38f4509d --- /dev/null +++ b/34_Digits/csharp/Resources/WantToTryAgain.txt @@ -0,0 +1 @@ +Do you want to try again (1 for yes, 0 for no) \ No newline at end of file diff --git a/34_Digits/csharp/Resources/YouWin.txt b/34_Digits/csharp/Resources/YouWin.txt new file mode 100644 index 00000000..120997d4 --- /dev/null +++ b/34_Digits/csharp/Resources/YouWin.txt @@ -0,0 +1,3 @@ +I guessed less than 1/3 of your numbers. +You beat me. Congratulations ***** + From aedfd73e8c5f7a1a85d80391f49500708aa4555c Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 30 Jul 2022 16:19:50 +1000 Subject: [PATCH 25/39] Add main game loop --- 34_Digits/csharp/Game.cs | 36 ++++++++++++++++++++++++++ 34_Digits/csharp/Program.cs | 6 +++++ 34_Digits/csharp/Resources/Resource.cs | 8 +----- 3 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 34_Digits/csharp/Game.cs create mode 100644 34_Digits/csharp/Program.cs diff --git a/34_Digits/csharp/Game.cs b/34_Digits/csharp/Game.cs new file mode 100644 index 00000000..2ddab01d --- /dev/null +++ b/34_Digits/csharp/Game.cs @@ -0,0 +1,36 @@ +namespace Digits +{ + internal class Game + { + private readonly IReadWrite _io; + private readonly IRandom _random; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _random = random; + } + + internal void Play() + { + _io.Write(Streams.Introduction); + + if (_io.ReadNumber(Prompts.ForInstructions) != 0) + { + _io.Write(Streams.Instructions); + } + + do + { + PlayOne(); + } while (_io.ReadNumber(Prompts.WantToTryAgain) == 1); + + _io.Write(Streams.Thanks); + } + + private void PlayOne() + { + + } + } +} \ No newline at end of file diff --git a/34_Digits/csharp/Program.cs b/34_Digits/csharp/Program.cs new file mode 100644 index 00000000..a427b3c8 --- /dev/null +++ b/34_Digits/csharp/Program.cs @@ -0,0 +1,6 @@ +global using Digits; +global using Games.Common.IO; +global using Games.Common.Randomness; +global using static Digits.Resources.Resource; + +new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Resource.cs b/34_Digits/csharp/Resources/Resource.cs index 7252c817..0a939802 100644 --- a/34_Digits/csharp/Resources/Resource.cs +++ b/34_Digits/csharp/Resources/Resource.cs @@ -1,7 +1,7 @@ using System.Reflection; using System.Runtime.CompilerServices; -namespace Chomp.Resources; +namespace Digits.Resources; internal static class Resource { @@ -24,12 +24,6 @@ internal static class Resource public static string WantToTryAgain => GetString(); } - internal static class Strings - { - public static string TooManyColumns => GetString(); - public static string TooManyRows => GetString(); - } - private static string GetString([CallerMemberName] string? name = null) { using var stream = GetStream(name); From 572b9b3a695d8a893542138f3c62773fba978b9b Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 3 Aug 2022 08:40:05 +1000 Subject: [PATCH 26/39] Complete game --- 34_Digits/csharp/Game.cs | 110 ++++++++++++++------- 34_Digits/csharp/Guesser.cs | 52 ++++++++++ 34_Digits/csharp/IOExtensions.cs | 20 ++++ 34_Digits/csharp/Program.cs | 2 +- 34_Digits/csharp/Resources/GuessResult.txt | 1 + 34_Digits/csharp/Resources/Headings.txt | 2 + 34_Digits/csharp/Resources/Resource.cs | 5 + 34_Digits/csharp/Resources/TenNumbers.txt | 1 + 8 files changed, 159 insertions(+), 34 deletions(-) create mode 100644 34_Digits/csharp/Guesser.cs create mode 100644 34_Digits/csharp/IOExtensions.cs create mode 100644 34_Digits/csharp/Resources/GuessResult.txt diff --git a/34_Digits/csharp/Game.cs b/34_Digits/csharp/Game.cs index 2ddab01d..19f225b3 100644 --- a/34_Digits/csharp/Game.cs +++ b/34_Digits/csharp/Game.cs @@ -1,36 +1,80 @@ -namespace Digits +namespace Digits; + +internal class GameSeries { - internal class Game + private readonly IReadOnlyList _weights = new List { 0, 1, 3 }.AsReadOnly(); + + private readonly IReadWrite _io; + private readonly IRandom _random; + + public GameSeries(IReadWrite io, IRandom random) { - private readonly IReadWrite _io; - private readonly IRandom _random; - - public Game(IReadWrite io, IRandom random) - { - _io = io; - _random = random; - } - - internal void Play() - { - _io.Write(Streams.Introduction); - - if (_io.ReadNumber(Prompts.ForInstructions) != 0) - { - _io.Write(Streams.Instructions); - } - - do - { - PlayOne(); - } while (_io.ReadNumber(Prompts.WantToTryAgain) == 1); - - _io.Write(Streams.Thanks); - } - - private void PlayOne() - { - - } + _io = io; + _random = random; } -} \ No newline at end of file + + internal void Play() + { + _io.Write(Streams.Introduction); + + if (_io.ReadNumber(Prompts.ForInstructions) != 0) + { + _io.Write(Streams.Instructions); + } + + do + { + new Game(_io, _random).Play(); + } while (_io.ReadNumber(Prompts.WantToTryAgain) == 1); + + _io.Write(Streams.Thanks); + } +} + +internal class Game +{ + private readonly IReadWrite _io; + private readonly Guesser _guesser; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _guesser = new Guesser(random); + } + + public void Play() + { + var correctGuesses = 0; + + for (int round = 0; round < 3; round++) + { + var digits = _io.Read10Digits(Prompts.TenNumbers, Streams.TryAgain); + + correctGuesses = GuessDigits(digits, correctGuesses); + } + + _io.Write(correctGuesses switch + { + < 10 => Streams.YouWin, + 10 => Streams.ItsATie, + > 10 => Streams.IWin + }); + } + + private int GuessDigits(IEnumerable digits, int correctGuesses) + { + _io.Write(Streams.Headings); + + foreach (var digit in digits) + { + var guess = _guesser.GuessNextDigit(); + if (guess == digit) { correctGuesses++; } + + _io.WriteLine(Formats.GuessResult, guess, digit, guess == digit ? "Right" : "Wrong", correctGuesses); + + _guesser.ObserveActualDigit(digit); + } + + return correctGuesses; + } +} diff --git a/34_Digits/csharp/Guesser.cs b/34_Digits/csharp/Guesser.cs new file mode 100644 index 00000000..debeed18 --- /dev/null +++ b/34_Digits/csharp/Guesser.cs @@ -0,0 +1,52 @@ +namespace Digits; + +internal class Guesser +{ + private readonly IReadOnlyList _weights = new List { 0, 1, 3 }.AsReadOnly(); + private readonly int[][,] _matrices = new[] { new int[3, 3], new int[9, 3], new int[27, 3] }; + private readonly int[] _indices = new[] { 2, 8, 26 }; + private readonly IRandom _random; + + public Guesser(IRandom random) + { + _random = random; + + for (int j = 0; j < 3; j++) + { + for (int i = 0; i < 3; i++) { _matrices[0][i, j] = 9; } + for (int i = 0; i < 9; i++) { _matrices[1][i, j] = i == 4 * j ? 2 : 3; } + for (int i = 0; i < 27; i++) { _matrices[2][i, j] = 1; } + } + } + + public int GuessNextDigit() + { + var currentSum = 0; + var guess = 0; + + for (int j = 0; j < 3; j++) + { + var sum = Enumerable.Range(0, 3).Aggregate((s, i) => s + GetWeightedValue(i, j)); + if (sum > currentSum || _random.NextFloat() >= 0.5) + { + currentSum = sum; + guess = j; + } + } + + return guess; + } + + public void ObserveActualDigit(int digit) + { + for (int i = 0; i < 3; i++) + { + _matrices[i][_indices[i], digit]++; + } + _indices[2] = _indices[2] % 9 * 3 + digit; + _indices[1] = _indices[2] % 9; + _indices[0] = digit; + } + + private int GetWeightedValue(int matrix, int row) => _weights[matrix] * _matrices[matrix][_indices[matrix], row]; +} \ No newline at end of file diff --git a/34_Digits/csharp/IOExtensions.cs b/34_Digits/csharp/IOExtensions.cs new file mode 100644 index 00000000..cd6af7ad --- /dev/null +++ b/34_Digits/csharp/IOExtensions.cs @@ -0,0 +1,20 @@ +namespace Digits; + +internal static class IOExtensions +{ + internal static IEnumerable Read10Digits(this IReadWrite io, string prompt, Stream retryText) + { + while (true) + { + var numbers = new float[10]; + io.ReadNumbers(prompt, numbers); + + if (numbers.All(n => n == 0 || n == 1 || n == 2)) + { + return numbers.Select(n => (int)n); + } + + io.Write(retryText); + } + } +} \ No newline at end of file diff --git a/34_Digits/csharp/Program.cs b/34_Digits/csharp/Program.cs index a427b3c8..1b5dd2e0 100644 --- a/34_Digits/csharp/Program.cs +++ b/34_Digits/csharp/Program.cs @@ -3,4 +3,4 @@ global using Games.Common.IO; global using Games.Common.Randomness; global using static Digits.Resources.Resource; -new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); \ No newline at end of file +new GameSeries(new ConsoleIO(), new RandomNumberGenerator()).Play(); \ No newline at end of file diff --git a/34_Digits/csharp/Resources/GuessResult.txt b/34_Digits/csharp/Resources/GuessResult.txt new file mode 100644 index 00000000..4e233e03 --- /dev/null +++ b/34_Digits/csharp/Resources/GuessResult.txt @@ -0,0 +1 @@ + {0} {1} {2} {3} \ No newline at end of file diff --git a/34_Digits/csharp/Resources/Headings.txt b/34_Digits/csharp/Resources/Headings.txt index b9ece8ff..8289cdf6 100644 --- a/34_Digits/csharp/Resources/Headings.txt +++ b/34_Digits/csharp/Resources/Headings.txt @@ -1 +1,3 @@ + My guess Your no. Result No. right + diff --git a/34_Digits/csharp/Resources/Resource.cs b/34_Digits/csharp/Resources/Resource.cs index 0a939802..2e935955 100644 --- a/34_Digits/csharp/Resources/Resource.cs +++ b/34_Digits/csharp/Resources/Resource.cs @@ -24,6 +24,11 @@ internal static class Resource public static string WantToTryAgain => GetString(); } + internal static class Formats + { + public static string GuessResult => GetString(); + } + private static string GetString([CallerMemberName] string? name = null) { using var stream = GetStream(name); diff --git a/34_Digits/csharp/Resources/TenNumbers.txt b/34_Digits/csharp/Resources/TenNumbers.txt index 5286066b..ad03893a 100644 --- a/34_Digits/csharp/Resources/TenNumbers.txt +++ b/34_Digits/csharp/Resources/TenNumbers.txt @@ -1 +1,2 @@ + Ten numbers, please \ No newline at end of file From b67a5d438c2794916e40690a86945b145b693767 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Wed, 3 Aug 2022 23:34:02 +1000 Subject: [PATCH 27/39] Add Memory and Matrix --- 34_Digits/csharp/Guesser.cs | 32 +++++--------------------- 34_Digits/csharp/Matrix.cs | 27 ++++++++++++++++++++++ 34_Digits/csharp/Memory.cs | 30 ++++++++++++++++++++++++ 34_Digits/csharp/Resources/IWin.txt | 1 + 34_Digits/csharp/Resources/ItsATie.txt | 1 + 34_Digits/csharp/Resources/YouWin.txt | 1 + 6 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 34_Digits/csharp/Matrix.cs create mode 100644 34_Digits/csharp/Memory.cs diff --git a/34_Digits/csharp/Guesser.cs b/34_Digits/csharp/Guesser.cs index debeed18..9cda59e9 100644 --- a/34_Digits/csharp/Guesser.cs +++ b/34_Digits/csharp/Guesser.cs @@ -2,21 +2,12 @@ namespace Digits; internal class Guesser { - private readonly IReadOnlyList _weights = new List { 0, 1, 3 }.AsReadOnly(); - private readonly int[][,] _matrices = new[] { new int[3, 3], new int[9, 3], new int[27, 3] }; - private readonly int[] _indices = new[] { 2, 8, 26 }; + private readonly Memory _matrices = new(); private readonly IRandom _random; public Guesser(IRandom random) { _random = random; - - for (int j = 0; j < 3; j++) - { - for (int i = 0; i < 3; i++) { _matrices[0][i, j] = 9; } - for (int i = 0; i < 9; i++) { _matrices[1][i, j] = i == 4 * j ? 2 : 3; } - for (int i = 0; i < 27; i++) { _matrices[2][i, j] = 1; } - } } public int GuessNextDigit() @@ -24,29 +15,18 @@ internal class Guesser var currentSum = 0; var guess = 0; - for (int j = 0; j < 3; j++) + for (int i = 0; i < 3; i++) { - var sum = Enumerable.Range(0, 3).Aggregate((s, i) => s + GetWeightedValue(i, j)); + var sum = _matrices.GetWeightedSum(i); if (sum > currentSum || _random.NextFloat() >= 0.5) { currentSum = sum; - guess = j; + guess = i; } } return guess; } - public void ObserveActualDigit(int digit) - { - for (int i = 0; i < 3; i++) - { - _matrices[i][_indices[i], digit]++; - } - _indices[2] = _indices[2] % 9 * 3 + digit; - _indices[1] = _indices[2] % 9; - _indices[0] = digit; - } - - private int GetWeightedValue(int matrix, int row) => _weights[matrix] * _matrices[matrix][_indices[matrix], row]; -} \ No newline at end of file + public void ObserveActualDigit(int digit) => _matrices.ObserveDigit(digit); +} diff --git a/34_Digits/csharp/Matrix.cs b/34_Digits/csharp/Matrix.cs new file mode 100644 index 00000000..c07b4553 --- /dev/null +++ b/34_Digits/csharp/Matrix.cs @@ -0,0 +1,27 @@ +namespace Digits; + +internal class Matrix +{ + private readonly int _weight; + private readonly int[,] _values; + + public Matrix(int width, int weight, Func seedFactory) + { + _weight = weight; + _values = new int[width, 3]; + + for (int i = 0; i < width; i++) + for (int j = 0; j < 3; j++) + { + _values[i, j] = seedFactory.Invoke(i, j); + } + + Index = width - 1; + } + + public int Index { get; set; } + + public int GetWeightedValue(int row) => _weight * _values[Index, row]; + + public int IncrementValue(int row) => _values[Index, row]++; +} \ No newline at end of file diff --git a/34_Digits/csharp/Memory.cs b/34_Digits/csharp/Memory.cs new file mode 100644 index 00000000..a3023351 --- /dev/null +++ b/34_Digits/csharp/Memory.cs @@ -0,0 +1,30 @@ +namespace Digits; + +public class Memory +{ + private readonly Matrix[] _matrices; + + public Memory() + { + _matrices = new[] + { + new Matrix(27, 3, (_, _) => 1), + new Matrix(9, 1, (i, j) => i == 4 * j ? 2 : 3), + new Matrix(3, 0, (_, _) => 9) + }; + } + + public int GetWeightedSum(int row) => _matrices.Select(m => m.GetWeightedValue(row)).Sum(); + + public void ObserveDigit(int digit) + { + for (int i = 0; i < 3; i++) + { + _matrices[i].IncrementValue(digit); + } + + _matrices[0].Index = _matrices[0].Index % 9 * 3 + digit; + _matrices[1].Index = _matrices[0].Index % 9; + _matrices[2].Index = digit; + } +} \ No newline at end of file diff --git a/34_Digits/csharp/Resources/IWin.txt b/34_Digits/csharp/Resources/IWin.txt index d810c60f..491f69cf 100644 --- a/34_Digits/csharp/Resources/IWin.txt +++ b/34_Digits/csharp/Resources/IWin.txt @@ -1,3 +1,4 @@ + I guessed more than 1/3 of your numbers. I win. diff --git a/34_Digits/csharp/Resources/ItsATie.txt b/34_Digits/csharp/Resources/ItsATie.txt index e80525f8..0e92fbf6 100644 --- a/34_Digits/csharp/Resources/ItsATie.txt +++ b/34_Digits/csharp/Resources/ItsATie.txt @@ -1,3 +1,4 @@ + I guessed exactly 1/3 of your numbers. It's a tie game. diff --git a/34_Digits/csharp/Resources/YouWin.txt b/34_Digits/csharp/Resources/YouWin.txt index 120997d4..87b26b38 100644 --- a/34_Digits/csharp/Resources/YouWin.txt +++ b/34_Digits/csharp/Resources/YouWin.txt @@ -1,3 +1,4 @@ + I guessed less than 1/3 of your numbers. You beat me. Congratulations ***** From 7ab0e91c1f117338c06149d75e4b9bc2764aad4d Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 12 Aug 2022 17:28:49 +1000 Subject: [PATCH 28/39] Add resource strings --- 67_One_Check/csharp/OneCheck.csproj | 8 ++++ 67_One_Check/csharp/Resources/Bye.txt | 2 + 67_One_Check/csharp/Resources/From.txt | 1 + 67_One_Check/csharp/Resources/IllegalMove.txt | 1 + .../csharp/Resources/Introduction.txt | 29 ++++++++++++ 67_One_Check/csharp/Resources/Resource.cs | 45 +++++++++++++++++++ 67_One_Check/csharp/Resources/Results.txt | 4 ++ 67_One_Check/csharp/Resources/To.txt | 1 + 67_One_Check/csharp/Resources/TryAgain.txt | 1 + 67_One_Check/csharp/Resources/YesOrNo.txt | 1 + 10 files changed, 93 insertions(+) create mode 100644 67_One_Check/csharp/Resources/Bye.txt create mode 100644 67_One_Check/csharp/Resources/From.txt create mode 100644 67_One_Check/csharp/Resources/IllegalMove.txt create mode 100644 67_One_Check/csharp/Resources/Introduction.txt create mode 100644 67_One_Check/csharp/Resources/Resource.cs create mode 100644 67_One_Check/csharp/Resources/Results.txt create mode 100644 67_One_Check/csharp/Resources/To.txt create mode 100644 67_One_Check/csharp/Resources/TryAgain.txt create mode 100644 67_One_Check/csharp/Resources/YesOrNo.txt diff --git a/67_One_Check/csharp/OneCheck.csproj b/67_One_Check/csharp/OneCheck.csproj index d3fe4757..3870320c 100644 --- a/67_One_Check/csharp/OneCheck.csproj +++ b/67_One_Check/csharp/OneCheck.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/67_One_Check/csharp/Resources/Bye.txt b/67_One_Check/csharp/Resources/Bye.txt new file mode 100644 index 00000000..ee4ddab1 --- /dev/null +++ b/67_One_Check/csharp/Resources/Bye.txt @@ -0,0 +1,2 @@ + +O.K. Hope you had fun!! \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/From.txt b/67_One_Check/csharp/Resources/From.txt new file mode 100644 index 00000000..bb4c7a2d --- /dev/null +++ b/67_One_Check/csharp/Resources/From.txt @@ -0,0 +1 @@ +Jump from \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/IllegalMove.txt b/67_One_Check/csharp/Resources/IllegalMove.txt new file mode 100644 index 00000000..a96b6e81 --- /dev/null +++ b/67_One_Check/csharp/Resources/IllegalMove.txt @@ -0,0 +1 @@ +Illegal move. Try again... \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/Introduction.txt b/67_One_Check/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..bc891a6e --- /dev/null +++ b/67_One_Check/csharp/Resources/Introduction.txt @@ -0,0 +1,29 @@ + One Check + Creative Computing Morristown, New Jersey + + + +Solitaire checker puzzle by David Ahl + +48 checkers and placed on the 2 outside spaces of a +standard 64-square checkerboard. The object is to +remove as many checkers as possible by diagonal jumps +(as in standard checkers). Use the numbered board to +indicate the square you wish to jump from and to. On +the board printed out on each turn '1' indicates a +checker and '0' an empty square. When you have no +possible jumps remaining, input a '0' in response to +question 'Jump from ?' + +Here is the numerical board: + +1 2 3 4 5 6 7 8 +9 10 11 12 13 14 15 16 +17 18 19 20 21 22 23 24 +25 26 27 28 29 30 31 32 +33 34 35 36 37 38 39 40 +41 42 43 44 45 46 47 48 +49 50 51 52 53 54 55 56 +57 58 59 60 61 62 63 64 + +And here is the opening position of the checkers. diff --git a/67_One_Check/csharp/Resources/Resource.cs b/67_One_Check/csharp/Resources/Resource.cs new file mode 100644 index 00000000..7095d7ec --- /dev/null +++ b/67_One_Check/csharp/Resources/Resource.cs @@ -0,0 +1,45 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace OneCheck.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + public static Stream IllegalMove => GetStream(); + public static Stream YesOrNo => GetStream(); + public static Stream Bye => GetStream(); + } + + internal static class Formats + { + public static string Results => GetString(); + } + + internal static class Prompts + { + public static string From => GetString(); + public static string To => GetString(); + public static string TryAgain => GetString(); + } + + internal static class Strings + { + public static string TooManyColumns => GetString(); + public static string TooManyRows => GetString(); + } + + private static string GetString([CallerMemberName] string? name = null) + { + using var stream = GetStream(name); + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + + + private static Stream GetStream([CallerMemberName] string? name = null) => + Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/Results.txt b/67_One_Check/csharp/Resources/Results.txt new file mode 100644 index 00000000..8d4bd13f --- /dev/null +++ b/67_One_Check/csharp/Resources/Results.txt @@ -0,0 +1,4 @@ + +You made {0} jumps and had {1} pieces +remaining on the board. + diff --git a/67_One_Check/csharp/Resources/To.txt b/67_One_Check/csharp/Resources/To.txt new file mode 100644 index 00000000..788636ff --- /dev/null +++ b/67_One_Check/csharp/Resources/To.txt @@ -0,0 +1 @@ +to \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/TryAgain.txt b/67_One_Check/csharp/Resources/TryAgain.txt new file mode 100644 index 00000000..c65e51fc --- /dev/null +++ b/67_One_Check/csharp/Resources/TryAgain.txt @@ -0,0 +1 @@ +Try again \ No newline at end of file diff --git a/67_One_Check/csharp/Resources/YesOrNo.txt b/67_One_Check/csharp/Resources/YesOrNo.txt new file mode 100644 index 00000000..703d4ad6 --- /dev/null +++ b/67_One_Check/csharp/Resources/YesOrNo.txt @@ -0,0 +1 @@ +Please answer 'Yes' or 'No'. \ No newline at end of file From 35f8248b1fb9b4d4d1093820fe804dbb8aaa1e6b Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 12 Aug 2022 17:49:05 +1000 Subject: [PATCH 29/39] Add game intro --- 67_One_Check/csharp/Board.cs | 18 +++++++++++++++++ 67_One_Check/csharp/Game.cs | 20 +++++++++++++++++++ 67_One_Check/csharp/Program.cs | 5 +++++ .../csharp/Resources/Introduction.txt | 17 ++++++++-------- 4 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 67_One_Check/csharp/Board.cs create mode 100644 67_One_Check/csharp/Game.cs create mode 100644 67_One_Check/csharp/Program.cs diff --git a/67_One_Check/csharp/Board.cs b/67_One_Check/csharp/Board.cs new file mode 100644 index 00000000..213a54d7 --- /dev/null +++ b/67_One_Check/csharp/Board.cs @@ -0,0 +1,18 @@ +namespace OneCheck; + +internal class Board +{ + private readonly int[][] _checkers; + + public Board() + { + _checkers = + Enumerable.Range(0, 8) + .Select(r => Enumerable.Range(0, 8) + .Select(c => r > 1 && r < 6 && c > 1 && c < 6 ? 0 : 1).ToArray()) + .ToArray(); + } + + public override string ToString() => + string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => $" {c}")))); +} \ No newline at end of file diff --git a/67_One_Check/csharp/Game.cs b/67_One_Check/csharp/Game.cs new file mode 100644 index 00000000..924fc04c --- /dev/null +++ b/67_One_Check/csharp/Game.cs @@ -0,0 +1,20 @@ +namespace OneCheck; + +internal class Game +{ + private readonly IReadWrite _io; + private readonly Board _board; + + public Game(IReadWrite io) + { + _io = io; + _board = new Board(); + } + + public void Play() + { + _io.Write(Streams.Introduction); + + _io.WriteLine(_board); + } +} diff --git a/67_One_Check/csharp/Program.cs b/67_One_Check/csharp/Program.cs new file mode 100644 index 00000000..4a3ab83b --- /dev/null +++ b/67_One_Check/csharp/Program.cs @@ -0,0 +1,5 @@ +global using Games.Common.IO; +global using static OneCheck.Resources.Resource; +using OneCheck; + +new Game(new ConsoleIO()).Play(); diff --git a/67_One_Check/csharp/Resources/Introduction.txt b/67_One_Check/csharp/Resources/Introduction.txt index bc891a6e..409f6b37 100644 --- a/67_One_Check/csharp/Resources/Introduction.txt +++ b/67_One_Check/csharp/Resources/Introduction.txt @@ -17,13 +17,14 @@ question 'Jump from ?' Here is the numerical board: -1 2 3 4 5 6 7 8 -9 10 11 12 13 14 15 16 -17 18 19 20 21 22 23 24 -25 26 27 28 29 30 31 32 -33 34 35 36 37 38 39 40 -41 42 43 44 45 46 47 48 -49 50 51 52 53 54 55 56 -57 58 59 60 61 62 63 64 + 1 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 + 25 26 27 28 29 30 31 32 + 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 + 49 50 51 52 53 54 55 56 + 57 58 59 60 61 62 63 64 And here is the opening position of the checkers. + From 876c71d89b5888059129af6e0469b436637a398f Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Tue, 16 Aug 2022 09:01:14 +1000 Subject: [PATCH 30/39] Add move logic --- 67_One_Check/csharp/Board.cs | 34 ++++++++++++++++++++++++++++++---- 67_One_Check/csharp/Game.cs | 28 +++++++++++++++++++++++++++- 67_One_Check/csharp/Move.cs | 13 +++++++++++++ 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 67_One_Check/csharp/Move.cs diff --git a/67_One_Check/csharp/Board.cs b/67_One_Check/csharp/Board.cs index 213a54d7..7ae917be 100644 --- a/67_One_Check/csharp/Board.cs +++ b/67_One_Check/csharp/Board.cs @@ -2,17 +2,43 @@ namespace OneCheck; internal class Board { - private readonly int[][] _checkers; + private readonly bool[][] _checkers; + private int _count; public Board() { _checkers = Enumerable.Range(0, 8) .Select(r => Enumerable.Range(0, 8) - .Select(c => r > 1 && r < 6 && c > 1 && c < 6 ? 0 : 1).ToArray()) + .Select(c => r <= 1 || r >= 6 || c <= 1 || c >= 6).ToArray()) .ToArray(); + _count = 48; } + private bool this[int index] + { + get => _checkers[(index - 1) / 8][(index-1) % 8]; + set => _checkers[(index - 1) / 8][(index-1) % 8] = value; + } + + public int Count => _count; + + public bool TryMove(Move move) + { + if (move.IsInRange && move.IsTwoSpacesDiagonally && IsPieceJumpingPieceToEmptySpace(move)) + { + this[move.From] = false; + this[move.Jumped] = false; + this[move.To] = true; + _count--; + return true; + } + + return false; + } + + private bool IsPieceJumpingPieceToEmptySpace(Move move) => this[move.From] && this[move.Jumped] && !this[move.To]; + public override string ToString() => - string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => $" {c}")))); -} \ No newline at end of file + string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => c ? " 1" : " 0")))); +} diff --git a/67_One_Check/csharp/Game.cs b/67_One_Check/csharp/Game.cs index 924fc04c..49da9851 100644 --- a/67_One_Check/csharp/Game.cs +++ b/67_One_Check/csharp/Game.cs @@ -4,6 +4,7 @@ internal class Game { private readonly IReadWrite _io; private readonly Board _board; + private int _moveCount; public Game(IReadWrite io) { @@ -15,6 +16,31 @@ internal class Game { _io.Write(Streams.Introduction); - _io.WriteLine(_board); + do + { + _io.WriteLine(_board); + _io.WriteLine(); + } while (PlayMove()); + + _io.WriteLine(Formats.Results, _moveCount, _board.Count); + } + + private bool PlayMove() + { + while (true) + { + var from = (int)_io.ReadNumber(Prompts.From); + if (from == 0) { return false; } + + var move = new Move { From = from, To = (int)_io.ReadNumber(Prompts.To) }; + + if (_board.TryMove(move)) + { + _moveCount++; + return true; + } + + _io.Write(Streams.IllegalMove); + } } } diff --git a/67_One_Check/csharp/Move.cs b/67_One_Check/csharp/Move.cs new file mode 100644 index 00000000..b90f7c0b --- /dev/null +++ b/67_One_Check/csharp/Move.cs @@ -0,0 +1,13 @@ +namespace OneCheck; + +internal class Move +{ + public int From { get; init; } + public int To { get; init; } + public int Jumped => (From + To) / 2; + + public bool IsInRange => From >= 1 && From <= 64 && To >= 1 && To <= 64; + public bool IsTwoSpacesDiagonally => RowDelta == 2 && ColumnDelta == 2; + private int RowDelta => Math.Abs(From / 8 - To / 8); + private int ColumnDelta => Math.Abs(From % 8 - To % 8); +} \ No newline at end of file From c603549db34a25cb445298d44fd6e333d31d4efd Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 19 Aug 2022 08:41:11 +1000 Subject: [PATCH 31/39] Finish game --- 67_One_Check/csharp/Board.cs | 32 +++++++++++++++++---- 67_One_Check/csharp/Game.cs | 35 +++++++++++------------ 67_One_Check/csharp/Move.cs | 2 +- 67_One_Check/csharp/Resources/Results.txt | 1 - 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/67_One_Check/csharp/Board.cs b/67_One_Check/csharp/Board.cs index 7ae917be..2e68072d 100644 --- a/67_One_Check/csharp/Board.cs +++ b/67_One_Check/csharp/Board.cs @@ -3,7 +3,8 @@ namespace OneCheck; internal class Board { private readonly bool[][] _checkers; - private int _count; + private int _pieceCount; + private int _moveCount; public Board() { @@ -12,16 +13,33 @@ internal class Board .Select(r => Enumerable.Range(0, 8) .Select(c => r <= 1 || r >= 6 || c <= 1 || c >= 6).ToArray()) .ToArray(); - _count = 48; + _pieceCount = 48; } private bool this[int index] { - get => _checkers[(index - 1) / 8][(index-1) % 8]; - set => _checkers[(index - 1) / 8][(index-1) % 8] = value; + get => _checkers[index / 8][index % 8]; + set => _checkers[index / 8][index % 8] = value; } - public int Count => _count; + public bool PlayMove(IReadWrite io) + { + while (true) + { + var from = (int)io.ReadNumber(Prompts.From); + if (from == 0) { return false; } + + var move = new Move { From = from - 1, To = (int)io.ReadNumber(Prompts.To) - 1 }; + + if (TryMove(move)) + { + _moveCount++; + return true; + } + + io.Write(Streams.IllegalMove); + } + } public bool TryMove(Move move) { @@ -30,7 +48,7 @@ internal class Board this[move.From] = false; this[move.Jumped] = false; this[move.To] = true; - _count--; + _pieceCount--; return true; } @@ -39,6 +57,8 @@ internal class Board private bool IsPieceJumpingPieceToEmptySpace(Move move) => this[move.From] && this[move.Jumped] && !this[move.To]; + public string GetReport() => string.Format(Formats.Results, _moveCount, _pieceCount); + public override string ToString() => string.Join(Environment.NewLine, _checkers.Select(r => string.Join(" ", r.Select(c => c ? " 1" : " 0")))); } diff --git a/67_One_Check/csharp/Game.cs b/67_One_Check/csharp/Game.cs index 49da9851..d9e64e26 100644 --- a/67_One_Check/csharp/Game.cs +++ b/67_One_Check/csharp/Game.cs @@ -3,13 +3,10 @@ namespace OneCheck; internal class Game { private readonly IReadWrite _io; - private readonly Board _board; - private int _moveCount; public Game(IReadWrite io) { _io = io; - _board = new Board(); } public void Play() @@ -18,29 +15,31 @@ internal class Game do { - _io.WriteLine(_board); - _io.WriteLine(); - } while (PlayMove()); + var board = new Board(); + do + { + _io.WriteLine(board); + _io.WriteLine(); + } while (board.PlayMove(_io)); - _io.WriteLine(Formats.Results, _moveCount, _board.Count); + _io.WriteLine(board.GetReport()); + } while (_io.ReadYesNo(Prompts.TryAgain) == "yes"); + + _io.Write(Streams.Bye); } +} - private bool PlayMove() +internal static class IOExtensions +{ + internal static string ReadYesNo(this IReadWrite io, string prompt) { while (true) { - var from = (int)_io.ReadNumber(Prompts.From); - if (from == 0) { return false; } + var response = io.ReadString(prompt).ToLower(); - var move = new Move { From = from, To = (int)_io.ReadNumber(Prompts.To) }; + if (response == "yes" || response == "no") { return response; } - if (_board.TryMove(move)) - { - _moveCount++; - return true; - } - - _io.Write(Streams.IllegalMove); + io.Write(Streams.YesOrNo); } } } diff --git a/67_One_Check/csharp/Move.cs b/67_One_Check/csharp/Move.cs index b90f7c0b..0b48659e 100644 --- a/67_One_Check/csharp/Move.cs +++ b/67_One_Check/csharp/Move.cs @@ -6,7 +6,7 @@ internal class Move public int To { get; init; } public int Jumped => (From + To) / 2; - public bool IsInRange => From >= 1 && From <= 64 && To >= 1 && To <= 64; + public bool IsInRange => From >= 0 && From <= 63 && To >= 0 && To <= 63; public bool IsTwoSpacesDiagonally => RowDelta == 2 && ColumnDelta == 2; private int RowDelta => Math.Abs(From / 8 - To / 8); private int ColumnDelta => Math.Abs(From % 8 - To % 8); diff --git a/67_One_Check/csharp/Resources/Results.txt b/67_One_Check/csharp/Resources/Results.txt index 8d4bd13f..a8771b6b 100644 --- a/67_One_Check/csharp/Resources/Results.txt +++ b/67_One_Check/csharp/Resources/Results.txt @@ -1,4 +1,3 @@ You made {0} jumps and had {1} pieces remaining on the board. - From 39733109c7eef5c372d39868b4c511a01ac18299 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 19 Aug 2022 17:39:01 +1000 Subject: [PATCH 32/39] Add string resources --- 41_Guess/csharp/Guess.csproj | 8 +++++ 41_Guess/csharp/Resources/Good.txt | 1 + 41_Guess/csharp/Resources/Introduction.txt | 9 +++++ 41_Guess/csharp/Resources/Limit.txt | 1 + 41_Guess/csharp/Resources/Resource.cs | 39 ++++++++++++++++++++++ 41_Guess/csharp/Resources/ShouldHave.txt | 1 + 41_Guess/csharp/Resources/ThatsIt.txt | 1 + 41_Guess/csharp/Resources/Thinking.txt | 2 ++ 41_Guess/csharp/Resources/TooHigh.txt | 1 + 41_Guess/csharp/Resources/TooLow.txt | 1 + 41_Guess/csharp/Resources/VeryGood.txt | 1 + 11 files changed, 65 insertions(+) create mode 100644 41_Guess/csharp/Resources/Good.txt create mode 100644 41_Guess/csharp/Resources/Introduction.txt create mode 100644 41_Guess/csharp/Resources/Limit.txt create mode 100644 41_Guess/csharp/Resources/Resource.cs create mode 100644 41_Guess/csharp/Resources/ShouldHave.txt create mode 100644 41_Guess/csharp/Resources/ThatsIt.txt create mode 100644 41_Guess/csharp/Resources/Thinking.txt create mode 100644 41_Guess/csharp/Resources/TooHigh.txt create mode 100644 41_Guess/csharp/Resources/TooLow.txt create mode 100644 41_Guess/csharp/Resources/VeryGood.txt diff --git a/41_Guess/csharp/Guess.csproj b/41_Guess/csharp/Guess.csproj index d3fe4757..3870320c 100644 --- a/41_Guess/csharp/Guess.csproj +++ b/41_Guess/csharp/Guess.csproj @@ -6,4 +6,12 @@ enable enable + + + + + + + + diff --git a/41_Guess/csharp/Resources/Good.txt b/41_Guess/csharp/Resources/Good.txt new file mode 100644 index 00000000..989dfa38 --- /dev/null +++ b/41_Guess/csharp/Resources/Good.txt @@ -0,0 +1 @@ +Good. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/Introduction.txt b/41_Guess/csharp/Resources/Introduction.txt new file mode 100644 index 00000000..7a1521e1 --- /dev/null +++ b/41_Guess/csharp/Resources/Introduction.txt @@ -0,0 +1,9 @@ + Guezs + Creative Computing Morristown, New Jersey + + + +This is a number guessing game. I'll think +of a number between 1 and any limit you want. +The you have to guess what it is. + diff --git a/41_Guess/csharp/Resources/Limit.txt b/41_Guess/csharp/Resources/Limit.txt new file mode 100644 index 00000000..62e698a6 --- /dev/null +++ b/41_Guess/csharp/Resources/Limit.txt @@ -0,0 +1 @@ +What limit do you want \ No newline at end of file diff --git a/41_Guess/csharp/Resources/Resource.cs b/41_Guess/csharp/Resources/Resource.cs new file mode 100644 index 00000000..6ba21657 --- /dev/null +++ b/41_Guess/csharp/Resources/Resource.cs @@ -0,0 +1,39 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Guess.Resources; + +internal static class Resource +{ + internal static class Streams + { + public static Stream Introduction => GetStream(); + public static Stream TooLow => GetStream(); + public static Stream TooHigh => GetStream(); + public static Stream Good => GetStream(); + public static Stream VeryGood => GetStream(); + } + + internal static class Formats + { + public static string Thinking => GetString(); + public static string ThatsIt => GetString(); + public static string ShouldHave => GetString(); + } + + internal static class Prompts + { + public static string Limit => GetString(); + } + + private static string GetString([CallerMemberName] string? name = null) + { + using var stream = GetStream(name); + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + + private static Stream GetStream([CallerMemberName] string? name = null) => + Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") + ?? throw new Exception($"Could not find embedded resource stream '{name}'."); +} \ No newline at end of file diff --git a/41_Guess/csharp/Resources/ShouldHave.txt b/41_Guess/csharp/Resources/ShouldHave.txt new file mode 100644 index 00000000..84803588 --- /dev/null +++ b/41_Guess/csharp/Resources/ShouldHave.txt @@ -0,0 +1 @@ +You should have been able to get it in only {0} \ No newline at end of file diff --git a/41_Guess/csharp/Resources/ThatsIt.txt b/41_Guess/csharp/Resources/ThatsIt.txt new file mode 100644 index 00000000..61f78c43 --- /dev/null +++ b/41_Guess/csharp/Resources/ThatsIt.txt @@ -0,0 +1 @@ +That's it! You got it in {0} tries. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/Thinking.txt b/41_Guess/csharp/Resources/Thinking.txt new file mode 100644 index 00000000..8f1bbac7 --- /dev/null +++ b/41_Guess/csharp/Resources/Thinking.txt @@ -0,0 +1,2 @@ +I'm thinking of a number between 1 and {0} +Now you try to guess what it is. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/TooHigh.txt b/41_Guess/csharp/Resources/TooHigh.txt new file mode 100644 index 00000000..bb4ee4ed --- /dev/null +++ b/41_Guess/csharp/Resources/TooHigh.txt @@ -0,0 +1 @@ +Too high. Try a smaller answer. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/TooLow.txt b/41_Guess/csharp/Resources/TooLow.txt new file mode 100644 index 00000000..4bc1776f --- /dev/null +++ b/41_Guess/csharp/Resources/TooLow.txt @@ -0,0 +1 @@ +Too low. Try a bigger answer. \ No newline at end of file diff --git a/41_Guess/csharp/Resources/VeryGood.txt b/41_Guess/csharp/Resources/VeryGood.txt new file mode 100644 index 00000000..606150c7 --- /dev/null +++ b/41_Guess/csharp/Resources/VeryGood.txt @@ -0,0 +1 @@ +Very good. \ No newline at end of file From 9118236a6fee35304977de7e3a1ec096d050f86c Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 19 Aug 2022 19:15:52 +1000 Subject: [PATCH 33/39] Add main program classes --- 41_Guess/csharp/Game.cs | 18 ++++++++++++++++++ 41_Guess/csharp/Program.cs | 7 +++++++ 2 files changed, 25 insertions(+) create mode 100644 41_Guess/csharp/Game.cs create mode 100644 41_Guess/csharp/Program.cs diff --git a/41_Guess/csharp/Game.cs b/41_Guess/csharp/Game.cs new file mode 100644 index 00000000..ea86a10a --- /dev/null +++ b/41_Guess/csharp/Game.cs @@ -0,0 +1,18 @@ +namespace Guess; + +internal class Game +{ + private readonly IReadWrite _io; + private readonly IRandom _random; + + public Game(IReadWrite io, IRandom random) + { + _io = io; + _random = random; + } + + public void Play() + { + + } +} \ No newline at end of file diff --git a/41_Guess/csharp/Program.cs b/41_Guess/csharp/Program.cs new file mode 100644 index 00000000..73ab09dd --- /dev/null +++ b/41_Guess/csharp/Program.cs @@ -0,0 +1,7 @@ +global using Games.Common.IO; +global using Games.Common.Randomness; +global using static Guess.Resources.Resource; + +using Guess; + +new Game(new ConsoleIO(), new RandomNumberGenerator()).Play(); From 769b277f638ea0c26fe6c947a8a830c83ebb9702 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 20 Aug 2022 08:26:33 +1000 Subject: [PATCH 34/39] Implement game --- 41_Guess/csharp/Game.cs | 62 +++++++++++++++++++++- 41_Guess/csharp/Resources/BlankLines.txt | 5 ++ 41_Guess/csharp/Resources/Introduction.txt | 2 +- 41_Guess/csharp/Resources/Resource.cs | 9 +++- 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 41_Guess/csharp/Resources/BlankLines.txt diff --git a/41_Guess/csharp/Game.cs b/41_Guess/csharp/Game.cs index ea86a10a..57ae071a 100644 --- a/41_Guess/csharp/Game.cs +++ b/41_Guess/csharp/Game.cs @@ -13,6 +13,66 @@ internal class Game public void Play() { - + while (true) + { + _io.Write(Streams.Introduction); + + var limit = _io.ReadNumber(Prompts.Limit); + _io.WriteLine(); + + // There's a bug here that exists in the original code. + // If the limit entered is <= 0 then the program will crash. + var targetGuessCount = checked((int)Math.Log2(limit) + 1); + + PlayGuessingRounds(limit, targetGuessCount); + + _io.Write(Streams.BlankLines); + } + } + + private void PlayGuessingRounds(float limit, int targetGuessCount) + { + while (true) + { + _io.WriteLine(Formats.Thinking, limit); + + // There's a bug here that exists in the original code. If a non-integer is entered as the limit + // then it's possible for the secret number to be the next integer greater than the limit. + var secretNumber = (int)_random.NextFloat(limit) + 1; + + var guessCount = 0; + + while (true) + { + var guess = _io.ReadNumber(""); + if (guess <= 0) { return; } + guessCount++; + if (IsGuessCorrect(guess, secretNumber)) { break; } + } + + ReportResult(guessCount, targetGuessCount); + + _io.Write(Streams.BlankLines); + } + } + + private bool IsGuessCorrect(float guess, int secretNumber) + { + if (guess < secretNumber) { _io.Write(Streams.TooLow); } + if (guess > secretNumber) { _io.Write(Streams.TooHigh); } + + return guess == secretNumber; + } + + private void ReportResult(int guessCount, int targetGuessCount) + { + _io.WriteLine(Formats.ThatsIt, guessCount); + _io.WriteLine( + (guessCount - targetGuessCount) switch + { + < 0 => Strings.VeryGood, + 0 => Strings.Good, + > 0 => string.Format(Formats.ShouldHave, targetGuessCount) + }); } } \ No newline at end of file diff --git a/41_Guess/csharp/Resources/BlankLines.txt b/41_Guess/csharp/Resources/BlankLines.txt new file mode 100644 index 00000000..3f2ff2d6 --- /dev/null +++ b/41_Guess/csharp/Resources/BlankLines.txt @@ -0,0 +1,5 @@ + + + + + diff --git a/41_Guess/csharp/Resources/Introduction.txt b/41_Guess/csharp/Resources/Introduction.txt index 7a1521e1..ed679492 100644 --- a/41_Guess/csharp/Resources/Introduction.txt +++ b/41_Guess/csharp/Resources/Introduction.txt @@ -1,4 +1,4 @@ - Guezs + Guess Creative Computing Morristown, New Jersey diff --git a/41_Guess/csharp/Resources/Resource.cs b/41_Guess/csharp/Resources/Resource.cs index 6ba21657..d42477e2 100644 --- a/41_Guess/csharp/Resources/Resource.cs +++ b/41_Guess/csharp/Resources/Resource.cs @@ -10,8 +10,7 @@ internal static class Resource public static Stream Introduction => GetStream(); public static Stream TooLow => GetStream(); public static Stream TooHigh => GetStream(); - public static Stream Good => GetStream(); - public static Stream VeryGood => GetStream(); + public static Stream BlankLines => GetStream(); } internal static class Formats @@ -26,6 +25,12 @@ internal static class Resource public static string Limit => GetString(); } + internal static class Strings + { + public static string Good => GetString(); + public static string VeryGood => GetString(); + } + private static string GetString([CallerMemberName] string? name = null) { using var stream = GetStream(name); From 44e4472924b761d427a705ef887863e0683b88c4 Mon Sep 17 00:00:00 2001 From: Scott Prive Date: Sat, 20 Aug 2022 12:35:07 -0400 Subject: [PATCH 35/39] Hopefully clarify Alternate rules --- 00_Alternate_Languages/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/00_Alternate_Languages/README.md b/00_Alternate_Languages/README.md index f7c55f95..ff6c9a95 100644 --- a/00_Alternate_Languages/README.md +++ b/00_Alternate_Languages/README.md @@ -1,9 +1,10 @@ #### Alternate Languages -This folder contains implementations of each program in alternate languages which are _not_ one of the agreed upon 10 languages, intended to meet these three criteria: +This folder contains implementations of each program in alternate languages which are _not_ one of the agreed upon 10 languages. +Implementations here are NOT bound to these three criteria: 1. Popular (by TIOBE index) 2. Memory safe 3. Generally considered a 'scripting' language -We welcome additional ports in whatever language you prefer, but these additional ports are for educational purposes only, and do not count towards the donation total at the end of the project. \ No newline at end of file +We welcome additional ports in whatever language you prefer, but these additional ports are for educational purposes only, and do not count towards the donation total at the end of the project. From 9f6bf9e07e5f8eb195c1f4f3c29a7af54cedf643 Mon Sep 17 00:00:00 2001 From: Scott Prive Date: Sat, 20 Aug 2022 12:40:09 -0400 Subject: [PATCH 36/39] Hopefully clarify Alternate rules --- 00_Alternate_Languages/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/00_Alternate_Languages/README.md b/00_Alternate_Languages/README.md index ff6c9a95..0c96b007 100644 --- a/00_Alternate_Languages/README.md +++ b/00_Alternate_Languages/README.md @@ -1,10 +1,14 @@ #### Alternate Languages This folder contains implementations of each program in alternate languages which are _not_ one of the agreed upon 10 languages. + Implementations here are NOT bound to these three criteria: 1. Popular (by TIOBE index) 2. Memory safe 3. Generally considered a 'scripting' language +So for example, (here only) C or PASCAL are allowed, but please remain faithful to original look-and-feel (console applications +guidelines, and try to keep the code portable (unless it is not possible, and then be very explicit about it). + We welcome additional ports in whatever language you prefer, but these additional ports are for educational purposes only, and do not count towards the donation total at the end of the project. From e7efe702faf772fea94f81671483697400e22330 Mon Sep 17 00:00:00 2001 From: Scott Prive Date: Sat, 20 Aug 2022 12:53:31 -0400 Subject: [PATCH 37/39] Hopefully clarify Alternate rules --- 00_Alternate_Languages/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/00_Alternate_Languages/README.md b/00_Alternate_Languages/README.md index 0c96b007..8c351060 100644 --- a/00_Alternate_Languages/README.md +++ b/00_Alternate_Languages/README.md @@ -8,7 +8,8 @@ Implementations here are NOT bound to these three criteria: 2. Memory safe 3. Generally considered a 'scripting' language -So for example, (here only) C or PASCAL are allowed, but please remain faithful to original look-and-feel (console applications -guidelines, and try to keep the code portable (unless it is not possible, and then be very explicit about it). +So for example, (here only) C or PASCAL are allowed. Please still remain faithful to original look-and-feel (console applications), +and try to keep the code portable (unless it is not possible, and then be very explicit about this limitation in your +README and your folder naming). We welcome additional ports in whatever language you prefer, but these additional ports are for educational purposes only, and do not count towards the donation total at the end of the project. From b0c4b3c6781d51992d24742c68707868b861f869 Mon Sep 17 00:00:00 2001 From: Scott Prive Date: Sat, 20 Aug 2022 12:55:29 -0400 Subject: [PATCH 38/39] Hopefully clarify Alternate rules --- 00_Alternate_Languages/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/00_Alternate_Languages/README.md b/00_Alternate_Languages/README.md index 8c351060..0cbe947e 100644 --- a/00_Alternate_Languages/README.md +++ b/00_Alternate_Languages/README.md @@ -8,8 +8,8 @@ Implementations here are NOT bound to these three criteria: 2. Memory safe 3. Generally considered a 'scripting' language -So for example, (here only) C or PASCAL are allowed. Please still remain faithful to original look-and-feel (console applications), -and try to keep the code portable (unless it is not possible, and then be very explicit about this limitation in your +So for example, (here only) C or PASCAL are allowed. Please still remain faithful to original look-and-feel (console applications). +Try to keep your code portable (unless it is not possible, and then be very explicit about this limitation in your README and your folder naming). We welcome additional ports in whatever language you prefer, but these additional ports are for educational purposes only, and do not count towards the donation total at the end of the project. From 0fb5c0508b4496518070edc46ca76def8a08aaad Mon Sep 17 00:00:00 2001 From: Alvaro Frias Garay Date: Sun, 21 Aug 2022 18:08:49 -0300 Subject: [PATCH 39/39] Add lua's russian roullete Signed-off-by: Alvaro Frias Garay --- 76_Russian_Roulette/lua/russianroulette.lua | 58 +++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 76_Russian_Roulette/lua/russianroulette.lua diff --git a/76_Russian_Roulette/lua/russianroulette.lua b/76_Russian_Roulette/lua/russianroulette.lua new file mode 100644 index 00000000..546ec6c4 --- /dev/null +++ b/76_Russian_Roulette/lua/russianroulette.lua @@ -0,0 +1,58 @@ +print [[ + RUSSIAN ROULETTE + CREATIVE COMPUTING MORRISTOWN, NEW JERSY +This is a game of >>>>>>>>>>Russian Roulette +Here is a Revolver + +]] + +local function parse_input() + local incorrect_input = true + local input = nil + while incorrect_input do + input = io.read(1) + if input == "1" or input == "2" then incorrect_input = false end + end + return input +end + +local function russian_roulette() + local NUMBER_OF_ROUNDS = 9 + + while true do + local dead = false + local n = 0 + print("Type '1' to Spin chamber and pull trigger") + print("Type '2' to Give up") + print("Go") + + while not dead do + local choice = parse_input() + if choice == "2" then break end + + if math.random() > 0.833333333333334 then + dead = true + else + print("CLICK") + n = n + 1 + end + + if n > NUMBER_OF_ROUNDS then break end + end + + if dead then + print("BANG!!!!! You're Dead!") + print("Condolences will be sent to your relatives.\n\n\n") + print("...Next victim...") + elseif n > NUMBER_OF_ROUNDS then + print("You win!!!!!") + print("Let someone else blow his brain out.\n") + else + print(" Chicken!!!!!\n\n\n") + print("...Next victim....") + end + end +end + +russian_roulette() +