예제 #1
0
    def test_handicap_load(self):
        input_sgf = (
            "(;GM[1]FF[4]CA[UTF-8]AP[CGoban:3]ST[2]RU[Chinese]SZ[19]HA[2]KM[0.50]TM[600]OT[5x30 byo-yomi]PW[kneh]PB[ayabot003]WR[4k]BR[6k]DT[2021-01-04]PC[The KGS Go Server at http://www.gokgs.com/]C[ayabot003 [6k\\"
            "]: GTP Engine for ayabot003 (black): Aya version 7.85x]RE[W+Resign];B[pd]BL[599.647];B[dp]BL[599.477];W[pp]WL[597.432];B[cd]BL[598.896];W[ed]WL[595.78];B[ec]BL[598.558])"
        )
        root = KaTrainSGF.parse_sgf(input_sgf)
        game = Game(MockKaTrain(force_package_config=True), MockEngine(), move_tree=root)
        assert 0 == len(game.root.placements)

        root2 = KaTrainSGF.parse_sgf("(;GM[1]FF[4]SZ[19]HA[2];)")
        game2 = Game(MockKaTrain(force_package_config=True), MockEngine(), move_tree=root2)
        assert 2 == len(game2.root.placements)
예제 #2
0
    def test_ko(self, new_game):
        b = Game(MockKaTrain(force_package_config=True),
                 MockEngine(),
                 move_tree=new_game)
        for move in ["A2", "B1"]:
            b.play(Move.from_gtp(move, player="B"))

        for move in ["B2", "C1"]:
            b.play(Move.from_gtp(move, player="W"))
        b.play(Move.from_gtp("A1", player="W"))
        assert 4 == len(self.nonempty_chains(b))
        assert 4 == len(b.stones)
        assert 1 == len(b.prisoners)
        with pytest.raises(IllegalMoveException) as exc:
            b.play(Move.from_gtp("B1", player="B"))
        assert "Ko" in str(exc.value)

        b.play(Move.from_gtp("B1", player="B"), ignore_ko=True)
        assert 2 == len(b.prisoners)

        with pytest.raises(IllegalMoveException) as exc:
            b.play(Move.from_gtp("A1", player="W"))

        b.play(Move.from_gtp("F1", player="W"))
        b.play(Move(coords=None, player="B"))
        b.play(Move.from_gtp("A1", player="W"))
        assert 3 == len(b.prisoners)
예제 #3
0
 def _do_new_game(self,
                  move_tree=None,
                  analyze_fast=False,
                  sgf_filename=None):
     self.idle_analysis = False
     mode = self.play_analyze_mode
     if (move_tree is not None
             and mode == MODE_PLAY) or (move_tree is None
                                        and mode == MODE_ANALYZE):
         self.play_mode.switch_ui_mode(
         )  # for new game, go to play, for loaded, analyze
     self.board_gui.animating_pv = None
     self.engine.on_new_game()  # clear queries
     self.game = Game(
         self,
         self.engine,
         move_tree=move_tree,
         analyze_fast=analyze_fast or not move_tree,
         sgf_filename=sgf_filename,
     )
     for bw, player_info in self.players_info.items():
         player_info.sgf_rank = self.game.root.get_property(bw + "R")
         player_info.calculated_rank = None
         if sgf_filename is not None:  # load game->no ai player
             player_info.player_type = PLAYER_HUMAN
             player_info.player_subtype = PLAYING_NORMAL
         self.update_player(bw,
                            player_type=player_info.player_type,
                            player_subtype=player_info.player_subtype)
     self.controls.graph.initialize_from_game(self.game.root)
     self.update_state(redraw_board=True)
예제 #4
0
 def test_merge(self):
     b = Game(MockKaTrain(), MockEngine())
     b.play(Move.from_gtp("B9", player="B"))
     b.play(Move.from_gtp("A3", player="B"))
     b.play(Move.from_gtp("A9", player="B"))
     assert 2 == len(self.nonempty_chains(b))
     assert 3 == len(b.stones)
     assert 0 == len(b.prisoners)
예제 #5
0
 def test_collide(self, new_game):
     b = Game(MockKaTrain(force_package_config=True), MockEngine(), move_tree=new_game)
     b.play(Move.from_gtp("B9", player="B"))
     with pytest.raises(IllegalMoveException):
         b.play(Move.from_gtp("B9", player="W"))
     assert 1 == len(self.nonempty_chains(b))
     assert 1 == len(b.stones)
     assert 0 == len(b.prisoners)
예제 #6
0
 def test_collide(self):
     b = Game(MockKaTrain(), MockEngine())
     b.play(Move.from_gtp("B9", player="B"))
     with pytest.raises(IllegalMoveException):
         b.play(Move.from_gtp("B9", player="W"))
     assert 1 == len(self.nonempty_chains(b))
     assert 1 == len(b.stones)
     assert 0 == len(b.prisoners)
예제 #7
0
 def test_merge(self, new_game):
     b = Game(MockKaTrain(force_package_config=True), MockEngine(), move_tree=new_game)
     b.play(Move.from_gtp("B9", player="B"))
     b.play(Move.from_gtp("A3", player="B"))
     b.play(Move.from_gtp("A9", player="B"))
     assert 2 == len(self.nonempty_chains(b))
     assert 3 == len(b.stones)
     assert 0 == len(b.prisoners)
예제 #8
0
def test_foxwq():
    for sgf in ["data/fox sgf error.sgf", "data/fox sgf works.sgf"]:
        file = os.path.join(os.path.dirname(__file__), sgf)
        move_tree = KaTrainSGF.parse_file(file)
        katrain = KaTrainBase(force_package_config=True, debug_level=0)
        game = Game(katrain, MagicMock(), move_tree)

        assert [] == move_tree.placements
        assert [] == game.root.placements
        while game.current_node.children:
            assert 1 == len(game.current_node.children)
            game.redo(1)
예제 #9
0
def play_game(black: AI, white: AI):
    players = {"B": black, "W": white}
    engines = {"B": black.get_engine(), "W": white.get_engine()}
    tag = f"{black.name} vs {white.name}"
    try:
        game = Game(Logger(),
                    engines,
                    game_properties={
                        "SZ": BOARDSIZE,
                        "PW": white.strategy,
                        "PB": black.strategy
                    })
        game.root.add_list_property("PW", [white.name])
        game.root.add_list_property("PB", [black.name])
        game.root.properties["AP"] = ["kt-selfplay"]
        start_time = time.time()
        while not game.end_result and game.current_node.depth < 300:
            p = game.current_node.next_player
            move, node = generate_ai_move(game, players[p].strategy,
                                          players[p].ai_settings)
        while not game.current_node.analysis_complete:
            time.sleep(0.001)
        game.game_id += f"_{game.current_node.format_score()}"
        if OUTPUT_SGF:
            sgf_out_msg = game.write_sgf("sgf_selfplay_simple/",
                                         trainer_config={
                                             "eval_show_ai": True,
                                             "save_feedback": [True],
                                             "eval_thresholds": [0]
                                         })
        else:
            sgf_out_msg = "<not saved>"
        print(
            f"{tag}\tGame finished in {time.time()-start_time:.1f}s @ move {game.current_node.depth} {game.current_node.format_score()} -> {sgf_out_msg}",
            file=sys.stderr,
        )
        score = game.current_node.score
        if score > 0.3:
            black.elo_comp.beat(white.elo_comp)
        elif score < -0.3:
            white.elo_comp.beat(black.elo_comp)
        else:
            black.elo_comp.tied(white.elo_comp)

        results[tag].append(score)
        all_results.append((black.name, white.name, score))

    except Exception as e:
        print(f"Exception in playing {tag}: {e}")
        print(f"Exception in playing {tag}: {e}", file=sys.stderr)
        traceback.print_exc()
        traceback.print_exc(file=sys.stderr)
예제 #10
0
    def test_ai_strategies(self):
        katrain = KaTrainBase(force_package_config=True, debug_level=0)
        engine = KataGoEngine(katrain, katrain.config("engine"))

        game = Game(katrain, engine)
        n_rounds = 3
        for _ in range(n_rounds):
            for strategy in AI_STRATEGIES:
                settings = katrain.config(f"ai/{strategy}")
                move, played_node = generate_ai_move(game, strategy, settings)
                katrain.log(f"Testing strategy {strategy} -> {move}", OUTPUT_INFO)
                assert move.coords is not None
                assert played_node == game.current_node

        assert game.current_node.depth == len(AI_STRATEGIES) * n_rounds

        for strategy in AI_STRATEGIES:
            game = Game(katrain, engine)
            settings = katrain.config(f"ai/{strategy}")
            move, played_node = generate_ai_move(game, strategy, settings)
            katrain.log(f"Testing strategy on first move {strategy} -> {move}", OUTPUT_INFO)
            assert game.current_node.depth == 1
예제 #11
0
 def _do_new_game(self, move_tree=None, analyze_fast=False):
     if move_tree is None:
         self.play_mode.select_mode(MODE_PLAY)
     else:
         self.play_mode.select_mode(MODE_ANALYZE)
     self.board_gui.animating_pv = None
     self.engine.on_new_game()  # clear queries
     self.game = Game(self,
                      self.engine,
                      move_tree=move_tree,
                      analyze_fast=analyze_fast)
     self.controls.graph.initialize_from_game(self.game.root)
     self.update_state(redraw_board=True)
예제 #12
0
 def _do_new_game(self, move_tree=None, analyze_fast=False):
     mode = self.play_analyze_mode
     if (move_tree is not None
             and mode == MODE_PLAY) or (move_tree is None
                                        and mode == MODE_ANALYZE):
         self.play_mode.switch_ui_mode(
         )  # for new game, go to play, for loaded, analyze
     self.board_gui.animating_pv = None
     self.engine.on_new_game()  # clear queries
     self.game = Game(self,
                      self.engine,
                      move_tree=move_tree,
                      analyze_fast=analyze_fast)
     self.controls.graph.initialize_from_game(self.game.root)
     self.update_state(redraw_board=True)
예제 #13
0
 def test_snapback(self, new_game):
     b = Game(MockKaTrain(force_package_config=True), MockEngine(), move_tree=new_game)
     for move in ["C1", "D1", "E1", "C2", "D3", "E4", "F2", "F3", "F4"]:
         b.play(Move.from_gtp(move, player="B"))
     for move in ["D2", "E2", "C3", "D4", "C4"]:
         b.play(Move.from_gtp(move, player="W"))
     assert 5 == len(self.nonempty_chains(b))
     assert 14 == len(b.stones)
     assert 0 == len(b.prisoners)
     b.play(Move.from_gtp("E3", player="W"))
     assert 4 == len(self.nonempty_chains(b))
     assert 14 == len(b.stones)
     assert 1 == len(b.prisoners)
     b.play(Move.from_gtp("D3", player="B"))
     assert 4 == len(self.nonempty_chains(b))
     assert 12 == len(b.stones)
     assert 4 == len(b.prisoners)
예제 #14
0
 def test_capture(self, new_game):
     b = Game(MockKaTrain(force_package_config=True), MockEngine(), move_tree=new_game)
     b.play(Move.from_gtp("A2", player="B"))
     b.play(Move.from_gtp("B1", player="W"))
     b.play(Move.from_gtp("A1", player="W"))
     b.play(Move.from_gtp("C1", player="B"))
     assert 3 == len(self.nonempty_chains(b))
     assert 4 == len(b.stones)
     assert 0 == len(b.prisoners)
     b.play(Move.from_gtp("B2", player="B"))
     assert 2 == len(self.nonempty_chains(b))
     assert 3 == len(b.stones)
     assert 2 == len(b.prisoners)
     b.play(Move.from_gtp("B1", player="B"))
     with pytest.raises(IllegalMoveException, match="Single stone suicide"):
         b.play(Move.from_gtp("A1", player="W"))
     assert 1 == len(self.nonempty_chains(b))
     assert 4 == len(b.stones)
     assert 2 == len(b.prisoners)
예제 #15
0
 def test_capture(self):
     b = Game(MockKaTrain(), MockEngine())
     b.play(Move.from_gtp("A2", player="B"))
     b.play(Move.from_gtp("B1", player="W"))
     b.play(Move.from_gtp("A1", player="W"))
     b.play(Move.from_gtp("C1", player="B"))
     assert 3 == len(self.nonempty_chains(b))
     assert 4 == len(b.stones)
     assert 0 == len(b.prisoners)
     b.play(Move.from_gtp("B2", player="B"))
     assert 2 == len(self.nonempty_chains(b))
     assert 3 == len(b.stones)
     assert 2 == len(b.prisoners)
     b.play(Move.from_gtp("B1", player="B"))
     with pytest.raises(IllegalMoveException) as exc:
         b.play(Move.from_gtp("A1", player="W"))
     assert "Suicide" in str(exc.value)
     assert 1 == len(self.nonempty_chains(b))
     assert 4 == len(b.stones)
     assert 2 == len(b.prisoners)
예제 #16
0
    def test_suicide(self):
        rulesets_to_test = BaseEngine.RULESETS_ABBR + [('{"suicide":true}', ""), ('{"suicide":false}', "")]
        for shortrule, _ in rulesets_to_test:
            new_game = GameNode(properties={"SZ": 19, "RU": shortrule})
            b = Game(MockKaTrain(force_package_config=True), MockEngine(), move_tree=new_game)
            b.play(Move.from_gtp("A18", player="B"))
            b.play(Move.from_gtp("B18", player="B"))
            b.play(Move.from_gtp("C19", player="B"))
            b.play(Move.from_gtp("A19", player="W"))
            assert 4 == len(b.stones)
            assert 0 == len(b.prisoners)

            if shortrule in ["tt", "nz", '{"suicide":true}']:
                b.play(Move.from_gtp("B19", player="W"))
                assert 3 == len(b.stones)
                assert 2 == len(b.prisoners)
            else:
                with pytest.raises(IllegalMoveException, match="Suicide"):
                    b.play(Move.from_gtp("B19", player="W"))
                assert 4 == len(b.stones)
                assert 0 == len(b.prisoners)
예제 #17
0

katrain = KaTrainBase(force_package_config=True, debug_level=0)
combined_settings = {**katrain.config("engine"), **settings}
engine = KataGoEngine(katrain, {**katrain.config("engine"), **settings})
thresholds = katrain.config("trainer/eval_thresholds")

games = []
n = 0
for sgf in os.listdir("sgftest/"):
    if sgf.lower().endswith("sgf"):
        print(sgf)
        with open(os.path.join("sgftest", sgf)) as f:
            move_tree = KaTrainSGF.parse_sgf(f.read())
        games.append(
            Game(katrain, engine, move_tree=move_tree, analyze_fast=False))
    n += 1
    if n >= 30000:  # small test=3
        break

while not engine.is_idle():
    print(
        f"waiting for engine to finish...{engine.queries_remaining()} queries left"
    )
    time.sleep(0.5)
engine.shutdown(finish=None)

reports = []
for game in games:
    sum_stats, _, _ = game_report(game, thresholds=thresholds)
    for bw in "BW":
예제 #18
0
from rank_utils import rank_game


def format_rank(rank):
    if rank <= 0:
        return f"{1-rank:5.1f}d"
    else:
        return f"{rank:5.1f}k"


if __name__ == "__main__":
    kt = KaTrainBase(force_package_config=True)
    e_config = kt.config("engine")
    e_config["max_visits"] = e_config[
        "fast_visits"] = 1  # since it's just policy anyway
    engine = KataGoEngine(kt, e_config)

    for filename in glob.glob("sgf_ogs/*.sgf"):
        game = Game(kt, engine, move_tree=KaTrainSGF.parse_file(filename))
        size = game.board_size
        len_segment = 80

        ranks = rank_game(game, len_segment)
        if not ranks:
            continue
        print("* File name: {0:s}".format(filename))
        for start, end, rank in ranks:
            print(
                f"\tMove quality for moves {start:3d} to {end:3d}\tB: {format_rank(rank['B'])}\tW: {format_rank(rank['W'])}"
            )
예제 #19
0
ENGINE_SETTINGS.update(x_engine_settings)

print(f"starting bot {bot} using server port {port}", file=sys.stderr)
print("setup: ",
      ai_strategy,
      ai_settings,
      engine.override_settings,
      file=sys.stderr)
print(ENGINE_SETTINGS, file=sys.stderr)
print(ai_strategy, ai_settings, file=sys.stderr)

game = Game(Logger(),
            engine,
            game_properties={
                "SZ": 19,
                "PW": "OGS",
                "PB": "OGS",
                "AP": "katrain ogs bot"
            })


def rank_to_string(r):
    r = math.floor(r)
    if r >= 30:
        return f"{r - 30 + 1}d"
    else:
        return f"{30 - r}k"


def format_rank(rank):
    if rank <= 0: