import gradio as gr import random # Initialize the game board and state def initialize_game(): board = [["" for _ in range(3)] for _ in range(3)] current_player = "X" status = "Player 1's turn (X)" buttons = [gr.Button(value="", elem_classes=["cell-btn"], interactive=True) for _ in range(9)] return board, current_player, status, *buttons # Check for a winner def check_winner(board): for i in range(3): if board[i][0] == board[i][1] == board[i][2] and board[i][0] != "": return board[i][0] if board[0][i] == board[1][i] == board[2][i] and board[0][i] != "": return board[0][i] if board[0][0] == board[1][1] == board[2][2] and board[0][0] != "": return board[0][0] if board[0][2] == board[1][1] == board[2][0] and board[0][2] != "": return board[0][2] return None # Check for a draw def check_draw(board): return all(cell != "" for row in board for cell in row) # Minimax algorithm for AI's move def minimax(board, depth, is_maximizing, difficulty): winner = check_winner(board) if winner == "X": return -10 + depth elif winner == "O": return 10 - depth elif check_draw(board): return 0 if is_maximizing: best = -float('inf') for i in range(3): for j in range(3): if board[i][j] == "": board[i][j] = "O" best = max(best, minimax(board, depth + 1, False, difficulty)) board[i][j] = "" return best else: best = float('inf') for i in range(3): for j in range(3): if board[i][j] == "": board[i][j] = "X" best = min(best, minimax(board, depth + 1, True, difficulty)) board[i][j] = "" return best # Find the best move for AI def get_best_move(board, difficulty): if difficulty == "easy": # Random move for easy level empty_cells = [(i, j) for i in range(3) for j in range(3) if board[i][j] == ""] if empty_cells: return random.choice(empty_cells) if difficulty == "intermediate": # Mixed strategy for intermediate if random.random() < 0.5: return get_best_move(board, "easy") best_val = -float('inf') best_move = (-1, -1) for i in range(3): for j in range(3): if board[i][j] == "": board[i][j] = "O" move_val = minimax(board, 0, False, difficulty) board[i][j] = "" if move_val > best_val: best_move = (i, j) best_val = move_val return best_move # Handle a move def handle_move(board, current_player, button_idx, game_status, difficulty): if "wins" in game_status or "draw" in game_status: buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] return board, current_player, game_status, *buttons row, col = divmod(button_idx, 3) if board[row][col] != "": status = f"Invalid move! Player {1 if current_player == 'X' else 2}'s turn ({current_player})" buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"]) for i in range(9)] return board, current_player, status, *buttons board[row][col] = current_player winner = check_winner(board) if winner: status = f"Player {1 if winner == 'X' else 2} ({winner}) wins! 🎉" buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] return board, current_player, status, *buttons if check_draw(board): status = "It's a draw! 🤝" buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] return board, current_player, status, *buttons # AI's turn if current_player == "X": current_player = "O" ai_row, ai_col = get_best_move(board, difficulty) board[ai_row][ai_col] = "O" winner = check_winner(board) if winner: status = f"AI ({winner}) wins! 🎉" buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] return board, current_player, status, *buttons if check_draw(board): status = "It's a draw! 🤝" buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] return board, current_player, status, *buttons current_player = "X" status = f"Player 1's turn (X)" buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"]) for i in range(9)] return board, current_player, status, *buttons # Build the Gradio UI with gr.Blocks(css=".cell-btn {height: 100px; width: 100px; font-size: 2em; text-align: center;}") as tic_tac_toe: gr.Markdown("## Tic-Tac-Toe with AI 🎮") difficulty = gr.Radio(["easy", "intermediate", "impossible"], value="impossible", label="Difficulty Level") # Initialize states board_state = gr.State([["" for _ in range(3)] for _ in range(3)]) current_player = gr.State("X") game_status = gr.Textbox(value="Player 1's turn (X)", label="Game Status", interactive=False) # Create grid buttons buttons = [] for i in range(3): with gr.Row(): for j in range(3): btn = gr.Button(value="", elem_classes=["cell-btn"]) buttons.append(btn) # Update buttons dynamically on click for idx, btn in enumerate(buttons): btn.click( handle_move, inputs=[board_state, current_player, gr.Number(idx, visible=False), game_status, difficulty], outputs=[board_state, current_player, game_status, *buttons], ) # Reset game button reset_button = gr.Button("Reset Game") reset_button.click( initialize_game, inputs=[], outputs=[board_state, current_player, game_status, *buttons], ) tic_tac_toe.launch()