File size: 3,851 Bytes
c4367ba 93ed0ca c533acd edf941b 17edf34 293933e c533acd c4367ba a487d57 c4367ba 93ed0ca cc9d79f a487d57 c533acd c4367ba cc9d79f c533acd a487d57 c533acd c4367ba a487d57 c533acd c0fee0a 93ed0ca c533acd c0fee0a c4c68cc c0fee0a c533acd c0fee0a a487d57 c533acd a487d57 c533acd a487d57 c533acd 23f367b c533acd c4367ba c533acd a487d57 c533acd a487d57 c533acd a487d57 6ad4064 c4367ba c533acd a487d57 c533acd a487d57 c0fee0a c533acd 34d6098 c533acd b8ed266 a487d57 c533acd a487d57 c533acd 9b082e6 |
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 |
import gradio as gr
from PIL import Image, ImageDraw, ImageFont
import random
time
DIRECTIONS = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
# Game logic
def initialize_board():
board = [[0]*8 for _ in range(8)]
board[3][3], board[4][4] = 1, 1
board[3][4], board[4][3] = -1, -1
return board
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, p):
moves = [(r,c) for r in range(8) for c in range(8) if get_flips(board,r,c,p)]
return random.choice(moves) if moves 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):
return not any(get_flips(board,r,c,p) for p in (-1,1) for r in range(8) for c in range(8))
# Rendering
def board_to_image(board, state):
board_state, player, last_user, last_ai = state
size = 400; board_size = 360; cell = board_size//8
img = Image.new('RGB',(size, size), 'darkgreen')
draw = ImageDraw.Draw(img)
# Load font
try:
font = ImageFont.truetype('arial.ttf', 24)
except:
font = ImageFont.load_default()
# Scoreboard
b, w = count_score(board_state)
draw.text((10, 10), f"Black: {b}", font=font, fill='white')
draw.text((size-150, 10), f"White: {w}", font=font, fill='white')
# Winner display
if is_game_over(board_state):
result = 'DRAW' if b==w else ('BLACK WINS' if b>w else 'WHITE WINS')
w_font = ImageFont.truetype('arial.ttf', 36) if hasattr(ImageFont, 'truetype') else font
draw.text((size//2 - 100, size//2 - 18), result, font=w_font, fill='yellow')
# Draw grid and stones
offset = 40
for r in range(8):
for c in range(8):
x0 = offset + c*cell
y0 = offset + r*cell
x1, y1 = x0+cell, y0+cell
draw.rectangle([x0,y0,x1,y1], outline='black')
val = board_state[r][c]
if val == 1:
draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='white')
elif val == -1:
draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='black')
return img
# Handlers
def click_handler(evt: gr.SelectData, state):
board, player, last_user, last_ai = state
# Calculate cell
x,y = evt.index; offset=40; cell=360//8
c = int((x-offset)//cell); r = int((y-offset)//cell)
if 0<=r<8 and 0<=c<8 and not is_game_over(board):
if apply_move(board, r, c, player): last_user=(r,c); player=-player
# AI move after delay
time.sleep(1)
if not is_game_over(board):
ai_mv = choose_move(board, player)
if ai_mv:
apply_move(board, ai_mv[0], ai_mv[1], player)
last_ai = ai_mv; player=-player
return board_to_image(board, (board, player, last_user, last_ai)), (board, player, last_user, last_ai)
def reset_game():
return (initialize_board(), -1, None, None)
# UI
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_game = gr.Button("New Game")
img.select(click_handler, inputs=[state], outputs=[img, state])
new_game.click(fn=lambda: (initialize_board(), -1, None, None), outputs=[state])
demo.launch()
|