Spaces:
Runtime error
Runtime error
import streamlit as st | |
import math | |
# --- Initialize session state --- | |
if "board" not in st.session_state: | |
st.session_state.board = [' ']*9 | |
if "game_over" not in st.session_state: | |
st.session_state.game_over = False | |
if "winner" not in st.session_state: | |
st.session_state.winner = None | |
# --- Game Logic --- | |
def check_winner(player): | |
win_combos = [ | |
[0,1,2], [3,4,5], [6,7,8], | |
[0,3,6], [1,4,7], [2,5,8], | |
[0,4,8], [2,4,6] | |
] | |
for combo in win_combos: | |
if all(st.session_state.board[i] == player for i in combo): | |
return True | |
return False | |
def is_full(): | |
return ' ' not in st.session_state.board | |
def minimax(is_maximizing, alpha, beta): | |
if check_winner('O'): | |
return 1 | |
if check_winner('X'): | |
return -1 | |
if is_full(): | |
return 0 | |
if is_maximizing: | |
max_eval = -math.inf | |
for i in range(9): | |
if st.session_state.board[i] == ' ': | |
st.session_state.board[i] = 'O' | |
eval_score = minimax(False, alpha, beta) | |
st.session_state.board[i] = ' ' | |
max_eval = max(max_eval, eval_score) | |
alpha = max(alpha, eval_score) | |
if beta <= alpha: | |
break | |
return max_eval | |
else: | |
min_eval = math.inf | |
for i in range(9): | |
if st.session_state.board[i] == ' ': | |
st.session_state.board[i] = 'X' | |
eval_score = minimax(True, alpha, beta) | |
st.session_state.board[i] = ' ' | |
min_eval = min(min_eval, eval_score) | |
beta = min(beta, eval_score) | |
if beta <= alpha: | |
break | |
return min_eval | |
def ai_move(): | |
best_score = -math.inf | |
move = None | |
for i in range(9): | |
if st.session_state.board[i] == ' ': | |
st.session_state.board[i] = 'O' | |
score = minimax(False, -math.inf, math.inf) | |
st.session_state.board[i] = ' ' | |
if score > best_score: | |
best_score = score | |
move = i | |
st.session_state.board[move] = 'O' | |
# --- Reset Game --- | |
def reset_game(): | |
st.session_state.board = [' ']*9 | |
st.session_state.game_over = False | |
st.session_state.winner = None | |
# --- Handle Player Move --- | |
def handle_click(i): | |
if st.session_state.board[i] == ' ' and not st.session_state.game_over: | |
st.session_state.board[i] = 'X' | |
if check_winner('X'): | |
st.session_state.game_over = True | |
st.session_state.winner = "You" | |
return | |
if is_full(): | |
st.session_state.game_over = True | |
st.session_state.winner = "Draw" | |
return | |
ai_move() | |
if check_winner('O'): | |
st.session_state.game_over = True | |
st.session_state.winner = "AI" | |
elif is_full(): | |
st.session_state.game_over = True | |
st.session_state.winner = "Draw" | |
# --- UI Layout --- | |
st.title("π€ Tic-Tac-Toe with AI") | |
st.write("You are X. The AI is O. Click on a box to make your move.") | |
# Display Board as 3x3 buttons | |
cols = st.columns(3) | |
for row in range(3): | |
for col in range(3): | |
idx = row*3 + col | |
with cols[col]: | |
if st.button(st.session_state.board[idx] if st.session_state.board[idx] != ' ' else ' ', key=idx): | |
handle_click(idx) | |
# Game Status | |
if st.session_state.game_over: | |
if st.session_state.winner == "Draw": | |
st.subheader("π€ It's a Draw!") | |
else: | |
st.subheader(f"π {st.session_state.winner} Wins!") | |
# Reset Button | |
if st.button("π Reset Game"): | |
reset_game() | |