File size: 3,482 Bytes
c4367ba 6ad4064 edf941b b8ed266 edf941b c4367ba 34d6098 c4367ba b8ed266 c4367ba b8ed266 c4367ba b8ed266 c4367ba 6ad4064 b8ed266 6ad4064 c4367ba b8ed266 6ad4064 c4367ba b8ed266 c4367ba b8ed266 c4367ba b8ed266 c4367ba b8ed266 34d6098 b8ed266 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 |
import gradio as gr
from PIL import Image, ImageDraw
import random
time
def choose_move(board, player):
valid_moves = []
for r in range(8):
for c in range(8):
if get_flips(board, r, c, player):
valid_moves.append((r, c))
if not valid_moves:
return None
return random.choice(valid_moves)
def initialize_board():
board = [[0 for _ in range(8)] for _ in range(8)]
board[3][3], board[4][4] = 1, 1
board[3][4], board[4][3] = -1, -1
return board
DIRECTIONS = [(-1, -1), (-1, 0), (-1, 1),
(0, -1), (0, 1),
(1, -1), (1, 0), (1, 1)]
def get_flips(board, row, col, player):
if board[row][col] != 0:
return []
flips = []
for dr, dc in DIRECTIONS:
r, c = row + dr, col + dc
buffer = []
while 0 <= r < 8 and 0 <= c < 8 and board[r][c] == -player:
buffer.append((r, c)); r += dr; c += dc
if buffer and 0 <= r < 8 and 0 <= c < 8 and board[r][c] == player:
flips.extend(buffer)
return flips
def apply_move(board, row, col, player):
flips = get_flips(board, row, col, player)
if not flips: return False
board[row][col] = player
for r, c in flips: board[r][c] = player
return True
def board_to_image(board, img_size=320):
cell = img_size // 8
img = Image.new('RGB', (img_size, img_size), 'green')
draw = ImageDraw.Draw(img)
for r in range(8):
for c in range(8):
x0, y0 = c*cell, r*cell; x1, y1 = x0+cell, y0+cell
draw.rectangle([x0,y0,x1,y1], outline='black')
if board[r][c]==1: draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='white')
elif board[r][c]==-1: draw.ellipse([x0+4,y0+4,x1-4,y1-4], fill='black')
return img
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 click_handler(evt: gr.SelectData, state):
board, player = state
x, y = evt.index
cell = 320/8
r, c = int(y//cell), int(x//cell)
if not (0<=r<8 and 0<=c<8):
yield board_to_image(board), "ボード上をクリックしてください。", state
return
if not apply_move(board, r, c, player):
yield board_to_image(board), f"({r+1},{c+1})には置けません。", state
return
b,w = count_score(board)
commentary = f"あなたは({r+1},{c+1})に石を置きました。\n現在:黒{b} - 白{w}。AIの思考中…"
player = -player
yield board_to_image(board), commentary, (board, player)
time.sleep(2)
ai_mv = choose_move(board, player)
if ai_mv:
apply_move(board, ai_mv[0], ai_mv[1], player)
b,w = count_score(board)
commentary = f"AIは({ai_mv[0]+1},{ai_mv[1]+1})に石を置きました。\n現在:黒{b} - 白{w}。{'あなた' if player==-1 else 'AI'}の番です。"
else:
commentary = "AIはパスしました。あなたの番です。"
player = -player
yield board_to_image(board), commentary, (board, player)
with gr.Blocks() as demo:
gr.HTML("<h2>オセロ(リバーシ)</h2>")
state = gr.State((initialize_board(), -1))
board_img = gr.Image(value=board_to_image(initialize_board()), interactive=True)
commentary = gr.Markdown("黒2 - 白2。黒の番です。")
board_img.select(click_handler, inputs=[state], outputs=[board_img, commentary, state])
demo.launch()
|