Source code for miniosl.player

"""player"""

import miniosl
import logging
import json
import re


class MyRandomPlayer(miniosl.SingleCPUPlayer):
    """sample of implementing virtual methods in python
    """
    def __init__(self):
        super().__init__()

    def think(self, usi: str):
        record = miniosl.usi_record(usi)
        state = record.replay(-1)
        moves = state.genmove()
        move = moves[0]
        return move

    def name(self):
        return "py-random"


[docs]class UsiPlayer(miniosl.SingleCPUPlayer): """bridge between usi engine and :py:class:`CPUPlayer` for self-play with :py:class:`GameArray`. """ def __init__(self, engine: miniosl.UsiProcess): super().__init__() self.engine = engine
[docs] def think(self, usi: str): record = miniosl.usi_record(usi) state = record.replay(-1) go = 'byoyomi 1000' ret = self.engine.search(usi, go) move = ret['move'] return state.to_move(move)
[docs] def name(self): id = self.engine.name return id.replace(' ', '_') if id else "usi"
def make_usi_player(cfg_path: str) -> UsiPlayer: with open(cfg_path, 'r') as f: cfg = json.load(f) if 'type' not in cfg or cfg['type'] != 'usi': raise ValueError(f'unsupported cfg {cfg_path}') path_and_args = cfg['path_and_args'] setoptions = cfg['setoptions'] cwd = cfg['cwd'] if 'cwd' in cfg else None engine = miniosl.UsiProcess(path_and_args, setoptions, cwd) if not hasattr(make_usi_player, 'players'): make_usi_player.players = [] pl = UsiPlayer(engine) make_usi_player.players.append(pl) return miniosl.CPUPlayer(pl, False) def clear_usi_players(): if hasattr(make_usi_player, 'players'): make_usi_player.players = [] def make_player( name: str, *, noise_scale=1.0, softalpha=0.00783, depth_weight=0.5, book_path='') -> miniosl.PlayerArray: """factory method""" gumbel_pattern = r'^gumbel([1-9][0-9]*)$' gumbel_d2_pattern = r'^gumbel([1-9][0-9]*)-([1-9][0-9]*)$' soft_pattern = r'^soft([1-9][0-9]*)$' soft_d2_pattern = r'^soft([1-9][0-9]*)-([1-9][0-9]*)$' td_pattern = r'^gumbeltd([1-9][0-9]*)$' ave_pattern = r'^gumbelave([1-9][0-9]*)$' max_pattern = r'^gumbelmax([1-9][0-9]*)$' config = miniosl.GumbelPlayerConfig() config.noise_scale = noise_scale config.depth_weight = depth_weight if book_path: config.book_path = book_path config.book_weight_p = 0 # todo if match := re.match(gumbel_d2_pattern, name): config.root_width = int(match.group(1)) config.second_width = int(match.group(2)) if config.root_width < config.second_width: raise RuntimeError( f'width mismatch {config.root_width} < {config.second_width}' ) return miniosl.FlatGumbelPlayer(config) elif match := re.match(gumbel_pattern, name): config.root_width = int(match.group(1)) return miniosl.FlatGumbelPlayer(config) elif match := re.match(td_pattern, name): config.root_width = int(match.group(1)) config.value_mix = 1 return miniosl.FlatGumbelPlayer(config) elif match := re.match(ave_pattern, name): config.root_width = int(match.group(1)) config.value_mix = 2 return miniosl.FlatGumbelPlayer(config) elif match := re.match(max_pattern, name): config.root_width = int(match.group(1)) config.value_mix = 3 return miniosl.FlatGumbelPlayer(config) elif match := re.match(soft_d2_pattern, name): config.root_width = int(match.group(1)) config.second_width = int(match.group(2)) if config.root_width < config.second_width: raise RuntimeError( f'width mismatch {config.root_width} < {config.second_width}' ) config.softalpha = softalpha return miniosl.FlatGumbelPlayer(config) elif match := re.match(soft_pattern, name): config.root_width = int(match.group(1)) config.softalpha = softalpha return miniosl.FlatGumbelPlayer(config) elif name == "greedy-policy": return miniosl.PolicyPlayer(True) elif name == "random": """ ... warning:: this depends on std::shared_ptr is used as holder for :py:class:`RandomPlayer`, otherwise results in dangling pointer. """ return miniosl.CPUPlayer(miniosl.RandomPlayer(), False) elif name == "myrandom": """save before return to keep its lifetime """ make_player.random = MyRandomPlayer() return miniosl.CPUPlayer(make_player.random, False) elif name.endswith('.json'): return make_usi_player(name) else: if name != "policy": logging.warn(f"unknown player name {name}") return miniosl.PolicyPlayer()