예제 소스
SGF 기보로 학습하는 바둑 LLM 인공지능 · 파일 169개
shapes.py
"""모양 판정: 호구(虎口).
호구 = 빈 점 P 의 네 방향 중 세 방향이 같은 색 돌(판 밖은 벽으로 셈)이고 남은 한 방향(입구)이 빈 점.
- 상대 호구에 들어가면 입구 하나만 남는 단수 → 바로 잡힌다 (hogu_entry)
- 내 호구를 메우면 이미 끊기지 않는 곳에 한 수를 쓰는 느린 수 (hogu_fill)
단, 둘러싼 내 그룹 활로가 2 이하(먹여치기·수부족 위험)이거나 따내는 수면 메워도 된다.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Optional
from .ladder import BOARD_SIZE, _Board
Point = tuple[int, int]
@dataclass
class HoguInfo:
point: Point
owner: int # 호구를 만든 색
mouth: Point # 입구(빈 점)
walls: int # 판 밖 방향 수
def tiger_mouth(cells: bytes | bytearray, r: int, c: int, *, size: int = BOARD_SIZE) -> Optional[HoguInfo]:
idx = r * size + c
if cells[idx] != 0:
return None
color = 0
stones = 0
walls = 0
empties: list[Point] = []
for dr, dc in ((-1, 0), (1, 0), (0, -1), (0, 1)):
nr, nc = r + dr, c + dc
if not (0 <= nr < size and 0 <= nc < size):
walls += 1
continue
v = cells[nr * size + nc]
if v == 0:
empties.append((nr, nc))
elif color == 0 or v == color:
color = v
stones += 1
else:
return None
if color == 0 or len(empties) != 1 or stones < 2 or stones + walls != 3:
return None
return HoguInfo((r, c), color, empties[0], walls)
def hogu_verdict(
cells: bytes | bytearray, r: int, c: int, who: int, *, size: int = BOARD_SIZE
) -> Optional[str]:
"""who 가 (r,c) 에 둘 때 호구 관련 나쁜 수면 'hogu_entry' | 'hogu_fill', 아니면 None."""
info = tiger_mouth(cells, r, c, size=size)
if info is None:
return None
b = _Board(cells, size)
idx = r * size + c
b2 = b.copy()
captured = b2.play(idx, who)
if captured is None or captured > 0:
return None
if info.owner != who:
return "hogu_entry" if len(b2.group(idx)[1]) <= 1 else None
for dr, dc in ((-1, 0), (1, 0), (0, -1), (0, 1)):
nr, nc = r + dr, c + dc
if 0 <= nr < size and 0 <= nc < size and b.c[nr * size + nc] == who:
if len(b.group(nr * size + nc)[1]) <= 2:
return None
return "hogu_fill"
def hogu_points(cells: bytes | bytearray, *, size: int = BOARD_SIZE) -> list[HoguInfo]:
out = []
for i in range(size * size):
if cells[i] == 0:
h = tiger_mouth(cells, i // size, i % size, size=size)
if h is not None:
out.append(h)
return out