Spaces:
Sleeping
Sleeping
import gradio as gr | |
import random | |
import copy | |
# Initialize the board | |
def initialize_board(): | |
return [["" for _ in range(3)] for _ in range(3)] | |
# Check for winner | |
def check_winner(board): | |
for row in board: | |
if row[0] == row[1] == row[2] and row[0] != "": | |
return row[0] | |
for col in range(3): | |
if board[0][col] == board[1][col] == board[2][col] and board[0][col] != "": | |
return board[0][col] | |
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] | |
if all(board[row][col] != "" for row in range(3) for col in range(3)): | |
return "Draw" | |
return None | |
# Minimax algorithm | |
def minimax(board, depth, is_maximizing): | |
winner = check_winner(board) | |
if winner == "X": | |
return -10 + depth | |
elif winner == "O": | |
return 10 - depth | |
elif winner == "Draw": | |
return 0 | |
if is_maximizing: | |
best_score = -float("inf") | |
for row in range(3): | |
for col in range(3): | |
if board[row][col] == "": | |
board[row][col] = "O" | |
score = minimax(board, depth + 1, False) | |
board[row][col] = "" | |
best_score = max(score, best_score) | |
return best_score | |
else: | |
best_score = float("inf") | |
for row in range(3): | |
for col in range(3): | |
if board[row][col] == "": | |
board[row][col] = "X" | |
score = minimax(board, depth + 1, True) | |
board[row][col] = "" | |
best_score = min(score, best_score) | |
return best_score | |
# AI move using Minimax | |
def ai_move(board, difficulty): | |
if difficulty == "Easy": | |
empty_cells = [(row, col) for row in range(3) for col in range(3) if board[row][col] == ""] | |
return random.choice(empty_cells) | |
if difficulty == "Intermediate": | |
if random.random() < 0.5: | |
empty_cells = [(row, col) for row in range(3) for col in range(3) if board[row][col] == ""] | |
return random.choice(empty_cells) | |
best_score = -float("inf") | |
best_move = None | |
for row in range(3): | |
for col in range(3): | |
if board[row][col] == "": | |
board[row][col] = "O" | |
score = minimax(board, 0, False) | |
board[row][col] = "" | |
if score > best_score: | |
best_score = score | |
best_move = (row, col) | |
return best_move | |
# Handle a move | |
def handle_move(state, row, col, difficulty): | |
board, current_player, status = state | |
if board[row][col] != "" or status != "Game On": | |
return state | |
board[row][col] = current_player | |
winner = check_winner(board) | |
if winner: | |
return board, current_player, f"{winner} wins!" if winner != "Draw" else "It's a Draw!" | |
current_player = "O" if current_player == "X" else "X" | |
if current_player == "O": | |
ai_row, ai_col = ai_move(board, difficulty) | |
board[ai_row][ai_col] = "O" | |
winner = check_winner(board) | |
if winner: | |
return board, current_player, f"{winner} wins!" if winner != "Draw" else "It's a Draw!" | |
current_player = "X" | |
return board, current_player, "Game On" | |
# Gradio Interface | |
def reset_game(): | |
return initialize_board(), "X", "Game On" | |
def display_board(board): | |
return [[gr.Button.update(value=board[row][col], interactive=(board[row][col] == "")) for col in range(3)] for row in range(3)] | |
def on_click(state, row, col, difficulty): | |
new_state = handle_move(state, row, col, difficulty) | |
board, _, status = new_state | |
return new_state, display_board(board), status | |
def main(): | |
with gr.Blocks() as app: | |
gr.Markdown("# Tic Tac Toe with Smart AI") | |
difficulty = gr.Radio(["Easy", "Intermediate", "Impossible"], value="Impossible", label="Select Difficulty") | |
board = gr.State(initialize_board()) | |
current_player = gr.State("X") | |
status = gr.State("Game On") | |
output_board = gr.Grid([[gr.Button("", elem_id=f"cell-{row}-{col}", interactive=True) for col in range(3)] for row in range(3)]) | |
status_display = gr.Textbox("Game On", interactive=False, label="Status") | |
reset_button = gr.Button("Reset Game") | |
for row in range(3): | |
for col in range(3): | |
output_board[row][col].click( | |
on_click, | |
inputs=[board, current_player, status, gr.State(row), gr.State(col), difficulty], | |
outputs=[board, output_board, status_display] | |
) | |
reset_button.click( | |
reset_game, inputs=[], outputs=[board, current_player, status, output_board, status_display] | |
) | |
return app | |
app = main() | |
app.launch() | |