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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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)
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)
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)
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)
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)
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)
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":
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'])}" )
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: