OrifjonKenjayev commited on
Commit
d6ba23f
·
verified ·
1 Parent(s): 897fa98

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -75
app.py CHANGED
@@ -1,86 +1,169 @@
1
  import gradio as gr
2
- import random
3
- from typing import Dict
4
- import uuid
5
 
6
  class TicTacToe:
7
  def __init__(self):
8
- self.board = [" " for _ in range(9)]
9
- self.winning_combinations = [
10
- [0, 1, 2], [3, 4, 5], [6, 7, 8], # Rows
11
- [0, 3, 6], [1, 4, 7], [2, 5, 8], # Columns
12
- [0, 4, 8], [2, 4, 6] # Diagonals
13
- ]
14
- self.human = "X"
15
- self.ai = "O"
16
- self.current_player = self.human
17
-
18
- def reset(self):
19
- self.board = [" " for _ in range(9)]
20
- self.current_player = self.human
21
- return self.board
22
-
23
- # Rest of your TicTacToe class remains the same...
24
- # (keeping all other methods identical)
25
-
26
- # Dictionary to store game instances for each session
27
- games: Dict[str, TicTacToe] = {}
28
-
29
- def get_game(session_id: str) -> TicTacToe:
30
- if session_id not in games:
31
- games[session_id] = TicTacToe()
32
- return games[session_id]
33
-
34
- css = """
35
- # Your existing CSS remains the same
36
- """
37
-
38
- def create_interface():
39
- with gr.Blocks(css=css) as demo:
40
- session_id = gr.State(lambda: str(uuid.uuid4()))
41
 
42
- with gr.Column(elem_id="game-container"):
43
- status = gr.Markdown("Your turn!", elem_id="message")
44
-
45
- with gr.Column(elem_classes=["board"]):
46
- cells = []
47
- for i in range(9):
48
- cells.append(gr.Button(" ", elem_classes=["cell"]))
49
-
50
- reset = gr.Button("New Game", elem_id="reset-btn")
51
-
52
- def handle_click(idx, session):
53
- game = get_game(session)
54
- if game.make_move(idx):
55
- return {
56
- status: game.get_status(),
57
- **{cell: game.board[i] for i, cell in enumerate(cells)}
58
- }
59
- return {status: "Invalid move!"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- def reset_game(session):
62
- game = get_game(session)
63
- game.reset()
64
- return {
65
- status: "Your turn!",
66
- **{cell: " " for cell in cells}
67
- }
68
 
69
- for i, cell in enumerate(cells):
70
- cell.click(
71
- handle_click,
72
- inputs=[gr.State(i), session_id],
73
- outputs=[status, *cells]
74
- )
75
 
76
- reset.click(
77
- reset_game,
78
- inputs=[session_id],
79
- outputs=[status, *cells]
80
- )
81
 
82
- return demo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- demo = create_interface()
85
- demo.queue() # Enable queuing for multiple users
86
  demo.launch()
 
1
  import gradio as gr
2
+ import numpy as np
3
+ from typing import List, Tuple, Optional
 
4
 
5
  class TicTacToe:
6
  def __init__(self):
7
+ self.board = np.zeros((3, 3))
8
+ self.human_player = 1
9
+ self.ai_player = -1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ def reset_board(self):
12
+ self.board = np.zeros((3, 3))
13
+ return self.format_board()
14
+
15
+ def check_winner(self) -> Optional[int]:
16
+ # Check rows, columns and diagonals
17
+ for player in [self.human_player, self.ai_player]:
18
+ # Rows and columns
19
+ for i in range(3):
20
+ if all(self.board[i, :] == player) or all(self.board[:, i] == player):
21
+ return player
22
+ # Diagonals
23
+ if all(np.diag(self.board) == player) or all(np.diag(np.fliplr(self.board)) == player):
24
+ return player
25
+
26
+ # Check for draw
27
+ if np.all(self.board != 0):
28
+ return 0
29
+
30
+ return None
31
+
32
+ def get_valid_moves(self) -> List[Tuple[int, int]]:
33
+ return [(i, j) for i in range(3) for j in range(3) if self.board[i, j] == 0]
34
+
35
+ def minimax(self, depth: int, is_maximizing: bool, alpha: float = float('-inf'), beta: float = float('inf')) -> Tuple[int, Optional[Tuple[int, int]]]:
36
+ winner = self.check_winner()
37
+ if winner is not None:
38
+ return winner * 100, None
39
+
40
+ if is_maximizing:
41
+ best_score = float('-inf')
42
+ best_move = None
43
+ for move in self.get_valid_moves():
44
+ self.board[move] = self.ai_player
45
+ score, _ = self.minimax(depth + 1, False, alpha, beta)
46
+ self.board[move] = 0
47
+
48
+ if score > best_score:
49
+ best_score = score
50
+ best_move = move
51
+
52
+ alpha = max(alpha, best_score)
53
+ if beta <= alpha:
54
+ break
55
+
56
+ return best_score, best_move
57
+ else:
58
+ best_score = float('inf')
59
+ best_move = None
60
+ for move in self.get_valid_moves():
61
+ self.board[move] = self.human_player
62
+ score, _ = self.minimax(depth + 1, True, alpha, beta)
63
+ self.board[move] = 0
64
+
65
+ if score < best_score:
66
+ best_score = score
67
+ best_move = move
68
+
69
+ beta = min(beta, best_score)
70
+ if beta <= alpha:
71
+ break
72
+
73
+ return best_score, best_move
74
+
75
+ def ai_move(self) -> str:
76
+ if len(self.get_valid_moves()) == 0:
77
+ return self.format_board()
78
+
79
+ _, best_move = self.minimax(0, True)
80
+ if best_move is not None:
81
+ self.board[best_move] = self.ai_player
82
+
83
+ return self.format_board()
84
+
85
+ def format_board(self) -> str:
86
+ symbols = {0: " ", 1: "X", -1: "O"}
87
+ return "\n".join([
88
+ "-------------",
89
+ f"| {symbols[self.board[0,0]]} | {symbols[self.board[0,1]]} | {symbols[self.board[0,2]]} |",
90
+ "-------------",
91
+ f"| {symbols[self.board[1,0]]} | {symbols[self.board[1,1]]} | {symbols[self.board[1,2]]} |",
92
+ "-------------",
93
+ f"| {symbols[self.board[2,0]]} | {symbols[self.board[2,1]]} | {symbols[self.board[2,2]]} |",
94
+ "-------------"
95
+ ])
96
+
97
+ def make_move(self, row: int, col: int) -> Tuple[str, str]:
98
+ # Check if move is valid
99
+ if self.board[row, col] != 0:
100
+ return self.format_board(), "Invalid move! Cell already taken."
101
+
102
+ # Make human move
103
+ self.board[row, col] = self.human_player
104
+
105
+ # Check if game is over after human move
106
+ winner = self.check_winner()
107
+ if winner is not None:
108
+ if winner == self.human_player:
109
+ return self.format_board(), "You win!"
110
+ elif winner == 0:
111
+ return self.format_board(), "It's a draw!"
112
+
113
+ # Make AI move
114
+ self.ai_move()
115
+
116
+ # Check if game is over after AI move
117
+ winner = self.check_winner()
118
+ if winner is not None:
119
+ if winner == self.ai_player:
120
+ return self.format_board(), "AI wins!"
121
+ elif winner == 0:
122
+ return self.format_board(), "It's a draw!"
123
+
124
+ return self.format_board(), "Game in progress"
125
 
126
+ # Create game instance
127
+ game = TicTacToe()
 
 
 
 
 
128
 
129
+ def play_game(row: int, col: int, board_state: str, game_status: str) -> Tuple[str, str]:
130
+ if "win" in game_status or "draw" in game_status:
131
+ return board_state, game_status
132
+ return game.make_move(row, col)
 
 
133
 
134
+ def reset_game() -> Tuple[str, str]:
135
+ return game.reset_board(), "Game reset! Your turn (X)"
 
 
 
136
 
137
+ # Create Gradio interface
138
+ with gr.Blocks() as demo:
139
+ gr.Markdown("# Tic Tac Toe vs AI")
140
+ gr.Markdown("You play as X, AI plays as O. Click the buttons to make your move!")
141
+
142
+ with gr.Row():
143
+ # Game board display
144
+ board_display = gr.Textbox(value=game.format_board(), label="Game Board", lines=7)
145
+ game_status = gr.Textbox(value="Your turn (X)", label="Game Status")
146
+
147
+ # Create 3x3 grid of buttons
148
+ with gr.Row():
149
+ for i in range(3):
150
+ with gr.Column():
151
+ for j in range(3):
152
+ btn = gr.Button(f"Row {i}, Col {j}")
153
+ btn.click(
154
+ fn=play_game,
155
+ inputs=[
156
+ gr.Number(value=i, visible=False),
157
+ gr.Number(value=j, visible=False),
158
+ board_display,
159
+ game_status
160
+ ],
161
+ outputs=[board_display, game_status]
162
+ )
163
+
164
+ # Reset button
165
+ reset_btn = gr.Button("Reset Game")
166
+ reset_btn.click(fn=reset_game, inputs=[], outputs=[board_display, game_status])
167
 
168
+ # Launch app
 
169
  demo.launch()