Spaces:
Sleeping
Sleeping
import gradio as gr | |
import math | |
# Check winner | |
def check_winner(board, player): | |
wins = [[0,1,2],[3,4,5],[6,7,8], | |
[0,3,6],[1,4,7],[2,5,8], | |
[0,4,8],[2,4,6]] | |
return any(board[a]==board[b]==board[c]==player for a,b,c in wins) | |
# Check draw | |
def is_full(board): | |
return ' ' not in board | |
# Minimax with alpha-beta pruning | |
def minimax(board, is_max, alpha, beta): | |
if check_winner(board,'O'): return 1 | |
if check_winner(board,'X'): return -1 | |
if is_full(board): return 0 | |
if is_max: | |
best = -math.inf | |
for i in range(9): | |
if board[i]==' ': | |
board[i]='O' | |
val = minimax(board, False, alpha, beta) | |
board[i]=' ' | |
best = max(best, val) | |
alpha = max(alpha, val) | |
if beta<=alpha: break | |
return best | |
else: | |
best = math.inf | |
for i in range(9): | |
if board[i]==' ': | |
board[i]='X' | |
val = minimax(board, True, alpha, beta) | |
board[i]=' ' | |
best = min(best, val) | |
beta = min(beta, val) | |
if beta<=alpha: break | |
return best | |
# AI move | |
def ai_move(board): | |
best_score = -math.inf | |
move = None | |
for i in range(9): | |
if board[i]==' ': | |
board[i]='O' | |
score = minimax(board, False, -math.inf, math.inf) | |
board[i]=' ' | |
if score > best_score: | |
best_score = score | |
move = i | |
if move is not None: | |
board[move]='O' | |
return board | |
# Player move | |
def player_move(cell, board): | |
board = board.copy() # work on a copy | |
if board[cell] != ' ': | |
return board, "โ Spot taken!", board | |
board[cell] = 'X' | |
if check_winner(board,'X'): | |
return board, "๐ You win!", board | |
if is_full(board): | |
return board, "๐ค Draw!", board | |
board = ai_move(board) | |
if check_winner(board,'O'): | |
return board, "๐ป AI wins!", board | |
if is_full(board): | |
return board, "๐ค Draw!", board | |
return board, "Your move!", board | |
# Reset board | |
def reset(): | |
new_board = [' ' for _ in range(9)] | |
return new_board, "New Game! You are X.", new_board | |
# Update buttons | |
def update_buttons(board): | |
return [board[i] if board[i] != ' ' else " " for i in range(9)] | |
# Build GUI | |
with gr.Blocks(css=""" | |
.grid {display:grid;grid-template-columns:repeat(3,100px);grid-gap:5px;justify-content:center;} | |
.grid button {height:100px;width:100px;font-size:2em;font-weight:bold;} | |
""") as demo: | |
gr.Markdown("<h1 style='text-align:center'>๐ฎ Tic Tac Toe AI</h1>") | |
status = gr.Label("New Game! You are X.") | |
board_state = gr.State([' ' for _ in range(9)]) # ๐ persistent board state | |
with gr.Column(): | |
game_buttons = [] | |
with gr.Row(elem_classes="grid"): | |
for i in range(9): | |
btn = gr.Button(" ") | |
game_buttons.append(btn) | |
reset_btn = gr.Button("๐ Reset Game") | |
# Wire buttons to player_move with state | |
for idx, btn in enumerate(game_buttons): | |
btn.click(player_move, | |
inputs=[gr.Number(value=idx, visible=False), board_state], | |
outputs=[gr.State(), status, board_state]) \ | |
.then(update_buttons, inputs=board_state, outputs=game_buttons) | |
# Reset game | |
reset_btn.click(reset, outputs=[gr.State(), status, board_state]) \ | |
.then(update_buttons, inputs=board_state, outputs=game_buttons) | |
demo.launch() | |