Renecto commited on
Commit
596f579
·
verified ·
1 Parent(s): 646ad12

Update app.py

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