예제 소스
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