Renecto commited on
Commit
6f3a24a
·
verified ·
1 Parent(s): 596f579

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -70
app.py CHANGED
@@ -5,105 +5,103 @@ 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()
 
5
 
6
  DIRECTIONS = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
7
 
 
8
  def initialize_board():
9
+ b = [[0]*8 for _ in range(8)]
10
+ b[3][3], b[4][4] = 1, 1
11
+ 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
  def board_to_image(state):
48
+ board, player, last_user, last_ai = state
49
+ size, bs = 400, 360; off = 20; cell = bs//8
50
+ img = Image.new('RGB', (size, size), 'darkgreen')
51
+ draw = ImageDraw.Draw(img)
52
+ try: fnt = ImageFont.truetype('arial.ttf',28)
53
+ except: fnt = ImageFont.load_default()
54
+ bl, wh = count_score(board)
55
+ draw.rectangle([0,0,size,off], fill='black')
56
+ draw.text((10,2), f"Black: {bl}", font=fnt, fill='yellow')
57
+ draw.text((size-140,2), f"White: {wh}", font=fnt, fill='yellow')
58
+ for r,c in get_possible(board, player):
59
+ x = off+c*cell+cell//2; y = off+r*cell+cell//2
60
+ draw.ellipse([x-5,y-5,x+5,y+5], outline='blue', width=2)
 
 
 
61
  for r in range(8):
62
  for c in range(8):
63
+ x0,y0 = off+c*cell, off+r*cell; x1,y1 = x0+cell, y0+cell
64
+ draw.rectangle([x0,y0,x1,y1], outline='black')
65
+ v = board[r][c]
66
  if v:
67
+ color = 'white' if v==1 else 'black'
68
+ draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill=color)
69
+ for pos,col in [(last_user,'red'), (last_ai,'orange')]:
 
70
  if pos:
71
+ r,c = pos; x0,y0 = off+c*cell, off+r*cell; x1,y1 = x0+cell, y0+cell
72
+ draw.rectangle([x0+2,y0+2,x1-2,y1-2], outline=col, width=4)
 
73
  if is_game_over(board):
74
+ res = 'DRAW' if bl==wh else 'BLACK WINS' if bl>wh else 'WHITE WINS'
75
+ draw.text((size//2-80,size//2-15), res, font=fnt, fill='cyan')
76
  return img
77
 
78
+ def click_handler(evt, state):
79
+ if state is None:
80
+ state = (initialize_board(), -1, None, None)
81
+ board, player, last_user, last_ai = state
82
+ x, y = evt.index; cell = 360//8; off = 20
83
+ c = int((x-off)//cell); r = int((y-off)//cell)
84
  if 0<=r<8 and 0<=c<8 and not is_game_over(board):
85
+ if apply_move(board, r, c, player):
86
+ last_user = (r, c); player = -player
87
+ time.sleep(1)
88
+ if not is_game_over(board):
89
+ mv = choose_move(board, player)
90
+ if mv:
91
+ apply_move(board, mv[0], mv[1], player)
92
+ last_ai = mv; player = -player
93
+ new_state = (board, player, last_user, last_ai)
94
+ return board_to_image(new_state), new_state
95
 
96
  def reset_game():
97
+ state = (initialize_board(), -1, None, None)
98
+ return board_to_image(state), state
99
 
100
+ demo = gr.Blocks()
 
101
  with demo:
102
+ state = gr.State((initialize_board(), -1, None, None))
103
+ img = gr.Image(value=board_to_image((initialize_board(),-1,None,None)), interactive=True)
104
+ new = gr.Button('New Game')
105
+ img.select(click_handler, inputs=[state], outputs=[img, state], show_progress=True)
106
+ new.click(reset_game, outputs=[img, state])
107
  demo.launch()