게시판SGF 기보로 학습하는 바둑 LLM 인공지능예제 소스

예제 소스

SGF 기보로 학습하는 바둑 LLM 인공지능 · 파일 169개

gamejudge.h

#pragma once

#include "goboard.h"

#include <QVector>

namespace GameJudge {

enum class RegionKind {
    SettledBlack, ///< 흑의 확정된 집(살아 있는 흑 그룹들로만 둘러싸임)
    SettledWhite, ///< 백의 확정된 집
    Dame,         ///< 양쪽 살아 있는 그룹이 둘러싸 — 둘 필요 없음
    Active,       ///< 분쟁 중. 한쪽 이상의 둘러싼 그룹이 아직 죽음/미생.
};

struct GroupBrief {
    Stone color = Stone::Empty;
    int stones = 0;
    int liberties = 0;
    int potentialEyes = 0;
    bool alive = false;
};

struct Analysis {
    int N = 0;
    QVector<GroupBrief> groups;          ///< 그룹 인덱스 → 정보
    QVector<int> stoneToGroup;           ///< 보드 칸 → 그룹 인덱스 (빈칸 -1)
    QVector<int> cellRegion;             ///< 보드 칸 → 빈영역 인덱스 (돌 -1)
    QVector<RegionKind> regionKind;      ///< 빈영역 인덱스 → 종류
    bool blackHasMeaningfulMove = false; ///< 흑이 둘 가치 있는 자리 존재
    bool whiteHasMeaningfulMove = false; ///< 백이 둘 가치 있는 자리 존재

    /// (r,c) 가 settled territory 면 그 색을, 아니면 Empty.
    Stone settledOwner(int r, int c) const;
    bool isDame(int r, int c) const;
    bool isActive(int r, int c) const;
};

/// 보드 상태를 분석.
Analysis analyze(const GoBoard &b);

/// who 가 둘 의미가 있는가? false 면 패스가 정답.
bool shouldPass(const GoBoard &b, Stone who);

/// 양쪽 모두 둘 의미 있는 수가 없는가? (= 게임 종료 시점)
bool gameIsOver(const GoBoard &b);

/**
 * 게임 도중 매 수마다 보여주는 어림 계가 (running estimate).
 *
 * finalScoring() 과 동일한 analyze() 결과를 사용한다:
 *  - 산 그룹 돌 수 (중국식 area 의 "내 돌")
 *  - SettledBlack/SettledWhite 확정 집
 *  - 죽은 상대 돌 → 내 territory 가산
 * 공배(dame)·분쟁(active) 은 점수에 넣지 않고 표시만 한다.
 *
 * 생사/영역 휴리스틱이 개선되면 이 어림도 함께 좋아진다.
 */
struct Estimate {
    int blackAliveStones = 0;
    int whiteAliveStones = 0;
    int blackDeadStones = 0; ///< 죽은 흑 돌 수 (점수상 백 territory 로 환원됨)
    int whiteDeadStones = 0; ///< 죽은 백 돌 수 (점수상 흑 territory 로 환원됨)
    int blackTerritory = 0;  ///< SettledBlack 영역 합계
    int whiteTerritory = 0;  ///< SettledWhite 영역 합계
    int dame = 0;            ///< 어느 쪽 영역도 아닌 빈 점 (양쪽 alive 그룹 사이)
    int active = 0;          ///< 분쟁 중인 빈 점 (점수에는 미반영, 표시만)
    double komi = 0.0;
    double finalBlack = 0.0;
    double finalWhite = 0.0;
    Stone leader = Stone::Empty; ///< Empty=대등
    double margin = 0.0;         ///< |finalBlack - finalWhite|
};

Estimate estimateScore(const GoBoard &b);

/**
 * 종국 계가 (한쪽이 패스 → 상대가 계가 수락 시 호출).
 *
 * 처리 절차:
 *  - 보드의 모든 그룹에 대해 alive 판정 (analyze() 와 동일 휴리스틱).
 *  - alive 인 자기 그룹의 돌 수 → 자기 돌 점수.
 *  - alive 가 아닌 그룹(사석)의 돌 수 → 상대 territory 에 가산.
 *  - 빈 영역마다 alive 그룹만 인접 색으로 보고:
 *      • 한쪽 alive 만 인접 → 그 쪽 territory.
 *      • 양쪽 alive 인접 → dame (반분: 흑 = (n+1)/2, 백 = n/2).
 *      • 어느 쪽 alive 도 인접 안 함 → dame 으로 처리 (반분).
 *  - finalBlack = blackStones + blackTerritory.
 *  - finalWhite = whiteStones + whiteTerritory + komi.
 *
 * 반환된 ScoreReport 를 GoBoard::acceptScoring() 에 넘기면 status/winner 가 확정됨.
 */
ScoreReport finalScoring(const GoBoard &b);

} // namespace GameJudge