BilalCode's picture
Update app.py
104a597 verified
Raw
History Blame Contribute Delete
6.31 kB
import gradio as gr
import random
class TicTacToe:
def __init__(self):
self.board = [' ' for _ in range(9)]
self.current_player = 'X'
self.game_over = False
self.winner = None
self.player_wins = 0
self.ai_wins = 0
self.ties = 0
def reset_game(self):
self.board = [' ' for _ in range(9)]
self.current_player = 'X'
self.game_over = False
self.winner = None
def make_move(self, position):
if self.board[position] == ' ' and not self.game_over:
self.board[position] = self.current_player
if self.check_winner():
self.game_over = True
self.winner = self.current_player
if self.current_player == 'X':
self.player_wins += 1
else:
self.ai_wins += 1
elif ' ' not in self.board:
self.game_over = True
self.winner = 'Tie'
self.ties += 1
else:
self.current_player = 'O' if self.current_player == 'X' else 'X'
return True
return False
def check_winner(self):
lines = [
[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 line in lines:
if self.board[line[0]] == self.board[line[1]] == self.board[line[2]] != ' ':
return True
return False
def ai_move(self):
move = self.find_best_move()
if move is not None:
self.make_move(move)
def find_best_move(self):
for i in range(9):
if self.board[i] == ' ':
self.board[i] = 'O'
if self.check_winner():
self.board[i] = ' '
return i
self.board[i] = ' '
for i in range(9):
if self.board[i] == ' ':
self.board[i] = 'X'
if self.check_winner():
self.board[i] = ' '
return i
self.board[i] = ' '
if self.board[4] == ' ':
return 4
corners = [0, 2, 6, 8]
available = [i for i in corners if self.board[i] == ' ']
if available:
return random.choice(available)
empty = [i for i in range(9) if self.board[i] == ' ']
return random.choice(empty) if empty else None
game = TicTacToe()
def make_player_move(position):
if game.game_over:
return update_display() + ("Game Over! Click 'New Game' to play again.",)
if game.make_move(position):
if game.game_over:
return update_display() + (get_game_status(),)
game.ai_move()
return update_display() + (get_game_status(),)
return update_display() + ("Invalid move! Try another cell.",)
def new_game():
game.reset_game()
return update_display() + ("New game started! You are ❌, make your move!",)
def update_display():
return tuple(
gr.update(value="❌" if c == 'X' else "β­•" if c == 'O' else "",
variant="primary" if c == 'X' else "stop" if c == 'O' else "secondary",
interactive=(c == ' ' and not game.game_over))
for c in game.board
)
def get_game_status():
if game.game_over:
if game.winner == 'X':
return "πŸŽ‰ You Win! Congratulations!"
elif game.winner == 'O':
return "πŸ€– AI Wins! Try again!"
return "🀝 It's a Tie!"
return "Your turn!" if game.current_player == 'X' else "AI is thinking... πŸ€–"
with gr.Blocks(
theme=gr.themes.Soft(),
title="🎯 Smart Tic-Tac-Toe vs AI",
css="""
.game-button {
height: 80px;
font-size: 2em;
}
"""
) as demo:
gr.Markdown("# 🎯 Smart Tic-Tac-Toe vs AI")
gr.Markdown("### You are ❌, AI is β­• β€” Get 3 in a row to win!")
with gr.Row():
with gr.Column(scale=2):
with gr.Row():
btn0 = gr.Button("", elem_classes="game-button")
btn1 = gr.Button("", elem_classes="game-button")
btn2 = gr.Button("", elem_classes="game-button")
with gr.Row():
btn3 = gr.Button("", elem_classes="game-button")
btn4 = gr.Button("", elem_classes="game-button")
btn5 = gr.Button("", elem_classes="game-button")
with gr.Row():
btn6 = gr.Button("", elem_classes="game-button")
btn7 = gr.Button("", elem_classes="game-button")
btn8 = gr.Button("", elem_classes="game-button")
new_game_btn = gr.Button("πŸ” New Game", variant="primary")
status_display = gr.Textbox(
label="Game Status",
value="New game started! You are ❌, make your move!",
lines=2, interactive=False
)
with gr.Column(scale=1):
gr.Markdown("### πŸ“Š Game Stats")
player_wins_display = gr.Number(label="πŸ† Your Wins", value=0, interactive=False)
ai_wins_display = gr.Number(label="πŸ€– AI Wins", value=0, interactive=False)
ties_display = gr.Number(label="🀝 Ties", value=0, interactive=False)
with gr.Accordion("πŸ’‘ Strategy Tips", open=False):
gr.Markdown("""
- Take the center if available
- Block your opponent’s winning move
- Create multiple win paths
- Think ahead β€” the AI does!
""")
buttons = [btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8]
for i, btn in enumerate(buttons):
btn.click(fn=lambda pos=i: make_player_move(pos), outputs=buttons + [status_display])
new_game_btn.click(fn=new_game, outputs=buttons + [status_display])
def update_stats():
return game.player_wins, game.ai_wins, game.ties
for btn in buttons:
btn.click(fn=update_stats, outputs=[player_wins_display, ai_wins_display, ties_display])
new_game_btn.click(fn=update_stats, outputs=[player_wins_display, ai_wins_display, ties_display])
# Required for Hugging Face Spaces
model = demo
# βœ… REQUIRED to launch on Hugging Face
if __name__ == "__main__":
demo.launch()