Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import random | |
| class TicTacToe: | |
| def __init__(self): | |
| self.board = [" " for _ in range(9)] | |
| self.winning_combinations = [ | |
| [0, 1, 2], [3, 4, 5], [6, 7, 8], # Rows | |
| [0, 3, 6], [1, 4, 7], [2, 5, 8], # Columns | |
| [0, 4, 8], [2, 4, 6] # Diagonals | |
| ] | |
| self.human = "X" | |
| self.ai = "O" | |
| self.current_player = self.human | |
| def reset(self): | |
| self.board = [" " for _ in range(9)] | |
| self.current_player = self.human | |
| return self.board | |
| def make_move(self, position): | |
| if self.board[position] == " " and not self.is_game_over(): | |
| self.board[position] = self.current_player | |
| if self.current_player == self.human: | |
| self.current_player = self.ai | |
| # AI makes its move after human | |
| if not self.is_game_over(): | |
| ai_move = self.get_best_move() | |
| self.board[ai_move] = self.ai | |
| self.current_player = self.human | |
| return True | |
| return False | |
| def is_winner(self, player): | |
| for combo in self.winning_combinations: | |
| if all(self.board[i] == player for i in combo): | |
| return True | |
| return False | |
| def is_game_over(self): | |
| return self.is_winner(self.human) or self.is_winner(self.ai) or " " not in self.board | |
| def get_status(self): | |
| if self.is_winner(self.human): | |
| return "You win! ๐" | |
| elif self.is_winner(self.ai): | |
| return "AI wins! ๐ค" | |
| elif " " not in self.board: | |
| return "It's a tie! ๐ค" | |
| return "Your turn!" | |
| def minimax(self, depth, is_maximizing): | |
| if self.is_winner(self.ai): | |
| return 1 | |
| if self.is_winner(self.human): | |
| return -1 | |
| if " " not in self.board: | |
| return 0 | |
| if is_maximizing: | |
| best_score = float('-inf') | |
| for i in range(9): | |
| if self.board[i] == " ": | |
| self.board[i] = self.ai | |
| score = self.minimax(depth + 1, False) | |
| self.board[i] = " " | |
| best_score = max(score, best_score) | |
| return best_score | |
| else: | |
| best_score = float('inf') | |
| for i in range(9): | |
| if self.board[i] == " ": | |
| self.board[i] = self.human | |
| score = self.minimax(depth + 1, True) | |
| self.board[i] = " " | |
| best_score = min(score, best_score) | |
| return best_score | |
| def get_best_move(self): | |
| best_score = float('-inf') | |
| best_move = None | |
| for i in range(9): | |
| if self.board[i] == " ": | |
| self.board[i] = self.ai | |
| score = self.minimax(0, False) | |
| self.board[i] = " " | |
| if score > best_score: | |
| best_score = score | |
| best_move = i | |
| return best_move | |
| game = TicTacToe() | |
| css = """ | |
| #game-container { | |
| max-width: 300px; | |
| margin: 0 auto; | |
| padding: 15px; | |
| } | |
| .board { | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 4px; | |
| background: #ff0000; | |
| padding: 4px; | |
| width: 240px; | |
| margin: 0 auto; | |
| } | |
| .cell { | |
| width: 100% !important; | |
| height: 75px !important; | |
| font-size: 24px !important; | |
| font-weight: bold !important; | |
| background: white !important; | |
| color: #0066cc !important; | |
| border: none !important; | |
| display: flex !important; | |
| align-items: center !important; | |
| justify-content: center !important; | |
| cursor: pointer !important; | |
| } | |
| .cell:hover { | |
| background: #f0f0f0 !important; | |
| } | |
| #message { | |
| text-align: center; | |
| margin: 15px 0; | |
| font-size: 18px; | |
| color: #333; | |
| } | |
| #reset-btn { | |
| background: #e74c3c !important; | |
| color: white !important; | |
| border: none !important; | |
| padding: 10px 20px !important; | |
| border-radius: 5px !important; | |
| cursor: pointer !important; | |
| margin: 10px auto !important; | |
| display: block !important; | |
| width: 120px !important; | |
| } | |
| """ | |
| def create_interface(): | |
| with gr.Blocks(css=css) as demo: | |
| with gr.Column(elem_id="game-container"): | |
| status = gr.Markdown("Your turn!", elem_id="message") | |
| with gr.Column(elem_classes=["board"]): | |
| cells = [] | |
| for i in range(9): | |
| cells.append(gr.Button(" ", elem_classes=["cell"])) | |
| reset = gr.Button("New Game", elem_id="reset-btn") | |
| def handle_click(idx): | |
| if game.make_move(idx): | |
| return { | |
| status: game.get_status(), | |
| **{cell: game.board[i] for i, cell in enumerate(cells)} | |
| } | |
| return {status: "Invalid move!"} | |
| def reset_game(): | |
| game.reset() | |
| return { | |
| status: "Your turn!", | |
| **{cell: " " for cell in cells} | |
| } | |
| for i, cell in enumerate(cells): | |
| cell.click( | |
| handle_click, | |
| inputs=[gr.State(i)], | |
| outputs=[status, *cells] | |
| ) | |
| reset.click( | |
| reset_game, | |
| outputs=[status, *cells] | |
| ) | |
| return demo | |
| demo = create_interface() | |
| demo.launch() |