게시판바둑 on-policy 학습: 대국 로그를 KataGo 라벨로 바꾸기예제 소스

예제 소스

바둑 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>
  );
}