まだ白石(PC)は弱いので強化中!
# 碁ならべver5.py ChatGPT-6 OK
# 白は黒の4x3、4x4を見逃している--禁止手 7/27/2025
# 白は飛び3を見逃す
import FreeSimpleGUI as sg
import random
import time
sg.theme('DarkBrown7')
BOARD_SIZE = 15 #15x15が標準size
EMPTY = '' # 碁盤目には何も書き込まない状態
BLACK = '●'
WHITE = '○'
def create_layout(): #layoutを設定する
board_layout = [[
sg.Button(EMPTY, size=(2, 1), font=(None, 18), pad=(0, 0), key=f'{y},{x}', button_color=('black', '#C8B560'))
for x in range(BOARD_SIZE)] for y in range(BOARD_SIZE)
]
control_layout = [[sg.Button('Again', key='AGAIN'), sg.Button('End', key='END')]] # 15x15の碁盤を作成している
return board_layout + control_layout # 碁盤作成後に「AGAIN」「END」のボタンを追加している
def reset_board(window): # elif event == 'AGAIN':の項で碁盤を元へ戻す
for y in range(BOARD_SIZE):
for x in range(BOARD_SIZE):
window[f'{y},{x}'].update(EMPTY, button_color=('black', '#C8B560'), disabled=False)
def is_valid(y, x):
return 0 <= y < BOARD_SIZE and 0 <= x < BOARD_SIZE
def get_board(window):
return [[window[f'{y},{x}'].GetText() for x in range(BOARD_SIZE)] for y in range(BOARD_SIZE)]
def check_winner(board, stone):
directions = [(0,1), (1,0), (1,1), (-1,1)]
for y in range(BOARD_SIZE):
for x in range(BOARD_SIZE):
for dy, dx in directions:
count = 0
for i in range(5):
ny, nx = y + dy*i, x + dx*i
if is_valid(ny, nx) and board[ny][nx] == stone:
count += 1
else:
break
if count == 5:
return True
return False
def block_open_three(board, stone):
directions = [(0,1), (1,0), (1,1), (-1,1)]
for y in range(BOARD_SIZE):
for x in range(BOARD_SIZE):
for dy, dx in directions:
coords = [(y + dy*i, x + dx*i) for i in range(-1, 4)]
if all(is_valid(cy, cx) for cy, cx in coords):
line = [board[cy][cx] for cy, cx in coords]
if line == [EMPTY, stone, stone, stone, EMPTY]:
for idx in [0, 4]:
ny, nx = coords[idx]
if board[ny][nx] == EMPTY:
return ny, nx
return None
def check_line(board, stone, count_needed):
directions = [(0,1), (1,0), (1,1), (-1,1)]
for y in range(BOARD_SIZE):
for x in range(BOARD_SIZE):
if board[y][x] != EMPTY:
continue
for dy, dx in directions:
for i in range(5):
sy, sx = y - dy*i, x - dx*i
coords = [(sy + dy*j, sx + dx*j) for j in range(5)]
if all(is_valid(cy, cx) for cy, cx in coords):
line = [board[cy][cx] for cy, cx in coords]
if line.count(stone) == count_needed and line.count(EMPTY) == 5 - count_needed:
return y, x
return None
def pc_move(window):
board = get_board(window)
# 1. 勝てる手
move = check_line(board, WHITE, 4)
if move:
y, x = move
flash_white(window, y, x)
return
# 2. 黒の4連をブロック
move = check_line(board, BLACK, 4)
if move:
y, x = move
flash_white(window, y, x)
return
# 3. 両三(□●●●□)をブロック
move = block_open_three(board, BLACK)
if move:
y, x = move
flash_white(window, y, x)
return
# 4. 黒の3連ブロック
move = check_line(board, BLACK, 3)
if move:
y, x = move
flash_white(window, y, x)
return
# 5. 黒石の近くに寄せる(スコア)
scores = {}
for y in range(BOARD_SIZE):
for x in range(BOARD_SIZE):
if board[y][x] != EMPTY:
continue
score = 0
for dy in [-1,0,1]:
for dx in [-1,0,1]:
ny, nx = y + dy, x + dx
if is_valid(ny, nx):
if board[ny][nx] == BLACK:
score += 2
elif board[ny][nx] == WHITE:
score += 1
scores[(y,x)] = score
if scores:
y, x = max(scores, key=scores.get)
flash_white(window, y, x)
return
# 6. ランダム
empty = [(y,x) for y in range(BOARD_SIZE) for x in range(BOARD_SIZE) if board[y][x] == EMPTY]
if empty:
y, x = random.choice(empty)
flash_white(window, y, x)
def flash_white(window, y, x):
key = f'{y},{x}'
window[key].update('○', button_color=('black', 'yellow'))
window.refresh()
time.sleep(1)
window[key].update('○', button_color=('black', '#C8B560'), disabled=True)
# --- メイン ---
layout = create_layout()
window = sg.Window('五目並べver5.1', layout)
while True:
event, values = window.read()
if event in (sg.WINDOW_CLOSED,):
break
elif event == 'END':
confirm = sg.popup_yes_no('終了しますか?', title='確認')
if confirm == 'Yes':
break
else:
continue
elif event == 'AGAIN':
reset_board(window)
continue
elif ',' in event:
if window[event].GetText() == EMPTY:
window[event].update('●', button_color=('white', '#333333'), disabled=True)
board = get_board(window)
if check_winner(board, BLACK):
sg.popup('黒の勝ちです!')
continue
pc_move(window)
board = get_board(window)
if check_winner(board, WHITE):
sg.popup('白の勝ちです!')
window.close()