import streamlit as st
import numpy as np
import random
import time
# JavaScript confetti function
def show_confetti():
st.components.v1.html("""
""", height=0)
# Custom CSS for premium UI
st.markdown("""
""", unsafe_allow_html=True)
# Sound effects (using HTML audio)
sound_effects = """
"""
st.components.v1.html(sound_effects, height=0)
def initialize_game():
"""Initialize the game board."""
st.session_state.game['board'] = [' ' for _ in range(9)]
st.session_state.game['current_player'] = 'X'
st.session_state.game['winner'] = None
st.session_state.game['game_over'] = False
st.session_state.game['last_move'] = None
def check_winner(board):
"""Check if there's a winner or if the game is a tie."""
# Check rows
for i in range(0, 9, 3):
if board[i] == board[i+1] == board[i+2] != ' ':
return board[i]
# Check columns
for i in range(3):
if board[i] == board[i+3] == board[i+6] != ' ':
return board[i]
# Check diagonals
if board[0] == board[4] == board[8] != ' ':
return board[0]
if board[2] == board[4] == board[6] != ' ':
return board[2]
# Check for tie
if ' ' not in board:
return 'Tie'
return None
def make_move(board, position, player):
"""Make a move on the board."""
if board[position] == ' ':
board[position] = player
st.session_state.game['last_move'] = position
st.components.v1.html("", height=0)
return True
return False
def minimax(board, depth, is_maximizing):
"""Minimax algorithm for unbeatable AI."""
winner = check_winner(board)
if winner == 'O':
return 10 - depth
elif winner == 'X':
return depth - 10
elif winner == 'Tie':
return 0
if is_maximizing:
best_score = -float('inf')
for i in range(9):
if board[i] == ' ':
board[i] = 'O'
score = minimax(board, depth + 1, False)
board[i] = ' '
best_score = max(score, best_score)
return best_score
else:
best_score = float('inf')
for i in range(9):
if board[i] == ' ':
board[i] = 'X'
score = minimax(board, depth + 1, True)
board[i] = ' '
best_score = min(score, best_score)
return best_score
def ai_move(board, difficulty):
"""AI move based on selected difficulty."""
if difficulty == 'Easy':
# Random moves
available = [i for i, spot in enumerate(board) if spot == ' ']
return random.choice(available) if available else -1
elif difficulty == 'Medium':
# Mix of random and smart moves
if random.random() < 0.5:
return ai_move(board, 'Easy')
else:
return ai_move(board, 'Hard')
elif difficulty == 'Hard':
# Unbeatable minimax AI
best_score = -float('inf')
best_move = -1
for i in range(9):
if board[i] == ' ':
board[i] = 'O'
score = minimax(board, 0, False)
board[i] = ' '
if score > best_score:
best_score = score
best_move = i
return best_move
def display_board(board):
"""Display the Tic Tac Toe board with premium UI."""
st.markdown('
', unsafe_allow_html=True)
cols = st.columns(3)
for i in range(9):
with cols[i % 3]:
button_label = board[i] if board[i] != ' ' else ' '
button_class = ""
if board[i] == 'X':
button_class = "x-button"
elif board[i] == 'O':
button_class = "o-button"
# Highlight last move
last_move_class = "last-move" if i == st.session_state.game['last_move'] else ""
if st.button(
button_label,
key=f"btn_{i}",
disabled=(board[i] != ' ' or
st.session_state.game['game_over'] or
st.session_state.game['current_player'] == 'O'),
use_container_width=True,
kwargs={"class": f"board-button {button_class} {last_move_class}"}
):
if make_move(board, i, 'X'):
st.session_state.game['winner'] = check_winner(board)
if st.session_state.game['winner']:
st.session_state.game['game_over'] = True
if st.session_state.game['winner'] == 'X':
st.session_state.game['scores']['X'] += 1
show_confetti()
st.components.v1.html("", height=0)
elif st.session_state.game['winner'] == 'O':
st.session_state.game['scores']['O'] += 1
else:
st.session_state.game['scores']['Ties'] += 1
else:
st.session_state.game['current_player'] = 'O'
st.rerun()
st.markdown('
', unsafe_allow_html=True)
def ai_turn():
"""Handle the AI's turn with visual feedback."""
if st.session_state.game['current_player'] == 'O' and not st.session_state.game['game_over']:
with st.spinner("🤖 AI is thinking..."):
time.sleep(0.8) # Simulate thinking time
move = ai_move(st.session_state.game['board'], st.session_state.game['difficulty'])
if move != -1 and make_move(st.session_state.game['board'], move, 'O'):
st.session_state.game['winner'] = check_winner(st.session_state.game['board'])
if st.session_state.game['winner']:
st.session_state.game['game_over'] = True
if st.session_state.game['winner'] == 'X':
st.session_state.game['scores']['X'] += 1
show_confetti()
st.components.v1.html("", height=0)
elif st.session_state.game['winner'] == 'O':
st.session_state.game['scores']['O'] += 1
else:
st.session_state.game['scores']['Ties'] += 1
else:
st.session_state.game['current_player'] = 'X'
st.rerun()
def display_status():
"""Display the current game status with premium UI."""
if st.session_state.game['winner']:
if st.session_state.game['winner'] == 'Tie':
st.markdown('