Renecto commited on
Commit
c533acd
·
verified ·
1 Parent(s): 17edf34

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -66
app.py CHANGED
@@ -1,116 +1,107 @@
1
  import gradio as gr
2
  from PIL import Image, ImageDraw, ImageFont
3
- import random, time
 
4
 
5
- # Constants
6
  DIRECTIONS = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
7
 
8
- # Initialize board
9
  def initialize_board():
10
  board = [[0]*8 for _ in range(8)]
11
  board[3][3], board[4][4] = 1, 1
12
  board[3][4], board[4][3] = -1, -1
13
  return board
14
 
15
- # Get flips
16
  def get_flips(board, r, c, p):
17
  if board[r][c] != 0: return []
18
  flips = []
19
  for dr, dc in DIRECTIONS:
20
- rr, cc = r+dr, c+dc
21
- buf = []
22
- while 0 <= rr < 8 and 0 <= cc < 8 and board[rr][cc] == -p:
23
- buf.append((rr, cc)); rr += dr; cc += dc
24
- if buf and 0 <= rr < 8 and 0 <= cc < 8 and board[rr][cc] == p:
25
- flips.extend(buf)
26
  return flips
27
 
28
- # Apply move
29
  def apply_move(board, r, c, p):
30
- flips = get_flips(board, r, c, p)
31
- if not flips: return False
32
  board[r][c] = p
33
- for rr, cc in flips:
34
- board[rr][cc] = p
35
  return True
36
 
37
- # AI choose move
38
  def choose_move(board, p):
39
- valid = [(r,c) for r in range(8) for c in range(8) if get_flips(board,r,c,p)]
40
- return random.choice(valid) if valid else None
41
 
42
- # Count score
43
  def count_score(board):
44
- black = sum(cell==-1 for row in board for cell in row)
45
- white = sum(cell==1 for row in board for cell in row)
46
- return black, white
47
 
48
- # Check game over
49
  def is_game_over(board):
50
  return not any(get_flips(board,r,c,p) for p in (-1,1) for r in range(8) for c in range(8))
51
 
52
- # Render board image
53
  def board_to_image(board, state):
54
  board_state, player, last_user, last_ai = state
55
- size, cell = 360, 360//8
56
- img = Image.new('RGB', (size, size+cell), 'darkgreen')
57
  draw = ImageDraw.Draw(img)
58
- font = ImageFont.load_default()
59
-
 
 
 
60
  # Scoreboard
61
  b, w = count_score(board_state)
62
- draw.text((10,2), f"B:{b}", font=font, fill='white')
63
- draw.text((size-40,2), f"W:{w}", font=font, fill='white')
64
-
65
- # Game end
66
  if is_game_over(board_state):
67
- winner = "Draw" if b==w else ("Black wins" if b>w else "White wins")
68
- draw.text((size//2-40, size//2), winner, font=font, fill='yellow')
69
-
70
- # Board grid and stones
 
71
  for r in range(8):
72
  for c in range(8):
73
- x0, y0 = c*cell, cell + r*cell
 
74
  x1, y1 = x0+cell, y0+cell
75
  draw.rectangle([x0,y0,x1,y1], outline='black')
76
- if board_state[r][c] == 1:
 
77
  draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='white')
78
- elif board_state[r][c] == -1:
79
  draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='black')
80
  return img
81
 
82
- # Click handler
83
-
84
- def click_handler(evt, state):
85
- # state: (board, player, last_user, last_ai)
86
- if state is None:
87
- state = (initialize_board(), -1, None, None)
88
  board, player, last_user, last_ai = state
89
-
90
- x, y = evt.index
91
- cell = 360 // 8
92
- c, r = int(x//cell), int((y-cell)//cell)
93
-
94
- # Player move
95
- if 0 <= r < 8 and 0 <= c < 8 and not is_game_over(board):
96
- if apply_move(board, r, c, player):
97
- last_user = (r, c)
98
- player = -player
99
-
100
- # AI move
101
- if not is_game_over(board):
102
- ai_mv = choose_move(board, player)
103
- if ai_mv:
104
- apply_move(board, ai_mv[0], ai_mv[1], player)
105
- last_ai = ai_mv
106
- player = -player
107
-
108
  return board_to_image(board, (board, player, last_user, last_ai)), (board, player, last_user, last_ai)
109
 
110
- # Main
 
111
 
 
112
  with gr.Blocks() as demo:
113
  state = gr.State((initialize_board(), -1, None, None))
114
- img = gr.Image(value=board_to_image(initialize_board(), (initialize_board(), -1, None, None)), interactive=True)
 
115
  img.select(click_handler, inputs=[state], outputs=[img, state])
 
116
  demo.launch()
 
1
  import gradio as gr
2
  from PIL import Image, ImageDraw, ImageFont
3
+ import random
4
+ time
5
 
 
6
  DIRECTIONS = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
7
 
8
+ # Game logic
9
  def initialize_board():
10
  board = [[0]*8 for _ in range(8)]
11
  board[3][3], board[4][4] = 1, 1
12
  board[3][4], board[4][3] = -1, -1
13
  return board
14
 
 
15
  def get_flips(board, r, c, p):
16
  if board[r][c] != 0: return []
17
  flips = []
18
  for dr, dc in DIRECTIONS:
19
+ rr, cc = r+dr, c+dc; buf=[]
20
+ while 0<=rr<8 and 0<=cc<8 and board[rr][cc] == -p:
21
+ buf.append((rr,cc)); rr+=dr; cc+=dc
22
+ if buf and 0<=rr<8 and 0<=cc<8 and board[rr][cc] == p:
23
+ flips += buf
 
24
  return flips
25
 
 
26
  def apply_move(board, r, c, p):
27
+ f = get_flips(board, r, c, p)
28
+ if not f: return False
29
  board[r][c] = p
30
+ for rr, cc in f: board[rr][cc] = p
 
31
  return True
32
 
 
33
  def choose_move(board, p):
34
+ moves = [(r,c) for r in range(8) for c in range(8) if get_flips(board,r,c,p)]
35
+ return random.choice(moves) if moves else None
36
 
 
37
  def count_score(board):
38
+ b = sum(cell==-1 for row in board for cell in row)
39
+ w = sum(cell==1 for row in board for cell in row)
40
+ return b, w
41
 
 
42
  def is_game_over(board):
43
  return not any(get_flips(board,r,c,p) for p in (-1,1) for r in range(8) for c in range(8))
44
 
45
+ # Rendering
46
  def board_to_image(board, state):
47
  board_state, player, last_user, last_ai = state
48
+ size = 400; board_size = 360; cell = board_size//8
49
+ img = Image.new('RGB',(size, size), 'darkgreen')
50
  draw = ImageDraw.Draw(img)
51
+ # Load font
52
+ try:
53
+ font = ImageFont.truetype('arial.ttf', 24)
54
+ except:
55
+ font = ImageFont.load_default()
56
  # Scoreboard
57
  b, w = count_score(board_state)
58
+ draw.text((10, 10), f"Black: {b}", font=font, fill='white')
59
+ draw.text((size-150, 10), f"White: {w}", font=font, fill='white')
60
+ # Winner display
 
61
  if is_game_over(board_state):
62
+ result = 'DRAW' if b==w else ('BLACK WINS' if b>w else 'WHITE WINS')
63
+ w_font = ImageFont.truetype('arial.ttf', 36) if hasattr(ImageFont, 'truetype') else font
64
+ draw.text((size//2 - 100, size//2 - 18), result, font=w_font, fill='yellow')
65
+ # Draw grid and stones
66
+ offset = 40
67
  for r in range(8):
68
  for c in range(8):
69
+ x0 = offset + c*cell
70
+ y0 = offset + r*cell
71
  x1, y1 = x0+cell, y0+cell
72
  draw.rectangle([x0,y0,x1,y1], outline='black')
73
+ val = board_state[r][c]
74
+ if val == 1:
75
  draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='white')
76
+ elif val == -1:
77
  draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='black')
78
  return img
79
 
80
+ # Handlers
81
+ def click_handler(evt: gr.SelectData, state):
 
 
 
 
82
  board, player, last_user, last_ai = state
83
+ # Calculate cell
84
+ x,y = evt.index; offset=40; cell=360//8
85
+ c = int((x-offset)//cell); r = int((y-offset)//cell)
86
+ if 0<=r<8 and 0<=c<8 and not is_game_over(board):
87
+ if apply_move(board, r, c, player): last_user=(r,c); player=-player
88
+ # AI move after delay
89
+ time.sleep(1)
90
+ if not is_game_over(board):
91
+ ai_mv = choose_move(board, player)
92
+ if ai_mv:
93
+ apply_move(board, ai_mv[0], ai_mv[1], player)
94
+ last_ai = ai_mv; player=-player
 
 
 
 
 
 
 
95
  return board_to_image(board, (board, player, last_user, last_ai)), (board, player, last_user, last_ai)
96
 
97
+ def reset_game():
98
+ return (initialize_board(), -1, None, None)
99
 
100
+ # UI
101
  with gr.Blocks() as demo:
102
  state = gr.State((initialize_board(), -1, None, None))
103
+ img = gr.Image(value=board_to_image(initialize_board(), (initialize_board(),-1,None,None)), interactive=True)
104
+ new_game = gr.Button("New Game")
105
  img.select(click_handler, inputs=[state], outputs=[img, state])
106
+ new_game.click(fn=lambda: (initialize_board(), -1, None, None), outputs=[state])
107
  demo.launch()