import os import numpy as np class Game: def __init__(self): """Initialize a new Tic-Tac-Toe game with an empty game board.""" self.game_arr = np.array([ [" ", " ", " "], [" ", " ", " "], [" ", " ", " "] ]) def update(self, row, column, new_val): """ Update the game board with the player's move at the specified position. Parameters: row (int): The row index of the move. column (int): The column index of the move. new_val (str): The value of the player's move ("X" or "O"). Raises: ValueError: If the new_val is not a valid move ("X" or "O"). """ valid = ["X", "x", "O", "o"] if new_val in valid: self.game_arr[row][column] = new_val self.make_grid(self.game_arr) else: print("Invalid Value!!") def make_grid(self,arr): """ Display the current Tic-Tac-Toe game board. Parameters: arr (numpy.array): The 3x3 numpy array representing the game board. """ print(f""" {arr[0][0]} | {arr[0][1]} | {arr[0][2]} ---------- {arr[1][0]} | {arr[1][1]} | {arr[1][2]} ---------- {arr[2][0]} | {arr[2][1]} | {arr[2][2]} """) def get_current_game(self): """ Get the current state of the Tic-Tac-Toe game board. Returns: numpy.array: The 3x3 numpy array representing the game board. """ return self.game_arr def check_win(self, arr): """ Check if there is a winning combination on the game board. Parameters: arr (numpy.array): The 3x3 numpy array representing the game board. Returns: list or False: If there is a winning combination, returns [True, "X"/"O"]. Otherwise, returns False. """ res_r = self.check_row(arr) if not res_r: res_c = self.check_col(arr) if not res_c: res_d = self.check_diag(arr) if not res_d: return False else: return [True,res_d[1]] else: return [True,res_c[1]] else: return [True,res_r[1]] def check_row(self, arr): """ Check if any row on the game board has a winning combination. Parameters: arr (numpy.array): The 3x3 numpy array representing the game board. Returns: list or False: If there is a winning row, returns [True, "X"/"O"]. Otherwise, returns False. """ # This shouldn't be hard-coded, but # I am doing it to save time for i in arr: if i[0] == i[1] == i[2] != " ": return [True,i[0]] return False def check_col(self, arr): """ Check if any column on the game board has a winning combination. Parameters: arr (numpy.array): The 3x3 numpy array representing the game board. Returns: list or False: If there is a winning column, returns [True, "X"/"O"]. Otherwise, returns False. """ # This shouldn't be hard-coded, but # I am doing it to save time for i in range(3): # Assuming it's a 3x3 grid if arr[0][i] == arr[1][i] == arr[2][i] != " ": return [True, arr[0][i]] return False def check_diag(self, arr): """ Check if any diagonal on the game board has a winning combination. Parameters: arr (numpy.array): The 3x3 numpy array representing the game board. Returns: list or False: If there is a winning diagonal, returns [True, "X"/"O"]. Otherwise, returns False. """ # This shouldn't be hard-coded, but # I am doing it to save time if arr[0][0] == arr[1][1] == arr[2][2] != " ": return [True,arr[0][0]] elif arr[0][2] == arr[1][1] == arr[2][0] != " ": return [True,arr[0][2]] else: return False def check_tie(self, arr) -> bool: """ Check if the game has ended in a tie (draw). Parameters: arr (numpy.array): The 3x3 numpy array representing the game board. Returns: bool: True if the game is a tie, False otherwise. """ if " " in arr: return False else: return True def game_details(self): print("Enter your choice according to this: ") print("1. Top Left") print("2. Top Center") print("3. Top Right") print("4. Center Left") print("5. Center Center") print("6. Center Right") print("7. Bottom Left") print("8. Bottom Center") print("9. Bottom Right") g = Game() win = False map_dict = { 1:[0,0], 2:[0,1], 3:[0,2], 4:[1,0], 5:[1,1], 6:[1,2], 7:[2,0], 8:[2,1], 9:[2,2], } players = {"O":"Player1", "X":"Player2"} choices = [] while not win: g.game_details() g.make_grid(g.get_current_game()) # getting input from player 1 player1 = int(input("Player 1 Enter the Choice(1-9): ")) # Checking if it's already taken while player1 in choices: print("Make another choice! It's already Taken!") player1 = int(input("Player 2 Enter the Choice(1-9): ")) # updating according to the player1's choice g.update(map_dict[player1][0], map_dict[player1][1], "O") # Checking for tie if g.check_tie(g.get_current_game()): os.system('cls' if os.name == 'nt' else 'clear') g.make_grid(g.get_current_game()) print("It's a tie!") break # checking if player 1 won check = g.check_win(g.get_current_game()) try: if check[0]==True: os.system('cls' if os.name == 'nt' else 'clear') g.make_grid(g.get_current_game()) print(f"{players[check[1]]} wins") win=True break except Exception: pass g.make_grid(g.get_current_game()) choices.append(player1) # getting input from player 2 player2 = int(input("Player 2 Enter the Choice(1-9): ")) # Checking if it's already taken while player2 in choices: print("Make another choice! It's already Taken!") player2 = int(input("Player 2 Enter the Choice(1-9): ")) # updating according to the player2's choice g.update(map_dict[player2][0], map_dict[player2][1], "X") # Checking for tie if g.check_tie(g.get_current_game()): os.system('cls' if os.name == 'nt' else 'clear') g.make_grid(g.get_current_game()) print("It's a tie!") break # checking if player 2 won check2 = g.check_win(g.get_current_game()) try: if check2[0]==True: os.system('cls' if os.name == 'nt' else 'clear') g.make_grid(g.get_current_game()) print(f"{players[check2[1]]} wins") win=True break except Exception: pass g.make_grid(g.get_current_game()) choices.append(player2)