Spaces:
Sleeping
Sleeping
| 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 = "<div style='font-size: 1.5em; color: green; font-weight: bold;'>Player 1's turn (X)</div>" | |
| difficulty = "Medium" | |
| buttons = [gr.Button(value="", elem_classes=["cell-btn"], interactive=True) for _ in range(9)] | |
| return board, current_player, difficulty, 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): | |
| 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)) | |
| 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)) | |
| board[i][j] = "" | |
| return best | |
| # Find the best move for AI | |
| def get_best_move(board): | |
| 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) | |
| board[i][j] = "" | |
| if move_val > best_val: | |
| best_move = (i, j) | |
| best_val = move_val | |
| return best_move | |
| # Random AI move (for Easy level) | |
| def get_random_move(board): | |
| empty_cells = [(i, j) for i in range(3) for j in range(3) if board[i][j] == ""] | |
| return random.choice(empty_cells) if empty_cells else (-1, -1) | |
| # AI move based on difficulty level | |
| def get_ai_move(board, difficulty): | |
| if difficulty == "Easy": | |
| return get_random_move(board) | |
| elif difficulty == "Medium": | |
| return get_random_move(board) if random.random() < 0.5 else get_best_move(board) | |
| elif difficulty == "Hard": | |
| return get_best_move(board) | |
| # Handle a move | |
| def handle_move(board, current_player, button_idx, difficulty, game_status): | |
| 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, difficulty, game_status, *buttons | |
| row, col = divmod(button_idx, 3) | |
| if board[row][col] != "": | |
| status = f"<div style='font-size: 1.5em; color: orange; font-weight: bold;'>Invalid move! Player {1 if current_player == 'X' else 2}'s turn ({current_player})</div>" | |
| buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"]) for i in range(9)] | |
| return board, current_player, difficulty, status, *buttons | |
| board[row][col] = current_player | |
| winner = check_winner(board) | |
| if winner: | |
| status = f"<div style='font-size: 2em; color: red; font-weight: bold;'>Player {1 if winner == 'X' else 2} ({winner}) wins! ๐</div>" | |
| buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] | |
| return board, current_player, difficulty, status, *buttons | |
| if check_draw(board): | |
| status = "<div style='font-size: 2em; color: blue; font-weight: bold;'>It's a draw! ๐ค</div>" | |
| buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] | |
| return board, current_player, difficulty, status, *buttons | |
| if current_player == "X": | |
| current_player = "O" | |
| ai_row, ai_col = get_ai_move(board, difficulty) | |
| board[ai_row][ai_col] = "O" | |
| winner = check_winner(board) | |
| if winner: | |
| status = f"<div style='font-size: 2em; color: purple; font-weight: bold;'>AI ({winner}) wins! ๐</div>" | |
| buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] | |
| return board, current_player, difficulty, status, *buttons | |
| if check_draw(board): | |
| status = "<div style='font-size: 2em; color: blue; font-weight: bold;'>It's a draw! ๐ค</div>" | |
| buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"], interactive=False) for i in range(9)] | |
| return board, current_player, difficulty, status, *buttons | |
| current_player = "X" | |
| status = "<div style='font-size: 1.5em; color: green; font-weight: bold;'>Player 1's turn (X)</div>" | |
| buttons = [gr.Button(value=board[i // 3][i % 3], elem_classes=["cell-btn"]) for i in range(9)] | |
| return board, current_player, difficulty, status, *buttons | |
| # Build the Gradio UI | |
| css = """ | |
| .cell-btn { | |
| height: 100px; | |
| width: 100px; | |
| font-size: 2em; | |
| text-align: center; | |
| background-color: #f0f0f0; | |
| border: 2px solid #ddd; | |
| transition: all 0.3s; | |
| } | |
| .cell-btn:hover { | |
| background-color: #e0e0e0; | |
| } | |
| """ | |
| with gr.Blocks(css=css) as tic_tac_toe: | |
| with gr.Row(): | |
| gr.HTML( | |
| """ | |
| <div style="text-align: center; margin: auto;"> | |
| <h1 style="color: #1155ff; font-size: 3.5em; font-weight: bold; font-family: 'Arial', sans-serif; margin-bottom: 0.5em;"> Tic-Tac-Toe with AI ๐ฎ</h1> | |
| <p style="font-size: 1.5em; color: #555555; font-weight: bold; font-family: 'Verdana', sans-serif;"> | |
| Let's Play! | |
| </p> | |
| </div> | |
| """ | |
| ) | |
| game_status = gr.Markdown(value="<div style='font-size: 1.5em; color: green; font-weight: bold;'>Player 1's turn (X)</div>") | |
| difficulty = gr.Radio(["Easy", "Medium", "Hard"], value="Medium", label="Select Difficulty Level") | |
| board_state = gr.State([["" for _ in range(3)] for _ in range(3)]) | |
| current_player = gr.State("X") | |
| 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) | |
| for idx, btn in enumerate(buttons): | |
| btn.click( | |
| handle_move, | |
| inputs=[board_state, current_player, gr.Number(idx, visible=False), difficulty, game_status], | |
| outputs=[board_state, current_player, difficulty, game_status, *buttons], | |
| ) | |
| reset_button = gr.Button("Reset Game") | |
| reset_button.click( | |
| initialize_game, | |
| inputs=[], | |
| outputs=[board_state, current_player, difficulty, game_status, *buttons], | |
| ) | |
| tic_tac_toe.launch() | |