From 374952d65a8fccee2dbb6bb14eddb4a5cd8a2eb5 Mon Sep 17 00:00:00 2001 From: Cory Date: Sun, 19 May 2024 04:06:01 -0400 Subject: [PATCH] This is the FINAL version of what I'm submitting. This is a version of minesweeper. You win by isolating every mine, which is the same as revealing all numbered spaces. There is no flag, so you have to keep track of, or figure out, what's revealed. The game ends if you win as described above or you lose by selecting a mine. I have playtested this and confirmed that the game ends in a win by meeting the above criterion. I also (not intentionally) confirmed you lose if you select a mine. I did the latter far too many times... Things to note: -I have the game in debug mode so that instructions appear. -There is no score. I don't think there's a score in minesweeper. You either survive the mines or die. -I have not implemented flagging potential locations of mines. You can technically play without them, so I don't think you lose out on any of the core gameplay. -I'm not sure why, but when the game ends, some of the mines don't show up and some of the revealed numbers disappear. -Because two displayed agents cannot occupy the same space, navigating with the cursor over mines or numbered squares may require pressing an arrow key multiple times. (I tried to not display the mines and then display them only when revealing spaces, but the revealing algorithm didn't work when I tried it like that. I promise I spent hours trying to get it to work before settling on this current iteration.) -You can lose on the first move... --- __pycache__/cursor.cpython-312.pyc | Bin 1858 -> 1587 bytes __pycache__/free_space.cpython-312.pyc | Bin 12977 -> 14102 bytes __pycache__/mine.cpython-312.pyc | Bin 1929 -> 2624 bytes __pycache__/spawner.cpython-312.pyc | Bin 3134 -> 4305 bytes cursor.py | 12 ++- free_space.py | 97 ++++++++++++++++--------- mine.py | 52 ++++++++++--- minesweeper_game.py | 4 +- spawner.py | 19 +++-- 9 files changed, 128 insertions(+), 56 deletions(-) diff --git a/__pycache__/cursor.cpython-312.pyc b/__pycache__/cursor.cpython-312.pyc index 4f75f8d7c2af82dcf00d788e6c0b5379747a6c14..9d714f170ebe776e14b1abee375d7abcf73ce240 100644 GIT binary patch delta 679 zcmY*Xzi$&U6h0?+mrE{JqLQU86-EV>qa~4bH_)PF(EDz9U?J2-q4i zRFy&e1q>`KurM%y1Pcq@(5*~t5gm}2cuq=ycfQY({k_lcefEc$*Jbas=ameIkFPej z?i_jV=6uxjQRZxO8O9-Jel9a5jkZML=o?3_x`~$DJn;2@QbX!7+Q^9q>OFdk=GAWQ zLetr^_KcR697k$TKEJSYy@XGr!S7QX_b3h$A-TYb3|SWwA@~5_qp7S-nd(#i%DM+i z-w}YA(QpQ!>6@Yeb7nHqr zz5sY+j2xpn38=ansjqdEM+p5apGV#g17NK48-j$ORsaA1 delta 880 zcmdnYbBK@kG%qg~0}$MrcS8k%)n5~1~Xfi1IcVQm@1Gt zDV!h@NtP*#ALN=SoH}5-iFaX7C<{X+6l!w$O@6_o<;DlJ^(DwZMf@N_07z5`hGe8F zB$pNy=NBnt7Aqu{D7*xP{VkT<%)HbpevnvBesW?-Y6?hBlcR`ZvKF(f#x3TY{PbJQ z#U(|zSc?+#(o=5 zFzYFUg0NT==$r^ntYkLync%B4H1dy9uqw- z$Qo=h-cYi=c4O^jW7mtau2)3d?#L=FFq$3tiGfkHig5;kcS@ zq3i`ir;CbCM}kj?T=$H>=ox<@A?-?f)`jex%jvln6LK$m=3VzJzvx+h*|p-LV#QU7 z%8$$-lRmIBi0FS{W)RT+z%IG5CB6j$Q1wp diff --git a/__pycache__/free_space.cpython-312.pyc b/__pycache__/free_space.cpython-312.pyc index 393eefb96b950acd47a9aac6a0c3ab35063d9e71..ea5f4931f12c5b05eee29f90ab85ec21dfa58a15 100644 GIT binary patch delta 2566 zcmZuzUu+vm8Q=Bp+H1#g5+!c_H{-a8>n7KCc*Q?uPzr7=^rQlD`!Pq9+e~F75Scc7CSK`XG0sq zF>>(CSZkCRq`)X8eAURKU>hs+uyr3jXaf|M%gL(4E!P4AO%L-JcjUnIL;1WPJC`wNhJku2 zFFNZRi5w(+4f8#T@)3B`$U~QU1|W}kBah3qP!+Ryr|F}SMbR?pbCu%|Rk=#60&$D9 zN{R+l)^=QClo>V5Dx^hi!sr?`%G5lJI5(ROd3r<7Iw2I+h4D0kK95nOujivic>q`8 z0M*x}c>9lD`~GWpFa4<{wbxH>Prvu(z9PkkS*vIr?0xiumS4Bj)T)}*HmYAr#H21| zE0zrgkTXxa1hjWIE;>6~F9G<=SBCMH~CMr*M~f(R|ThMjispDghAH zWdNd=KsfS6r?BWd;RoTYHvarnzhJR7zZ z`65X0Z&PXpkOv?;>wf7DmIJz1V13|g8AA6r8&Fxm4A_3rX|srAKF2i3ZZ@lVy2Tgi z%Bovs5zw%19DMv7huOoRZ`l~k54-kiEZu$uH7*Q*o0!y*6z|4tD9Yz@ul`La<4>hc zS=>o?y&sBbKimv`TM01lpZ%TjXWl6dfc9VftlE8YmFyj3~+Ge;A>IHRUhpCm$K$P;< zNMlW+xyICBrI-vQk1~1d4Ks8rvUNq3w!WcCn-NnjLGmmGyL!b=q_ZvDuqdOqe(=^O zey3auf|dt;xva)&)kyG{mSkx`x+8C0_>Qt5t;>PD^|e6C>Ki-3iNS%rgUx^khP1hE zxzH=n?LO%7>^Ut{z^yq>DjWgCD4x8}x8-H%54X5NOj>{zfd;ElA0Ey@KLth)TL%C| z?QxPX(tHUS25HfD?3ete^#cG{BH_G1GUsq9cgB6#Vb{PK9xPdZo;1DamD;6+#Y?mE zm*#R_6fXnc=Dd%zjj08v0$q?tiY`>j$Z^~$8;}|SHUrMaC{ob>_A)cv3cLYI<|zW( zG7u8DO3h~57`8W?z@dp&FXofLBDcg1ZD5LJ@hzgm3kQVAMp2VNjZ$`&J%!pP>j5#V z2V@W}(JIh{Q=&f5#V@o}m#3^-Hb-KCL-HSBg{Ru-_OFAAe*~EHfgewb{_q*`kMNw> z3nyxOeMj$Hd^$M%;N0%uL|syor|!y6Q=<y8n(u#iuV>)C-tmF{I7R>5Q}Cq^^m{S!_wd`(&lD{=vOgkq zod7oPf{jvq>|gus^5BR^j{RrpW{WvRofkw)17? zA8)#`+!`@>iTl7kOB~#GcvWz6+~B+dFj_`bL$d(+IR*bBB`d~i7C!|JLISrd5X0JY z_X-Jc%8o$|W&s#J4<{9 delta 1453 zcma)6O>7%Q6yDjL_3wIPw|2biIEfP{rQ1-aCTate@)N~I0c1$YfgIY@wKuiX*p6mR z(?l(4PXsA|s*w;ol#zfwlC_ z%-i?AdGCF1{Z{oOQ@t7p_yqoRou8WjzW1E^H)>D??LZznhTiFx;8o}G@DXWHI9f+F-bj?s5xzIffg8TQ}A$@_>muU_RroBIWu zYz+w;{Kl2eFDW2lR@nIUq%I+b}o~f$sEl70zG25Qm&fJJ5Nm0 zTFMtp!_ROvUon}dY|WXKrTPkiCNU2&Pnh{dv&ei$Yk5+fv&yR`lL^)PqDPoy)d|B^ zskY2qjw8dRa?v#01nOkovD?(rL!v80_Z4n862f~p zC?kKg!l-xno5avxEydaVX=yy&&y(X>7rv~FX9M_(OU(M*R{~--E*DhX1Pu;f=(%D?@n&BVjQ3)U340EBb6SO zboz!E$pG<;fyfSsegHi0Ve8@Nd)Yv`2f@e7fwM(>*755KQO|v*(~I3_X-nQspO03i z?hcxPb2C{Yb8kZ?5x&@CVpn0`$h=jM^JtA&4bd)!^aH=hA;C+c?`cVO6fA@TzcCo5 zH?%6x|0+ri2?X@#$%kQa;+YI{S=?fHQtS`!1%^(}VV&pfC2F&Tzw*1Fvp7dT4IbQX zc$ueGowKKmfHU#YL}*|b$jL4M=ppkKN_mnm)J{vtBhlt}p-UL6{7v)y#C~<{z6RO-A^Z7D!{fBZzU?t?=;Q&r0|1W$!~sS)+%0m` zx*FV4-ub`|f!nuS0Ny(-zK%Bnd<5QXj_&zV=1u%(@5tm65NxXtv*i>TfZY%P%oBkz zAfP(|Daca*kVHcuP!gA^x^HYEB4rz1a4D0S~=ee*gdg diff --git a/__pycache__/mine.cpython-312.pyc b/__pycache__/mine.cpython-312.pyc index 354f038160fa360bb15ca80a38c4295994db353b..9efde473ffd67e405063a8cdf5c579cc20d17520 100644 GIT binary patch literal 2624 zcmbtW&u<$=6rQ!$&f2kKr%h0Qpms}X%BCeQqLhM2L`9mCLUKUi&`8y4vorN>Z10+# zb%L!R<mk1DyB+xDXl?YsCSH6Sv5bK;Aea-C4=L9DHrCH0sVHzRxe zmO^1?96GCnky(k7*%*~(<1{ua)A)5Vo1ijak|qFqXcADNJ%A~y0H$dQu$QI*Gxc6A z6UbAx!vZp6hG9hr?8o7=vrhzCl9q@r6bN;qNzr+zU?|%ERZ=XU-Ocnz+Oo;%M>UoRRJ z7>8wzRO^AF>o#b0y^+P0jzl76mZt!gN%MeuL%x;W0f9WnHY6?9IFnYxc7b!d=%|M3 zKy=l2p;xpQn4^k?bj)z$GMZ>HuLt4<2^46!YY$GD1U)#US6Cw>Rvb!MQ1M=XWwNc1 z!9%d*l!v=8G1E~)2O{$maM-J4Nt%x|UEfq%Al{ctvH9+qp`OMbgfy9tDAqM|i9Btz z^a>%~ypQ`4jm9G%W9;EWkow@_75(D$%*Bs_WZU*HJk&s%3S^{CxR{uRSRmt`0?Foh`nc;hC-au!&@$6IhK)f%&b`C?VHUpwAXu6iyghbv zY^}7>JKW6e-^!iX$ep-vJ<1ifa_2X4=YJUgY3j$RUvrbcA3U<=eRHryr2fm&%7x~{ zq5Gdc%AeWHzun9a ztSWbuUk<*pnLif_U!}KuN&d359VeMn?Yq)lrI7vj*;xS)cO@#2AV&=t-#sTBjyS{> zinXm{QIErodu}hDLSwtV)Z?1m_`1WoDWk+xUh~?NLRui%ESpj&FpCzzQ>bS9BdVY) zm^zG6pe2^2a@k$%Hixkau&EO(q$#huKDvgOZO%f(k&e;C%(NB{6r1a;QuXU?w)Ie( zSIb6yy`@3R?=bx?l60MxS6$M?Q+CZvp^q(xiWIHG3z!M(F=2k5@@uT8}lp=&V1=iwWs~ zyv#AvsBxxFs*46!aS$FEND^eO!hFjG3j?pU3k4qj@uHpNYS}dne7{bsb2T64Qr9`@ zi&SHNJF&!ZL6#{b->HLBr}!k1)9Yki5|@zU>ciWX^wL zAGYkB0CR5$;UqwJ1esgzVk0H|WA_XiVTk|f7C6a5x7fua?Q+|>Coqg{*8z2{_9f8m zVouJqm|4;tW*4nF*W--=vGP5mV=(PWv}rAiufKRc^&qY56_?hagy}&>*FUKl<+jGd zA5ekPPBNn&zDHgk!V!ey2=KlU?-atT2n7U@RxH(`Kzg_p0pdr@S&*)iW`5uDBow~o z_gk`*IMzzai9@YSI&rvlKuM^rfkYzP>Wg3pdm{V74g64O``jJpvGPuP8)F{EK+bS{ S!=Nro(m$C|Dcd3d!q2}^x;ugZ delta 917 zcmZ8gzi-n(6!!T?ViPBA)u1W`+M|LBw-CWlb)bT&pi&5^>e9(F@ij3`;&OJ25+PBE zr3?sFxAG4}-I*EKDv;RF{ReDSIv~Nqd*`SM*z)K1-o5vI@1D<}%kRcYC&l6g4X%Ta zYug`;qtZ#GPih{K_HLX+X%u%nU787NZS(xm;O&%wxx))>e9k^;;=Vph)`hP>wdP*y zFY@BMKKaHtCRrxYAm$9KMqbB5n`m8iduB~K>#JM-YHf3ML+0vxJc)U4dMn zhZF?0>0OQIAlldZM3p8uM`#dGn$0L=J?9AwqKak(f@c;0^lQ7&+)Gm3$m%`9$6&$B z^reMU3C}w~vOI?THtV^HZ|Gfyr3A%*vRpYd-#bA2&8C%%mg71{-E%IHcNPk>7*;U4 zi7fjHW{>P5$Jss$TD^kO&78S^>z7B>{;xNaX8dY61vIaZ)UG%SYtpGV10K{<#-*Ln zvykIK=NA#C5oQpS>NT|H5pE!;4HnRHMBiC#T^hKiMF%diih~@nrV*4?JVT4CR6IuT n<8XYBGJyNrUTMeSUW?u1Rd8_*34WPVgAnq|rKC8}02I$(;(f{8 diff --git a/__pycache__/spawner.cpython-312.pyc b/__pycache__/spawner.cpython-312.pyc index c9c381d5ae6fbdf6940448ddc3f756ec47713b07..80365de3602051b4d3dc8ee835fd7d6d6630b3bf 100644 GIT binary patch delta 1651 zcmZuxO>7%Q6rNfCt?jk5NtzNjsXC!aD?@5R0hOOnHEBv56_rZ#Ko2O|*b`@)^{zX+ z8_Q9sD^Vd;AVt+2hy({N91t9+xNw0RCoYNDipWwVDsdnelqMh~t4O?A*PBphBtOmj z=FOY;zW1$v?B5tl|C~xC5UjELGxHxQ_tV`He$0t9oY{6l0vD?&eT`eYDfE8xyIJWE zoL&jFF^oQW%s0Xx<7fCpL7uFOjA{9z&y+hROS0#k2<%eqM$@p(q6UC|1(IeN_^WowC! z64$1FB8@StN)~C&&XMbuOUhb}ENDw`Xf>a!FlvipNDu|LnYaj;Wfnw~pD))OyJ}Dk za+bA4N^DmI)uGOU%WR7g-7g)$8az?eOo!-B^UNHb7ujrTQ0UJr5smm|<_MJ8LfgHpj6GGZ7KyK)WwYU*X+7-*OnUaiLY$EYc#Gs}a*J&rxRQ zmb3m_q9+RF|Br30r0M1;3_`G==L&(qfn2fgh2P$vh!07F@)BaD73oHZYq8$0K>rv8 z*a7_qSa@F_0Twv~JE+_zZ`2P+w|Q^lzY;wc(*HV9gN{@sdJH7Uzg46Qcnk9XX#3Q+j@+|$9YLJGTpkb!Qa z9T};a)mwLOeQ|Q5>(r)tcyq=l%)O_Gv^3=Bi=d!219XNSUojKgO@Ial|Ng?$# z>w(v;xFTDi0>vFzjp@4B_9(FObjS6ZA_|)L)YW z8_9vSo4+K~D&? zn!lT0@4M(JQ=4sP!c!&#XWCQpfivYPmkxKvJ>|{dZy$Ydax~@!tx<16!zX3z039`6ql1PvTu9te@aNVG_Nr delta 629 zcmcbpxKD!bG%qg~0}yPU<(a0&v5`-ZiLqm{0+WjLrV?h5I0&RLt!9LLZ&Jvp}$Rfp&!de9sE8(9k勉|NiBuoi{u3?55#t1a5$9i%h ztM23mmN-V~$@f|G8QCWDv)VFBPWEMO=aq%&s$tBMpZt*3k`Y9zOtxoZXH=Z*&Zdaq zPoBgsJXx2GWAb`7ZbsF~yV?AKW^l91SyeJrGH9~Rz@B zxF{KLMIi8ofXH;diF`9kt_i4o;AiJm{US73m9L&rVDeJF3mjK@ls=d;@F-5c$!~3< z1+;o4Ly-`WDiQz@958|#$S4*B5-kij_=FqWKd~^e+I;4aVO5^&DWICD0aC{bA~Zn+ z8;Ahw)d#WQ=KbQZ$<0qG%}KQ@G6YJ10=F0xTOXJi85zIwFfdBrWe~l~pm3K#@;i$% Mqw*&PAOY460PusB!2kdN diff --git a/cursor.py b/cursor.py index c5f11f0..bf3ebc3 100644 --- a/cursor.py +++ b/cursor.py @@ -2,6 +2,7 @@ # ------------ # By Cory # This module defines a cursor agent class. + class Cursor: name = "cursor" character = 'O' @@ -11,8 +12,10 @@ class Cursor: self.position = position def handle_keystroke(self, keystroke, game): + ''' + Move the cursor using arrow keys. + ''' x, y = self.position - if keystroke.name in ("KEY_LEFT", "KEY_RIGHT", "KEY_UP", "KEY_DOWN"): if keystroke.name == "KEY_LEFT": new_position = (x - 1, y) @@ -25,9 +28,10 @@ class Cursor: if game.on_board(new_position): if game.is_empty(new_position): self.position = new_position - game.log("The cursor is at " + str(self.position)) - for i in range(10): - game.log("mine"+str(i) + " is located at " + str(game.get_agent_by_name("mine"+str(i)).position)) def hide(self): + ''' + This is called because I was calling this method based on an agent's location, but I don't need the + cursor to do anything. + ''' pass \ No newline at end of file diff --git a/free_space.py b/free_space.py index bc3d7cd..c5565e5 100644 --- a/free_space.py +++ b/free_space.py @@ -14,46 +14,28 @@ class FreeSpace: self.position = position self.width , self.height = position - def handle_keystroke(self, keystroke, game): - if keystroke.name in ("KEY_ENTER"): - if not game.is_empty(self.position): - if self.revealed == False: - board_width,board_height = game.board_size - for i in range(10): - game.get_agent_by_name("mine"+str(i)).show() - for i in range(board_width): - for j in range(board_height): - try: - game.get_agent_by_name("freespace"+str(i)+str(j)).show() - except: - pass - self.reveal(game) - for i in range(board_width): - for j in range(board_height): - try: - game.get_agent_by_name("freespace"+str(i)+str(j)).hide() - except: - pass - for i in range(10): - game.get_agent_by_name("mine"+str(i)).hide() + def name_me(self, named): + ''' + Give a free space a name.''' + self.name = named + + def show(self): + ''' + Used to turn display on. Necessary to be able to call upon a space based on its position. + ''' + self.display = True def hide(self): + ''' + Used to hide free spaces only if they have not already been revealed. + ''' if self.revealed == False: self.display = False - def show(self): - self.display = True - - def play_turn(self, game): - if (not game.is_empty(self.position)) and self.revealed and self.display == True: - self.display = False - elif game.is_empty(self.position) and self.revealed and self.neighbors > 0 and self.display == False: - self.display = True - - def name_me(self, named): - self.name = named - def check_neighbors(self,game): + ''' + Used to determine the number that should be shown when the space is revealed. Counts neighboring mines. + ''' names_of_mines = ["mine0","mine1","mine2","mine3","mine4","mine5","mine6","mine7","mine8","mine9"] if game.on_board((self.width + 1,self.height)): if len(game.get_agents_by_position()[(self.width + 1,self.height)]) != 0: @@ -90,7 +72,54 @@ class FreeSpace: if self.neighbors > 0: self.character = str(self.neighbors) + def play_turn(self, game): + ''' + Make sure a number is hidden when the cursor is over it. This is needed to allow the cursor to move + over a spot where a number is. + ''' + if (not game.is_empty(self.position)) and self.revealed and self.display == True: + self.display = False + elif game.is_empty(self.position) and self.revealed and self.neighbors > 0 and self.display == False: + self.display = True + + + def handle_keystroke(self, keystroke, game): + ''' + When a space without a mine is selected, use a recursive algorithm defined below to reveal spaces. + Then, check if all non-mine spaces have been revealed; if so, the game has been won. + ''' + if keystroke.name in ("KEY_ENTER"): + if not game.is_empty(self.position): + if self.revealed == False: + board_width,board_height = game.board_size + for i in range(board_width): + for j in range(board_height): + try: + game.get_agent_by_name("freespace"+str(i)+str(j)).show() + except: + pass + self.reveal(game) + win = True + for i in range(board_width): + for j in range(board_height): + if len(game.get_agents_by_position()[(i,j)]) != 0: + if not game.get_agents_by_position()[i,j][0].revealed: + win = False + if win == True: + game.log("You successfully isolated every mine! Congratulations! You've won!") + game.end() + for i in range(board_width): + for j in range(board_height): + try: + game.get_agent_by_name("freespace"+str(i)+str(j)).hide() + except: + pass + def reveal(self,game): + ''' + Recursive algorithm to reveal squares. Reveals itself and then if it has no neighboring mines, + it asks all 8 of its neighbors (assuming none are off the map) to reveal themselves. + ''' self.revealed = True if self.neighbors == 0: if game.on_board((self.width + 1,self.height)): diff --git a/mine.py b/mine.py index 086e5b4..bd6727a 100644 --- a/mine.py +++ b/mine.py @@ -10,29 +10,61 @@ class Mine: def __init__(self, position): self.position = position + def name_me(self, named): + ''' + Assign a name to a given mine. + ''' + self.name = named + def handle_keystroke(self, keystroke, game): + ''' + This ends the game if enter is pressed while the cursor is over a mine. + ''' if keystroke.name in ("KEY_ENTER"): if game.get_agent_by_name("cursor").position == self.position: + for i in range(10): + game.get_agent_by_name("mine"+str(i)).character = 'M' + game.get_agent_by_name("cursor").character = 'M' game.log("You hit a mine! Game over.") game.end() def play_turn(self, game): + ''' + Make sure the mine is hidden when the cursor is over it. This is needed to allow the cursor to move + over a spot where a mine is. + ''' if (not game.is_empty(self.position)): self.display = False elif game.is_empty(self.position): self.display = True - def hide(self): - pass - - def name_me(self, named): - self.name = named - - def check_neighbors(self,game): - pass - def reveal(self): + ''' + This is called because I was calling this method based on an agent's location, but I don't need the + mine to do anything. + ''' pass def show(self): - pass \ No newline at end of file + ''' + This is called because I was calling this method based on an agent's location, but I don't need the + mine to do anything. + ''' + pass + + def hide(self): + ''' + This is called because I was calling this method based on an agent's location, but I don't need the + mine to do anything. + ''' + pass + + def check_neighbors(self,game): + ''' + This is called because I was calling this method based on an agent's location, but I don't need the + mine to do anything. + ''' + pass + + + diff --git a/minesweeper_game.py b/minesweeper_game.py index d895b6b..896f281 100644 --- a/minesweeper_game.py +++ b/minesweeper_game.py @@ -1,12 +1,12 @@ # minesweeper_game.py # ------------ # By Cory -# This class implements a simple minesweeper game on a 9x9 grid. +# This class implements a simple minesweeper game on a 9x9 grid with 10 mines. from retro.game import Game from spawner import Spawner board_size = (9, 9) spawner = Spawner(board_size) -game = Game([spawner], {"score": 0}, board_size=board_size,debug=True) +game = Game([spawner], {"score": 0}, board_size=board_size,debug=True) # debug is on so you can see the instructions :) game.play() \ No newline at end of file diff --git a/spawner.py b/spawner.py index af0f797..f1a6743 100644 --- a/spawner.py +++ b/spawner.py @@ -16,26 +16,26 @@ class Spawner: self.board_width, self.board_height = width, height def play_turn(self, game): - # On the first turn we will spawn everything. + ''' + Creates all other agents and prints instructions when the game begins. + ''' if game.turn_number == 1: # First spawn 10 mines for i in range(10): mine = Mine(((randint(0, self.board_width - 1)),(randint(0, self.board_height - 1)))) mine.name_me("mine"+str(i)) - while not game.is_empty(mine.position): + while not game.is_empty(mine.position): # Ensure mines are not in the same location mine = Mine(((randint(0, self.board_width - 1)),(randint(0, self.board_height - 1)))) mine.name_me("mine"+str(i)) - game.log(str(mine.name) + " is located at " + str(mine.position)) game.add_agent(mine) - # Then spawn free spaces everywhere + # Then spawn free spaces everywhere there is not a mine. for i in range(self.board_width): for j in range(self.board_height): if game.is_empty((i,j)): free_space = FreeSpace((i,j)) free_space.name_me("freespace"+str(i)+str(j)) game.add_agent(free_space) - # Now ask all free spaces to keep track of their neighbors that are mines - # and all of the mines and free spaces to hide themselves. + # Now ask all free spaces to keep track of their neighbors that are mines and hide themselves. for i in range(self.board_width): for j in range(self.board_height): if len(game.get_agents_by_position()[(i,j)]) != 0: @@ -44,3 +44,10 @@ class Spawner: # Now create a cursor. cursor = Cursor((self.board_width - 1, self.board_height - 1)) game.add_agent(cursor) + # Print instructions. + game.log("To move, use the arrow keys. You may have to") + game.log("press an arrow key more than once to move.") + game.log("Please make sure the cursor is where you want it") + game.log("before selecting a space. To select a space, ") + game.log("press return. The game is over when all spots") + game.log("with mines are surrounded by numbers.") \ No newline at end of file