Untitled
unknown
plain_text
8 months ago
6.6 kB
3
Indexable
# AUTHORS: Filip Labuda, Jędrzej Stańczewski # RULES: Players take turns placing their pieces on a 5x5 board. Each player has 12 pieces to use. # After all pieces have been placed, the player who has formed the most three-piece combinations in a row wins. # ENVIRONMENT SETUP: The program requires the easyAI library to run. # You can install it using the command "pip install easyAI" or "pip3 install easyAI". from easyAI import TwoPlayerGame, AI_Player, Human_Player, Negamax class ThreeInARowGame(TwoPlayerGame): """ Attributes: players: A list of players. board_size: Size of the board (5x5). board: A list representing the board with each cell initialized to empty (' '). current_player: The player whose turn it is (1 for player 1, 2 for player 2). total_pieces: The total number of pieces each player has to place (12 per player). men_to_place: A list containing the number of pieces left to place for each player. """ def __init__(self, players): """ Initializes the game board and players. Args: players (list): A list containing the players (either AI or human). """ self.players = players self.board_size = 5 self.board = [' '] * (self.board_size ** 2) # Initialize a 5x5 board self.current_player = 1 # Player 1 starts self.total_pieces = 12 # Total pieces each player has self.men_to_place = [self.total_pieces, self.total_pieces] # Pieces left to place for each player def possible_moves(self): """ Returns a list of possible moves (empty positions) on the board. Returns: list: A list of strings representing the indices of empty cells. """ return [str(i + 1) for i, cell in enumerate(self.board) if cell == ' '] def make_move(self, move): """ Places a player's piece on the board at the specified position. Args: move (str): The index of the cell (1-based) where the current player wants to place a piece. """ index = int(move) - 1 self.board[index] = self.current_player_symbol() self.men_to_place[self.current_player - 1] -= 1 def unmake_move(self, move): """ Removes a player's piece from the board (used for undoing a move). Args: move (str): The index of the cell (1-based) where the piece should be removed. """ index = int(move) - 1 self.board[index] = ' ' self.men_to_place[self.current_player - 1] += 1 def is_over(self): """ Determines if the game is over. The game is over when both players have placed all their pieces or there are no possible moves left. Returns: bool: True if the game is over, False otherwise. """ return sum(self.men_to_place) == 0 or not self.possible_moves() def show(self): """ Displays the current state of the board as a 5x5 grid. """ for i in range(self.board_size): row = '|'.join(self.board[i*self.board_size:(i+1)*self.board_size]) print(row) if i < self.board_size - 1: print('-' * (self.board_size * 2 - 1)) def scoring(self): """ Calculates the score of the current player based on the number of "three-in-a-row" they have. Returns: int: The score, where each "three-in-a-row" gives a point. """ counts = self.count_three_in_a_row() score = counts[self.current_player - 1] - counts[1 - (self.current_player - 1)] return score def current_player_symbol(self): """ Returns the symbol associated with the current player. Returns: str: 'X' for player 1 and 'O' for player 2. """ return 'X' if self.current_player == 1 else 'O' def count_three_in_a_row(self): """ Counts the number of occurrences where each player has three connected pieces horizontally, vertically, or diagonally. Returns: list: A list of two integers where the first element is the count for player 1 and the second is the count for player 2. """ counts = [0, 0] # Index 0 for Player 1, Index 1 for Player 2 b = self.board size = self.board_size lines = [] # Collect all possible lines of length 3 # Horizontal lines for i in range(size): for j in range(size - 2): lines.append([b[i*size + j + k] for k in range(3)]) # Vertical lines for j in range(size): for i in range(size - 2): lines.append([b[(i + k)*size + j] for k in range(3)]) # Diagonal lines (top-left to bottom-right) for i in range(size - 2): for j in range(size - 2): lines.append([b[(i + k)*size + (j + k)] for k in range(3)]) # Diagonal lines (top-right to bottom-left) for i in range(size - 2): for j in range(2, size): lines.append([b[(i + k)*size + (j - k)] for k in range(3)]) # Count occurrences for each player for line in lines: if line.count('X') == 3 and line.count('O') == 0: counts[0] += 1 elif line.count('O') == 3 and line.count('X') == 0: counts[1] += 1 return counts def win_message(self): """ Determines the winner based on the number of "three-in-a-row" sequences each player has and prints the result. Returns: str: A message indicating whether player 1 won, player 2 won, or if it's a tie. """ counts = self.count_three_in_a_row() print(f"Player 1: {counts[0]}, player 2: {counts[1]}") if counts[0] > counts[1]: return "Player 1 wins!" elif counts[1] > counts[0]: return "Player 2 wins!" else: return "It's a tie!" # Main game logic if __name__ == "__main__": """ Entry point for the game when executed as a script. Initializes the game with a human player and an AI player, then starts the game loop. """ ai_algo = Negamax(2) # Depth of 2 game = ThreeInARowGame([Human_Player(), AI_Player(ai_algo)]) game.play() print(game.win_message())
Editor is loading...
Leave a Comment