aicodingfun commited on
Commit
66fa8ea
·
verified ·
1 Parent(s): 4f9bfc4

Add application file

Browse files
Files changed (1) hide show
  1. app.py +125 -0
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import random
3
+ import gradio as gr
4
+ from PIL import Image, ImageDraw
5
+
6
+ def ai_move(board):
7
+ best_score = -np.inf
8
+ best_move = None
9
+ for r, c in available_moves(board):
10
+ board[r][c] = "X"
11
+ score = minimax(board, 0, False) # AI 使用最大化策略,深度從 0 開始
12
+ board[r][c] = ""
13
+ if score > best_score:
14
+ best_score = score
15
+ best_move = (r, c)
16
+ if best_move:
17
+ board[best_move[0]][best_move[1]] = "X"
18
+ return board
19
+
20
+ def initialize_board():
21
+ return [["", "", ""] for _ in range(3)]
22
+
23
+ def draw_board(board):
24
+ img_size = 300
25
+ cell_size = img_size // 3
26
+ img = Image.new("RGB", (img_size, img_size), "white")
27
+ draw = ImageDraw.Draw(img)
28
+
29
+ # Draw grid lines
30
+ for i in range(1, 3):
31
+ draw.line([(0, i * cell_size), (img_size, i * cell_size)], fill="black", width=3)
32
+ draw.line([(i * cell_size, 0), (i * cell_size, img_size)], fill="black", width=3)
33
+
34
+ # Draw ⨉ and 𐤏
35
+ for r in range(3):
36
+ for c in range(3):
37
+ if board[r][c] == "X":
38
+ draw.line([(c * cell_size + 10, r * cell_size + 10), ((c + 1) * cell_size - 10, (r + 1) * cell_size - 10)], fill="red", width=3)
39
+ draw.line([((c + 1) * cell_size - 10, r * cell_size + 10), (c * cell_size + 10, (r + 1) * cell_size - 10)], fill="red", width=3)
40
+ elif board[r][c] == "O":
41
+ draw.ellipse([(c * cell_size + 10, r * cell_size + 10), ((c + 1) * cell_size - 10, (r + 1) * cell_size - 10)], outline="blue", width=3)
42
+
43
+ return img
44
+
45
+ def check_winner(board):
46
+ for i in range(3):
47
+ if board[i][0] == board[i][1] == board[i][2] and board[i][0] != "":
48
+ return board[i][0]
49
+ if board[0][i] == board[1][i] == board[2][i] and board[0][i] != "":
50
+ return board[0][i]
51
+ if board[0][0] == board[1][1] == board[2][2] and board[0][0] != "":
52
+ return board[0][0]
53
+ if board[0][2] == board[1][1] == board[2][0] and board[0][2] != "":
54
+ return board[0][2]
55
+ if all(cell != "" for row in board for cell in row):
56
+ return "Tie"
57
+ return None
58
+
59
+ def available_moves(board):
60
+ return [(r, c) for r in range(3) for c in range(3) if board[r][c] == ""]
61
+
62
+ def minimax(board, depth, is_maximizing):
63
+ result = check_winner(board)
64
+ if result == "O":
65
+ return -10 + depth
66
+ elif result == "X":
67
+ return 10 - depth
68
+ elif result == "Tie":
69
+ return 0
70
+
71
+ if is_maximizing:
72
+ best_score = -np.inf
73
+ for r, c in available_moves(board):
74
+ board[r][c] = "X"
75
+ score = minimax(board, depth + 1, False)
76
+ board[r][c] = ""
77
+ best_score = max(score, best_score)
78
+ return best_score
79
+ else:
80
+ best_score = np.inf
81
+ for r, c in available_moves(board):
82
+ board[r][c] = "O"
83
+ score = minimax(board, depth + 1, True)
84
+ board[r][c] = ""
85
+ best_score = min(score, best_score)
86
+ return best_score
87
+
88
+ def play_tic_tac_toe(evt: gr.SelectData, board, game_over):
89
+ if game_over:
90
+ return draw_board(board), "Game already finished! Please reset to play again.", True
91
+
92
+ r, c = evt.index[1] // 100, evt.index[0] // 100
93
+ if board[r][c] != "":
94
+ return draw_board(board), "Invalid move! This spot is already taken. Please select an empty square.", False
95
+
96
+ board[r][c] = "O"
97
+ result = check_winner(board)
98
+ if result:
99
+ return draw_board(board), f"Game Over! Player {result} wins!" if result != "Tie" else "It's a tie!", True
100
+
101
+ board = ai_move(board)
102
+ result = check_winner(board)
103
+ if result:
104
+ return draw_board(board), f"Game Over! Player {result} wins!" if result != "Tie" else "It's a tie!", True
105
+
106
+ return draw_board(board), "Game in progress", False
107
+
108
+ def reset_game():
109
+ board = initialize_board()
110
+ return draw_board(board), board, "New game started!", False
111
+
112
+ with gr.Blocks() as app:
113
+ gr.Markdown("# Tic-Tac-Toe AI Game")
114
+
115
+ board = initialize_board()
116
+ board_image = gr.Image(value=draw_board(board), interactive=False, label="Board", show_download_button=False, show_fullscreen_button=False)
117
+ message_display = gr.Textbox(label="Game Status", value="Game in progress")
118
+ reset_button = gr.Button("Reset Game")
119
+ board_state = gr.State(board)
120
+ game_over_state = gr.State(False)
121
+
122
+ board_image.select(play_tic_tac_toe, inputs=[board_state, game_over_state], outputs=[board_image, message_display, game_over_state])
123
+ reset_button.click(reset_game, inputs=[], outputs=[board_image, board_state, message_display, game_over_state])
124
+
125
+ app.launch()