From ab265b96bd0c24f73725468e90eca9995cba9949 Mon Sep 17 00:00:00 2001 From: shailawazeer Date: Sat, 24 May 2025 16:53:13 +0500 Subject: [PATCH] Added basic UI to play tictactoe against MiniMax AI --- .../__pycache__/tictactoe.cpython-313.pyc | Bin 0 -> 5850 bytes tictactoe/game_play.py | 66 +++++++++++++++++ tictactoe/tictactoe.py | 68 +++++------------- 3 files changed, 84 insertions(+), 50 deletions(-) create mode 100644 tictactoe/__pycache__/tictactoe.cpython-313.pyc create mode 100644 tictactoe/game_play.py diff --git a/tictactoe/__pycache__/tictactoe.cpython-313.pyc b/tictactoe/__pycache__/tictactoe.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1d8204cecbbc8f03d77e064f724271d50495738 GIT binary patch literal 5850 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 literal 0 HcmV?d00001 diff --git a/tictactoe/game_play.py b/tictactoe/game_play.py new file mode 100644 index 0000000..3528ad1 --- /dev/null +++ b/tictactoe/game_play.py @@ -0,0 +1,66 @@ +import tictactoe + +def print_board(board): + """ + Prints the board in a human-readable format. + """ + for row in board: + print("|", end=" ") + for cell in row: + print(cell if cell is not None else " ", end=" | ") + print("\n" + "-" * 13) + + +def get_human_move(board): + """ + Prompts user to input a valid move. + """ + while True: + try: + print("Enter row and column num") + row = int(input("Enter row (0, 1, 2): ")) + col = int(input("Enter column (0, 1, 2): ")) + if (row, col) in tictactoe.actions(board): + return (row, col) + else: + print("Invalid move. Try again.\n") + except ValueError: + print("Please enter valid integers.\n") + + +def main(): + board = tictactoe.initial_state() + human_player = input("Do you want to play as X or O? ").strip().upper() + + if human_player not in ["X", "O"]: + print("Invalid choice. Defaulting to X.") + human_player = "X" + + ai_player = tictactoe.O if human_player == tictactoe.X else tictactoe.X + + while not tictactoe.terminal(board): + print_board(board) + current = tictactoe.player(board) + + if current == human_player: + print(f"Your turn ({human_player})") + move = get_human_move(board) + else: + print(f"AI is thinking... ({ai_player})") + move = tictactoe.minimax(board) + + board = tictactoe.result(board, move) + + # Final board and result + print_board(board) + win = tictactoe.winner(board) + if win is None: + print("It's a draw!") + elif win == human_player: + print("You win!") + else: + print("AI wins!") + + +if __name__ == "__main__": + main() diff --git a/tictactoe/tictactoe.py b/tictactoe/tictactoe.py index 3d8d187..777fd42 100644 --- a/tictactoe/tictactoe.py +++ b/tictactoe/tictactoe.py @@ -65,56 +65,24 @@ def winner(board): """ Returns the winner of the game, if there is one. """ - for i in range(3): - if ( - board[i][0] == board[i][1] - and board[i][0] == board[i][2] - and board[i][0] != None - ): - if board[i][0] == "X": - return X - elif board[i][0] == "O": - return O - else: - return None - - for i in range(3): - if ( - board[0][i] == board[1][i] - and board[1][i] == board[2][i] - and board[0][i] != None - ): - if board[0][i] == "X": - return X - elif board[0][i] == "O": - return O - else: - return None - - if ( - board[0][0] == board[1][1] - and board[1][1] == board[2][2] - and board[0][0] != None - ): - if board[0][0] == "X": - return X - elif board[0][0] == "O": - return O - else: - return None - - if ( - board[2][0] == board[1][1] - and board[1][1] == board[0][2] - and board[2][0] != None - ): - if board[2][0] == "X": - return X - elif board[2][0] == "O": - return O - else: - return None - + win_combos = [ + # Rows + [(0,0), (0,1), (0,2)], + [(1,0), (1,1), (1,2)], + [(2,0), (2,1), (2,2)], + # Columns + [(0,0), (1,0), (2,0)], + [(0,1), (1,1), (2,1)], + [(0,2), (1,2), (2,2)], + # Diagonals + [(0,0), (1,1), (2,2)], + [(0,2), (1,1), (2,0)], + ] + + for combo in win_combos: + a, b, c = combo + if board[a[0]][a[1]] == board[b[0]][b[1]] == board[c[0]][c[1]] != None: + return board[a[0]][a[1]] return None