diff --git a/__pycache__/cursor.cpython-312.pyc b/__pycache__/cursor.cpython-312.pyc index 4f75f8d..9d714f1 100644 Binary files a/__pycache__/cursor.cpython-312.pyc and b/__pycache__/cursor.cpython-312.pyc differ diff --git a/__pycache__/free_space.cpython-312.pyc b/__pycache__/free_space.cpython-312.pyc index 393eefb..ea5f493 100644 Binary files a/__pycache__/free_space.cpython-312.pyc and b/__pycache__/free_space.cpython-312.pyc differ diff --git a/__pycache__/mine.cpython-312.pyc b/__pycache__/mine.cpython-312.pyc index 354f038..9efde47 100644 Binary files a/__pycache__/mine.cpython-312.pyc and b/__pycache__/mine.cpython-312.pyc differ diff --git a/__pycache__/spawner.cpython-312.pyc b/__pycache__/spawner.cpython-312.pyc index c9c381d..80365de 100644 Binary files a/__pycache__/spawner.cpython-312.pyc and b/__pycache__/spawner.cpython-312.pyc differ 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