From 2af3d6c2e76fb90b214c98907d6ff982e3f94d8a Mon Sep 17 00:00:00 2001 From: ilmabura Date: Sun, 7 Dec 2025 16:17:56 -0500 Subject: [PATCH] Last milestone completed Completed the project. I wanted to replace the player with a penguin, but it didn't fit the maze, so I kept it as an '>'. It shows where you begin and where you need to go to finish, and each game is a different maze. I thought this was very difficult and i needed to learn how to make a maze, I was not prepared for that. --- __pycache__/markers.cpython-312.pyc | Bin 0 -> 1010 bytes __pycache__/player.cpython-312.pyc | Bin 1538 -> 2439 bytes __pycache__/wall.cpython-312.pyc | Bin 597 -> 624 bytes escape_the_maze.py | 27 ++++++++++++++--------- markers.py | 24 +++++++++++++++++++++ player.py | 32 ++++++++++++++++++++++------ wall.py | 1 + 7 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 __pycache__/markers.cpython-312.pyc create mode 100644 markers.py diff --git a/__pycache__/markers.cpython-312.pyc b/__pycache__/markers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9dde5b5336dad1ff28f02c13af720990b10989d GIT binary patch literal 1010 zcmbtTJ#W)M7`}7t#7z?ls8neX$c3Sbgkmbhh8U0tLV_@K^Kx>0m)gYkg|kDHs6&Pf zEX@547XO2VKTvr>;t#ZVsMLvjZ6_+w1#ya>JnyI9dms5*vsp*-w7x#|9x4d^0AqF3 zl4Or0IYA0~g(zAgioeKAI9B0Pq_48};hEaeoFbt>TpHN}Nlp+$7N*EjD7Gq8u~b^I zG^$!vsx6UKn^iltbn`H_Mf}zlBPQmL>xMjU>;dy5BX*e)LD1mC+z9MBGp1hb8vD_H zH&0FRVcHOk5+0JN>&2|+lmq930I$d=yPc17jE@n?0{}CW;C_Nreas^-_IQ{msTwhV zC^lp?f?C74d||pgVCG;VY)}5oz#e(w5rHv?!znX^sdHdXLN9(|js<_uoR}QhvLeW@ z6m`e5R42rf353kIuiUn~^1|yffCc*AGCrxFo0&9FKhdEwl+6f9>x2ZHPJG}ELOx7v zzl_ufq1=(~4ac>G?Zix^n!|lA(yf8dolzt!KeB*@v1rP^2@+fKPc#5vJ2`-I(LD)E zbgn3xepW@dwimBYH+L5=Pj~Jv-eszy?G=?!^q;afdU7L?Tk3xBr|!c%dX4bIweY>Q z@B`m=M*k$dsKK>$0Qe?Kt&5GoispB&j<*(S2MTTgzykZ?CeYT(F3Q_r0zlq%3vIOj wUMS@EJ4&HO-r@JIm-@3p{O97nOwG00mE^2~F}_ghc<&rZxM)lG2`nG*7hpl?P5=M^ literal 0 HcmV?d00001 diff --git a/__pycache__/player.cpython-312.pyc b/__pycache__/player.cpython-312.pyc index c3ad2557c73052b6583ca44f13e861f4805f46f0..927c78fb2e6f8f25a00b2487d94a8da79a9ae20f 100644 GIT binary patch literal 2439 zcmaJ?%}*Og6rZ(s{q5Qclu*dW5RsG(2^RUN+9pA21Nl%1K`Buh(q^^U9qbMEE}312 z+Fc|L9E=o+MpcC)^}w+emmK>SR8@NkBvIT|4oE$+hMSXLg*sW(Hzo+<&du#N0pEq)|zprouWfE*VWD2VeR z>WXbt35|n|Crul=Q}7}MV&n^sEx{a%8-Ddku3(i&?oOGi2K;j+brNEsOdC!?(JY5&NbpUQAI8&?`zckJ4QjEFw3=zPsBX`l_47&e@8u8`cFqv>eDY zqAR+>WDl$_JZRg23hQDM1-fnlRYVb0Bso(3foBN|%QfPZscGXeS|-?-U>8kcU}Mw5 zcZ!zAViaUs59!PI9m6-&Vo`?N0w};7qZs5I^EP6c$9G!UxTk1LvOH9&lbe9>*#%ru z=_H}Hj8(Q)-n1yu{e)spXbfU7;$^raTPZ;H^-)fsUW^HYS8t5?qv4?oV_uxiUAuho(%6_62IH!H-ZJx4b;?DR zF}vM`Z(8N|?-NY;)1q_oFTvZ=jo#q2L|jg^8)l z5niKSoIN%UwV?Fh1)L{*?FkhxWs>PFTDKV`G7bP1;I*19z-fy_*)px}4GMO*;s99M ze?!NsHru)|Ge0vg)`VJrV{d0IwU%sM7?>ZZf3cc8+}O9jes8J&QMvx{{BR@Pws3p? zcD=fqmj6$&Bs>~g>fdhh&1(86STq&2;kD%6C&`12)Sk6uX5rlYx%$3m$s<3WdeM7k zrT5Iw!@qVv>%H38*HasOaAhsi!Zx@hzQ89|@QKyTiAHzNx8h>rVWNI|CEL~L`8<$5 zTFD-6WLp=se{sMl=qJRz^5|1WRJ>yhWFLZV4*e4nrPz83rCMhP z8`+lG%NwF7^=_mRQtM`Wht%ntGs_WK@ICY~H;f6n*H^K#{uT#l4(1pY*lZ8$VL=f7 N6+aLFHv delta 605 zcmXv~PiqrF9G%&n{nJf0meyh@sjc=8E^03-@zC^=peR~A3QEIvcWl;fvSDUz-H>3A zg6W}1SV2F6Jy;JS^g9Srq=zskKSFE{LQkF9G;f&4Z{Ey%^PBlF`97WbWts-y`1A9g zS3=#)6S&ZQv6zWeOJnLY-;OY8tam@H=b2hhR%dY4k%Z#{qL%p_P56>4EvY5D zunEc__Tls$$n<(Zz0eD47Gj8E{}nSf0-LyH>NPM^c04z%Ftvic%}PiSPl|uTjlAfL zPH<|2zuD`1W=H94_p(YOBrAH~0O`x^Qg3{+{pb|Q%Iv_nqF6(xFs)f|Xr31d;^HLm gOkb%6?i(M^uaX5WCb43-FGC3bON-Dt1)LJcIph$NDgXcg diff --git a/__pycache__/wall.cpython-312.pyc b/__pycache__/wall.cpython-312.pyc index d667fe8cdb3ba06143468bf35bfe89b2889a9bad..28d2e07890cb4bdd9e52641759540fd60d638063 100644 GIT binary patch delta 188 zcmcc0@_~i#G%qg~0}x0bGtJ~=oXF>+A_wG6XGmp;VoYI(VoG6*VoqU-Vo70+VohOb zVTfX@WYuJwSQWz>DAwS4Lrki{|1(fPv4|5WS;Pz^{4^QCbdkVh872uuL7)&L5Et_U Vi4V+-jEvuzI2aW_F#rj$CIFLTDMkPQ delta 178 zcmeysa+QVeG%qg~0}y=NVVe1hVIrT8f)tQ9ogtMWiZO*DiYbLLiaCWTiY0})g&~Ty zl0}nsVqMI{+bgBmfXa$FfkXqt0||u=mR{b^Kn{bSCfnqBj24rhGb#uP1NkisADNg~ zIX_7lCvZu>*-;95%W6DWy57c0~d}E+Y^ZgH(KAW@Kdi&cx2B L_=y2XfHeRBqW&gO diff --git a/escape_the_maze.py b/escape_the_maze.py index c8e850b..fbf42b4 100644 --- a/escape_the_maze.py +++ b/escape_the_maze.py @@ -3,21 +3,19 @@ import random from retro.game import Game from player import Player from wall import Wall +from markers import StartMarker, FinishMarker def generate_maze_grid(width, height): """ Generate a 'perfect' maze on a width x height grid. 1 = wall, 0 = passage. - - Uses depth-first search on a grid of cells spaced 2 apart, - which gives a nice twisty maze like your example image. """ grid = [[1 for _ in range(width)] for _ in range(height)] for y in range(1, height - 1, 2): for x in range(1, width - 1, 2): - grid[y][x] = 0 + grid[y][x] = 0 visited = set() @@ -47,7 +45,7 @@ def create_maze_walls(board_size): center_x = (width // 2) | 1 center_y = (height // 2) | 1 - grid[center_y][center_x] = 0 + grid[center_y][center_x] = 0 end_position = (center_x, center_y) wall_positions = [] @@ -63,26 +61,35 @@ def create_maze_walls(board_size): def main(): board_size = (100, 40) - player = Player(board_size) - walls, end_position = create_maze_walls(board_size) print("Exit (goal) will be around:", end_position) + start_position = (1, 1) + + player = Player(board_size, end_position) + + start_marker = StartMarker(start_position) + finish_marker = FinishMarker(end_position) + state = { "win": False, + "message": "", } game = Game( - agents=[player] + walls, + agents=[ + start_marker, + finish_marker, + player, + ] + walls, state=state, board_size=board_size, - debug=True, + debug=False, framerate=24, color="white_on_black", ) game.play() - if __name__ == "__main__": main() \ No newline at end of file diff --git a/markers.py b/markers.py new file mode 100644 index 0000000..4f52ed3 --- /dev/null +++ b/markers.py @@ -0,0 +1,24 @@ +class StartMarker: + """ + Labels the start of the maze with 's'. + """ + character = "S" + color= "red_on_white" + blocks_movement = False + + def __init__(self, position): + # position is a tuple (x, y) + self.position = position + + +class FinishMarker: + """ + Labels the finish of the maze with 'f'. + """ + character = "F" + color = "red_on_black" + blocks_movement = False + + def __init__(self, position): + # position is a tuple (x, y) + self.position = position \ No newline at end of file diff --git a/player.py b/player.py index 3ef3627..2122aea 100644 --- a/player.py +++ b/player.py @@ -1,21 +1,36 @@ + class Player: """ Player agent for Escape the Maze. Moves one step at a time using the arrow keys. + Ends the game when it reaches the goal position. """ name = "player" - character = ">" # 🐧Penguin icon + character = ">" - def __init__(self, board_size): + def __init__(self, board_size, goal_position): # Start near the top-left corner width, height = board_size self.position = (1, 1) + self.goal_position = goal_position + + def can_move_to(self, position, game): + """ + Returns True if there is no blocking agent (e.g., Wall) on this tile. + Non-blocking agents (like start/finish markers) are ignored. + """ + for agent in game.agents: + agent_pos = getattr(agent, "position", None) + if agent_pos == position: + if getattr(agent, "blocks_movement", False): + return False + return True def handle_keystroke(self, keystroke, game): """ - Called once for each key pressed since the last turn. - Moves the player using the arrow keys. + Called for each key pressed since the last turn. + Moves the player using the arrow keys and checks for win. """ x, y = self.position new_position = None @@ -29,10 +44,13 @@ class Player: elif keystroke.name == "KEY_RIGHT": new_position = (x + 1, y) - if new_position is None: return + if game.on_board(new_position) and self.can_move_to(new_position, game): + self.position = new_position - if game.on_board(new_position) and game.is_empty(new_position): - self.position = new_position \ No newline at end of file + if self.position == self.goal_position: + game.state["win"] = True + game.state["message"] = "Congratulations! You've escaped the maze!" + game.end() \ No newline at end of file diff --git a/wall.py b/wall.py index d9c2b5e..cb98365 100644 --- a/wall.py +++ b/wall.py @@ -3,6 +3,7 @@ class Wall: A simple wall tile. It just sits on the board and blocks movement. """ character = "█" + blocks_movement = True def __init__(self, position): # position is a tuple (x, y) self.position = position \ No newline at end of file