Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
|
3 |
+
# Othello (Reversi) logic implementation
|
4 |
+
def initialize_board():
|
5 |
+
board = [[0 for _ in range(8)] for _ in range(8)]
|
6 |
+
board[3][3], board[4][4] = 1, 1 # White
|
7 |
+
board[3][4], board[4][3] = -1, -1 # Black
|
8 |
+
return board
|
9 |
+
|
10 |
+
# Directions for flipping
|
11 |
+
DIRECTIONS = [(-1, -1), (-1, 0), (-1, 1),
|
12 |
+
(0, -1), (0, 1),
|
13 |
+
(1, -1), (1, 0), (1, 1)]
|
14 |
+
|
15 |
+
# Check if a move is valid and collect flips
|
16 |
+
def get_flips(board, row, col, player):
|
17 |
+
if board[row][col] != 0:
|
18 |
+
return []
|
19 |
+
flips = []
|
20 |
+
for dr, dc in DIRECTIONS:
|
21 |
+
r, c = row + dr, col + dc
|
22 |
+
buffer = []
|
23 |
+
while 0 <= r < 8 and 0 <= c < 8 and board[r][c] == -player:
|
24 |
+
buffer.append((r, c))
|
25 |
+
r += dr; c += dc
|
26 |
+
if buffer and 0 <= r < 8 and 0 <= c < 8 and board[r][c] == player:
|
27 |
+
flips.extend(buffer)
|
28 |
+
return flips
|
29 |
+
|
30 |
+
# Apply move if valid
|
31 |
+
def apply_move(board, row, col, player):
|
32 |
+
flips = get_flips(board, row, col, player)
|
33 |
+
if not flips:
|
34 |
+
return False
|
35 |
+
board[row][col] = player
|
36 |
+
for r, c in flips:
|
37 |
+
board[r][c] = player
|
38 |
+
return True
|
39 |
+
|
40 |
+
# Generate HTML representation
|
41 |
+
def board_to_html(board):
|
42 |
+
html = '<table style="border-collapse: collapse;">'
|
43 |
+
for r in range(8):
|
44 |
+
html += '<tr>'
|
45 |
+
for c in range(8):
|
46 |
+
cell = board[r][c]
|
47 |
+
if cell == 1:
|
48 |
+
color = 'white'
|
49 |
+
elif cell == -1:
|
50 |
+
color = 'black'
|
51 |
+
else:
|
52 |
+
color = 'transparent'
|
53 |
+
html += f'<td style="width:40px;height:40px;border:1px solid #000;text-align:center;vertical-align:middle;background:{color};"></td>'
|
54 |
+
html += '</tr>'
|
55 |
+
html += '</table>'
|
56 |
+
return html
|
57 |
+
|
58 |
+
# Count score
|
59 |
+
def count_score(board):
|
60 |
+
black = sum(cell == -1 for row in board for cell in row)
|
61 |
+
white = sum(cell == 1 for row in board for cell in row)
|
62 |
+
return black, white
|
63 |
+
|
64 |
+
# Gradio interaction
|
65 |
+
def play_move(row, col, state):
|
66 |
+
board, player = state
|
67 |
+
row, col = int(row) - 1, int(col) - 1
|
68 |
+
if not (0 <= row < 8 and 0 <= col < 8):
|
69 |
+
return board_to_html(board), f"Invalid position.", state
|
70 |
+
if not apply_move(board, row, col, player):
|
71 |
+
return board_to_html(board), "Invalid move.", state
|
72 |
+
# Switch player
|
73 |
+
player = -player
|
74 |
+
black_score, white_score = count_score(board)
|
75 |
+
status = f"Black: {black_score} | White: {white_score} | {'Black' if player == -1 else 'White'} to move"
|
76 |
+
return board_to_html(board), status, (board, player)
|
77 |
+
|
78 |
+
# Initialize Gradio app
|
79 |
+
def main():
|
80 |
+
with gr.Blocks() as demo:
|
81 |
+
gr.HTML("<h2>Othello (Reversi) Game</h2>")
|
82 |
+
board_html = gr.HTML(board_to_html(initialize_board()))
|
83 |
+
status = gr.Text(value="Black: 2 | White: 2 | Black to move", interactive=False)
|
84 |
+
with gr.Row():
|
85 |
+
row_input = gr.Slider(1, 8, step=1, label="Row")
|
86 |
+
col_input = gr.Slider(1, 8, step=1, label="Column")
|
87 |
+
submit = gr.Button("Place")
|
88 |
+
state = gr.State((initialize_board(), -1)) # -1: Black, 1: White
|
89 |
+
submit.click(fn=play_move,
|
90 |
+
inputs=[row_input, col_input, state],
|
91 |
+
outputs=[board_html, status, state])
|
92 |
+
demo.launch()
|
93 |
+
|
94 |
+
if __name__ == "__main__":
|
95 |
+
main()
|