예제 소스
바둑 on-policy 학습: 대국 로그를 KataGo 라벨로 바꾸기 · 파일 169개
GoBoard.tsx
"use client";
import { BOARD_SIZE, EMPTY, BLACK, WHITE, type Stone, type Point } from "@/lib/board";
import styles from "./GoBoard.module.css";
type Props = {
board: Stone[];
lastMove: Point | null;
pending: Point | null;
ownership?: number[] | null;
onSelect: (r: number, c: number) => void;
interactive: boolean;
};
function ownershipStyle(v: number): React.CSSProperties | undefined {
const a = Math.min(0.55, Math.abs(v) * 0.7);
if (a < 0.08) return undefined;
if (v < 0) return { background: `rgba(20, 20, 20, ${a})` };
return { background: `rgba(255, 255, 255, ${a})` };
}
export function GoBoard({ board, lastMove, pending, ownership, onSelect, interactive }: Props) {
const cells: React.ReactNode[] = [];
for (let r = 0; r < BOARD_SIZE; r++) {
for (let c = 0; c < BOARD_SIZE; c++) {
const i = r * BOARD_SIZE + c;
const v = board[i];
const isStar =
([3, 9, 15].includes(r) && [3, 9, 15].includes(c)) || (r === 9 && c === 9);
const isLast = lastMove && lastMove.r === r && lastMove.c === c;
const isPending = pending && pending.r === r && pending.c === c;
const own = ownership?.[i];
cells.push(
<button
key={`${r}-${c}`}
type="button"
className={styles.cell}
style={{ gridColumn: c + 1, gridRow: r + 1 }}
disabled={!interactive || v !== EMPTY}
onClick={() => onSelect(r, c)}
aria-label={`${r},${c}`}
>
{own != null && v === EMPTY ? (
<span className={styles.own} style={ownershipStyle(own)} />
) : null}
{isStar && v === EMPTY && !isPending ? <span className={styles.star} /> : null}
{v === BLACK ? <span className={`${styles.stone} ${styles.black}`} /> : null}
{v === WHITE ? <span className={`${styles.stone} ${styles.white}`} /> : null}
{isPending && v === EMPTY ? <span className={styles.ghost} /> : null}
{isLast ? <span className={styles.mark} /> : null}
</button>,
);
}
}
return (
<div className={styles.frame}>
<div className={styles.grid} role="grid" aria-label="바둑판">
<svg className={styles.lines} viewBox="0 0 19 19" preserveAspectRatio="none">
{Array.from({ length: BOARD_SIZE }, (_, i) => (
<g key={i}>
<line x1={0.5} y1={i + 0.5} x2={18.5} y2={i + 0.5} />
<line x1={i + 0.5} y1={0.5} x2={i + 0.5} y2={18.5} />
</g>
))}
</svg>
{cells}
</div>
</div>
);
}