예제 소스
SGF 기보로 학습하는 바둑 LLM 인공지능 · 파일 169개
test_cross_lessons.py
from __future__ import annotations
import json
import sys
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from scripts.monitor_mariago_web_play import ( # noqa: E402
BLACK,
MAX_GAME_PLIES,
WHITE,
_heuristic_score,
empty_board,
heuristic_move,
idx,
)
from vlm_server.cross_lessons import ( # noqa: E402
absorb_game,
empty_book,
heuristic_shape_delta,
lesson_bonus_heuristic,
lesson_bonus_r5,
r5_live_delta,
)
def board_with(*, black=(), white=()):
board = empty_board()
for r, c in black:
board[idx(r, c)] = BLACK
for r, c in white:
board[idx(r, c)] = WHITE
return board
class CrossLessonTest(unittest.TestCase):
def test_game_length_is_capped_at_200(self):
self.assertEqual(MAX_GAME_PLIES, 200)
def test_hogu_entry_is_penalized_on_the_heuristic(self):
board = board_with(white=[(3, 4), (4, 3), (4, 5)])
inside = _heuristic_score(board, 4, 4, BLACK, None)
outside = _heuristic_score(board, 10, 10, BLACK, None)
self.assertIsNotNone(inside)
self.assertIsNotNone(outside)
self.assertLess(inside, outside)
self.assertLess(r5_live_delta(board, 4, 4, BLACK), 0)
def test_winner_moves_teach_the_other_side(self):
book = empty_book()
moves = [
"1. B Q16 (3,15)",
"2. W D4 (15,3)",
"3. B D16 (3,3)",
"4. W Q4 (15,15)",
"5. B C15 (4,2)",
"6. W C3 (16,2)",
]
# 백이 흑 한 점을 따내는 국면을 직접 넣는다.
board = board_with(black=[(3, 3)], white=[(2, 3), (3, 2), (4, 3)])
capture = _heuristic_score(board, 3, 4, WHITE, None)
self.assertIsNotNone(capture)
absorb_game(
book,
[
"1. B D16 (3,3)",
"2. W C16 (3,2)",
"3. B C15 (4,2)",
"4. W E16 (3,4)",
"5. B C17 (2,2)",
"6. W D17 (2,3)",
"7. B PASS",
"8. W D15 (4,3)",
],
"white",
"unit:capture",
)
self.assertGreater(book["to_heuristic"]["capture"], 0)
self.assertGreater(
lesson_bonus_heuristic(board, 3, 4, WHITE, book),
0,
)
self.assertEqual(lesson_bonus_r5(board, 10, 10, BLACK, book), 0.0)
self.assertFalse(
absorb_game(book, moves, "black", "unit:capture"),
)
def test_heuristic_shape_reaches_r5_after_four_stones(self):
board = board_with(
black=[(3, 3), (3, 9), (3, 15), (15, 3)],
)
linked = heuristic_shape_delta(board, 3, 6, BLACK)
isolated = heuristic_shape_delta(board, 9, 9, BLACK)
self.assertGreater(linked, isolated)
def test_lesson_file_roundtrip_does_not_change_capture_priority(self):
board = board_with(
black=[(2, 3), (3, 2), (4, 3)],
white=[(3, 3)],
)
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "games.jsonl"
path.write_text(
json.dumps(
{
"game_id": 1,
"score": {"winner": "black"},
"moves": ["1. B D16 (3,3)", "2. W Q16 (3,15)"],
}
)
+ "\n",
encoding="utf-8",
)
from vlm_server.cross_lessons import ingest_jsonl
book = ingest_jsonl(path, empty_book(), source="tmp")
self.assertIn("tmp:1", book["seen_games"])
self.assertEqual(
heuristic_move(board, BLACK, None, __import__("random").Random(1))[:2],
(3, 4),
)
if __name__ == "__main__":
unittest.main()