diff --git a/src/game/game.py b/src/game/game.py index 6ba22bd..f1d9e1c 100644 --- a/src/game/game.py +++ b/src/game/game.py @@ -30,6 +30,13 @@ def play() -> None: class Game2048: + """ + Initialize the 2048 game board. + + Parameters: + - size (int): Size of the board (default is 4) + """ + def __init__(self, size: int = 4): self.size = size self.board = np.zeros((size, size), dtype=int) @@ -39,13 +46,25 @@ class Game2048: self.add_random_tile() def add_random_tile(self) -> None: - """Add a random tile to the board.""" + """ + Add a random tile (either 2 or 4) to a random empty cell on the board. + The probability of getting a 2 or 4 is determined by the Config.tile.probability weights. + """ tile_value = random.choices([2, 4], weights=Config.tile.probability)[0] tile_row_options, tile_col_options = np.nonzero(np.logical_not(self.board)) tile_loc = np.random.randint(0, len(tile_row_options)) self.board[tile_row_options[tile_loc], tile_col_options[tile_loc]] = tile_value def move(self, direction: Direction) -> tuple[bool, int]: + """ + Move the tiles in the specified direction and update the score. + + Parameters: + - direction (Direction): The direction to move the tiles. + + Returns: + tuple[bool, int]: A tuple indicating whether the move was successful and the updated score. + """ match direction: case Direction.LEFT: return self.move_left() @@ -57,6 +76,12 @@ class Game2048: return self.move_down() def move_right(self) -> tuple[bool, int]: + """ + Move tiles to the right and update the score. + + Returns: + tuple[bool, int]: A tuple indicating whether the move was successful and the updated score. + """ self.board, moved = self._move_and_merge(self.board) if moved: @@ -64,6 +89,12 @@ class Game2048: return moved, self.score def move_left(self) -> tuple[bool, int]: + """ + Move tiles to the left and update the score. + + Returns: + tuple[bool, int]: A tuple indicating whether the move was successful and the updated score. + """ board = np.rot90(self.board, 2) board, moved = self._move_and_merge(board) self.board = np.rot90(board, 2) @@ -73,6 +104,12 @@ class Game2048: return moved, self.score def move_up(self) -> tuple[bool, int]: + """ + Move tiles upwards and update the score. + + Returns: + tuple[bool, int]: A tuple indicating whether the move was successful and the updated score. + """ board = np.rot90(self.board, -1) board, moved = self._move_and_merge(board) self.board = np.rot90(board, 1) @@ -82,6 +119,12 @@ class Game2048: return moved, self.score def move_down(self) -> tuple[bool, int]: + """ + Move tiles downwards and update the score. + + Returns: + tuple[bool, int]: A tuple indicating whether the move was successful and the updated score. + """ board = np.rot90(self.board, 1) board, moved = self._move_and_merge(board) self.board = np.rot90(board, -1) @@ -91,12 +134,30 @@ class Game2048: return moved, self.score def _move_and_merge(self, board: np.ndarray) -> tuple[np.ndarray, bool]: + """ + Move and merge tiles in the specified direction. + + Parameters: + - board (np.ndarray): The game board. + + Returns: + tuple[np.ndarray, bool]: A tuple containing the updated board and whether any tiles were moved or merged. + """ board, has_pushed = self._push_board_right(board) board, has_merged = self._merge(board) board, _ = self._push_board_right(board) return board, has_pushed or has_merged def _merge(self, board: np.ndarray) -> tuple[np.ndarray, bool]: + """ + Merge adjacent tiles with the same value. + + Parameters: + - board (np.ndarray): The game board. + + Returns: + tuple[np.ndarray, bool]: A tuple containing the updated board and whether any tiles were merged. + """ done = False for row in range(self.size): for col in range(self.size - 1, 0, -1): @@ -109,6 +170,9 @@ class Game2048: return board, done def display(self) -> None: + """ + Display the current state of the game board and the score. + """ print(f"Score: {self.score}") for row in self.board: for val in row: @@ -116,6 +180,15 @@ class Game2048: print() def _push_board_right(self, board: np.ndarray) -> tuple[np.ndarray, bool]: + """ + Push tiles to the right, removing empty spaces. + + Parameters: + - board (np.ndarray): The game board. + + Returns: + tuple[np.ndarray, bool]: A tuple containing the updated board and whether any tiles were pushed. + """ new_board = np.zeros((self.size, self.size), dtype=int) done = False for row in range(self.size):