Source code for ttt.models.game

import numpy as np
from loguru import logger
from colorama import init, Fore

from .agent import Agent
from .action import Action


[docs]class Game: """ Class modeling. Attributes ---------- grid: numpy.ndarray player_1: ttt.models.Agent player_2: ttt.models.Agent result: int grid_is_full: bool game_sequence: list Parameters ---------- player_1: ttt.models.Agent player_2: ttt.models.Agent """ def __init__(self, player_1: Agent, player_2: Agent) -> None: self.grid = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0]) self.result = -1 self.grid_is_full = False self.player_1 = player_1 self.player_2 = player_2 self.player_1.update_grid(self.grid.copy()) self.player_2.update_grid(self.grid.copy()) self.game_sequence = [self.grid.copy()]
[docs] def apply_move(self, move: Action, player_id: int) -> None: """ Commits the move over the board. Parameters ---------- move: ttt.models.Action Move to be performed. player_id: int Value to apply. """ self.grid[move.value] = int(player_id) self.player_1.update_grid(self.grid.copy()) self.player_2.update_grid(self.grid.copy()) self.check_victory() self.check_if_grid_is_full() self.game_sequence.append(self.grid.copy())
[docs] def check_horizontal_win(self) -> None: """Checks if there is 3 consecutives marks of the same player horizontally.""" if self.grid[0] == self.grid[1] == self.grid[2] and self.grid[2] != 0: self.result = self.grid[0] if self.grid[3] == self.grid[4] == self.grid[5] and self.grid[5] != 0: self.result = self.grid[3] if self.grid[6] == self.grid[7] == self.grid[8] and self.grid[8] != 0: self.result = self.grid[6]
[docs] def check_vertical_win(self) -> None: """Checks if there is 3 consecutives marks of the same player vertically.""" if self.grid[0] == self.grid[3] == self.grid[6] and self.grid[6] != 0: self.result = self.grid[0] if self.grid[1] == self.grid[4] == self.grid[7] and self.grid[7] != 0: self.result = self.grid[1] if self.grid[2] == self.grid[5] == self.grid[8] and self.grid[8] != 0: self.result = self.grid[2]
[docs] def check_diagonal_win(self) -> None: """Checks if there is 3 consecutives marks of the same player diagonally""" if self.grid[0] == self.grid[4] == self.grid[8] and self.grid[8] != 0: self.result = self.grid[0] if self.grid[2] == self.grid[4] == self.grid[6] and self.grid[6] != 0: self.result = self.grid[2]
[docs] def check_if_grid_is_full(self) -> None: """Checks if there is no more possible move.""" count = 9 - np.count_nonzero(self.grid) if count == 0: self.grid_is_full = True if self.result < 0: self.result = 0
[docs] def check_victory(self) -> None: """Checks if there is 3 consecutives marks of the same player.""" self.check_horizontal_win() self.check_vertical_win() self.check_diagonal_win()
[docs] def print_board(self) -> dict: """Displays the current grid.""" init(autoreset=True) positions = {} for index, value in enumerate(self.grid): if value == 1: mark = f"{Fore.RED}X{Fore.RESET}" elif value == 2: mark = f"{Fore.CYAN}O{Fore.RESET}" else: mark = f"{Fore.GREEN}{index + 1}{Fore.RESET}" positions[f"p{index}"] = mark logger.info(""" {p0} | {p1} | {p2} ----------- {p3} | {p4} | {p5} ----------- {p6} | {p7} | {p8} """.format(**positions)) return positions