File size: 4,313 Bytes
c4367ba 93ed0ca c0fee0a edf941b c0fee0a edf941b c4367ba cc9d79f c4367ba 93ed0ca cc9d79f c0fee0a c4367ba cc9d79f c0fee0a 93ed0ca c0fee0a c4367ba c0fee0a 93ed0ca c0fee0a 93ed0ca c0fee0a cc9d79f c4367ba c0fee0a cc9d79f c0fee0a 6ad4064 c4367ba c0fee0a b8ed266 c0fee0a b8ed266 c0fee0a 34d6098 b8ed266 c0fee0a c4367ba |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
import gradio as gr
from PIL import Image, ImageDraw, ImageFont
import random, time
# Game logic as before
DIRECTIONS = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
def initialize_board():
b = [[0]*8 for _ in range(8)]
b[3][3], b[4][4] = 1, 1
b[3][4], b[4][3] = -1, -1
return b
def get_flips(board, r, c, p):
if board[r][c] != 0: return []
flips=[]
for dr,dc in DIRECTIONS:
rr,cc=r+dr,c+dc; buf=[]
while 0<=rr<8 and 0<=cc<8 and board[rr][cc]==-p:
buf.append((rr,cc)); rr+=dr; cc+=dc
if buf and 0<=rr<8 and 0<=cc<8 and board[rr][cc]==p:
flips+=buf
return flips
def apply_move(board, r, c, p):
f=get_flips(board,r,c,p)
if not f: return False
board[r][c]=p
for rr,cc in f: board[rr][cc]=p
return True
def choose_move(board, player):
valid=[(r,c) for r in range(8) for c in range(8) if get_flips(board,r,c,player)]
return random.choice(valid) if valid else None
def count_score(board):
b=sum(cell==-1 for row in board for cell in row)
w=sum(cell==1 for row in board for cell in row)
return b,w
def is_game_over(board):
if any(get_flips(board,r,c,p) for p in [-1,1] for r in range(8) for c in range(8)): return False
return True
# Image renderer
FONT = ImageFont.truetype("arial.ttf", 24)
def board_to_image(board, state):
board, player, last_user, last_ai, history = state
size=360; cell=size//8
img=Image.new('RGB',(size,size+cell*2),'darkgreen')
draw=ImageDraw.Draw(img)
# Scoreboard top
b,w=count_score(board)
draw.rectangle([0,0,size,cell],fill='navy')
draw.text((10,2),f"BLACK: {b}",font=FONT,fill='white')
draw.text((size-160,2),f"WHITE: {w}",font=FONT,fill='white')
# Game end highlight
if is_game_over(board):
winner = "Draw" if b==w else ("Black Wins" if b>w else "White Wins")
draw.rectangle([0,cell,size,cell*2],fill='maroon')
draw.text((size//2-80,cell+2),winner,font=FONT,fill='yellow')
# Board
for r in range(8):
for c in range(8):
x0,y0=c*cell,cell*2+r*cell; x1,y1=x0+cell,y0+cell
draw.rectangle([x0,y0,x1,y1],outline='black')
# candidate
if board[r][c]==0 and get_flips(board,r,c,player):
draw.ellipse([x0+cell*0.4,y0+cell*0.4,x0+cell*0.6,y0+cell*0.6],fill='yellow')
if board[r][c]==1: draw.ellipse([x0+4,y0+4,x1-4,y1-4],fill='white')
if board[r][c]==-1: draw.ellipse([x0+4,y0+4,x1-4,y1-4],fill='black')
# markers
for mark,clr in ((state[2],'red'),(state[3],'blue')):
if mark:
mr,mc=mark; x0,y0=mc*cell,cell*2+mr*cell; x1,y1=x0+cell,y0+cell
draw.rectangle([x0,y0,x1,y1],outline=clr,width=4)
# history display
y=text_y=cell*2+8*cell+2
for i,res in enumerate(history[-5:]):
draw.text((10,y+i*(cell//2)),res,font=ImageFont.truetype("arial.ttf",16),fill='white')
return img
# Handlers
def click_handler(evt,state):
board,player,lu,la,history=state
x,y=evt.index; cell=360//8; c,r=int(x//cell),int((y-cell*2)//cell)
if 0<=r<8 and 0<=c<8 and not is_game_over(board):
if apply_move(board,r,c,player): lu=(r,c); player=-player
yield board_to_image(board,(board,player,lu,la,history)),(board,player,lu,la,history)
if is_game_over(board):
history.append(f"Game {len(history)+1}: {'Black' if count_score(board)[0]>count_score(board)[1] else 'White' if count_score(board)[1]>count_score(board)[0] else 'Draw'}")
return
# AI
yield board_to_image(board,(board,player,lu,la,history)),(board,player,lu,la,history)
time.sleep(2)
ai_mv=choose_move(board,player)
if ai_mv: apply_move(board,ai_mv[0],ai_mv[1],player); la=ai_mv; player=-player
yield board_to_image(board,(board,player,lu,la,history)),(board,player,lu,la,history)
def reset_handler():
return initialize_board(),-1,None,None,[]
with gr.Blocks() as demo:
state=gr.State((initialize_board(),-1,None,None,[]))
img=gr.Image(value=board_to_image(initialize_board(),(initialize_board(),-1,None,None,[])),interactive=True)
new_btn=gr.Button("New Game")
img.select(click_handler,inputs=[state],outputs=[img,state])
new_btn.click(fn=reset_handler,outputs=[state,img])
demo.launch()
|