def _option(self, arg): current_parameter = None name = [] type = [] default = [] min = None max = None current_var = None var = [] for token in arg.split(" "): if token == "name" and not name: current_parameter = "name" elif token == "type" and not type: current_parameter = "type" elif token == "default" and not default: current_parameter = "default" elif token == "min" and min is None: current_parameter = "min" elif token == "max" and max is None: current_parameter = "max" elif token == "var": current_parameter = "var" if current_var is not None: var.append(" ".join(current_var)) current_var = [] elif current_parameter == "name": name.append(token) elif current_parameter == "type": type.append(token) elif current_parameter == "default": default.append(token) elif current_parameter == "var": current_var.append(token) elif current_parameter == "min": try: min = int(token) except ValueError: LOGGER.exception("exception parsing option min") elif current_parameter == "max": try: max = int(token) except ValueError: LOGGER.exception("exception parsing option max") if current_var is not None: var.append(" ".join(current_var)) type = " ".join(type) default = " ".join(default) if type == "check": if default == "true": default = True elif default == "false": default = False else: default = None elif type == "spin": try: default = int(default) except ValueError: LOGGER.exception("exception parsing option spin default") default = None option = Option(" ".join(name), type, default, min, max, var) self.options[option.name] = option
def _registration(self, arg): LOGGER.error("engine registration not supported")
def _info(self, arg): if not self.info_handlers: return # Notify info handlers of start. for info_handler in self.info_handlers: info_handler.pre_info(arg) # Initialize parser state. board = None pv = None score_kind = None score_cp = None score_mate = None score_lowerbound = False score_upperbound = False refutation_move = None refuted_by = [] currline_cpunr = None currline_moves = [] string = [] def end_of_parameter(): # Parameters with variable length can only be handled when the # next parameter starts or at the end of the line. if pv is not None: for info_handler in self.info_handlers: info_handler.pv(pv) if score_cp is not None or score_mate is not None: for info_handler in self.info_handlers: info_handler.score(score_cp, score_mate, score_lowerbound, score_upperbound) if refutation_move is not None: if refuted_by: for info_handler in self.info_handlers: info_handler.refutation(refutation_move, refuted_by) else: for info_handler in self.info_handlers: info_handler.refutation(refutation_move, None) if currline_cpunr is not None: for info_handler in self.info_handlers: info_handler.currline(currline_cpunr, currline_moves) def handle_integer_token(token, fn): try: intval = int(token) except ValueError: LOGGER.exception( "exception parsing integer token from info: %r", arg) return for info_handler in self.info_handlers: fn(info_handler, intval) def handle_float_token(token, fn): try: floatval = float(token) except ValueError: LOGGER.exception("exception parsing float token from info: %r", arg) for info_handler in self.info_handlers: fn(info_handler, floatval) def handle_move_token(token, fn): try: move = chess.Move.from_uci(token) except ValueError: LOGGER.exception("exception parsing move token from info: %r", arg) return for info_handler in self.info_handlers: fn(info_handler, move) # Find multipv parameter first. if "multipv" in arg: current_parameter = None for token in arg.split(" "): if token == "string": break if current_parameter == "multipv": handle_integer_token( token, lambda handler, val: handler.multipv(val)) current_parameter = token # Parse all other parameters. current_parameter = None for token in arg.split(" "): if current_parameter == "string": string.append(token) elif not token: # Ignore extra spaces. Those can not be directly discarded, # because they may occur in the string parameter. pass elif token in [ "depth", "seldepth", "time", "nodes", "pv", "multipv", "score", "currmove", "currmovenumber", "hashfull", "nps", "tbhits", "cpuload", "refutation", "currline", "ebf", "string" ]: end_of_parameter() current_parameter = token pv = None score_kind = None score_mate = None score_cp = None score_lowerbound = False score_upperbound = False refutation_move = None refuted_by = [] currline_cpunr = None currline_moves = [] if current_parameter == "pv": pv = [] if current_parameter in ["refutation", "pv", "currline"]: board = self.board.copy(stack=False) elif current_parameter == "depth": handle_integer_token(token, lambda handler, val: handler.depth(val)) elif current_parameter == "seldepth": handle_integer_token( token, lambda handler, val: handler.seldepth(val)) elif current_parameter == "time": handle_integer_token(token, lambda handler, val: handler.time(val)) elif current_parameter == "nodes": handle_integer_token(token, lambda handler, val: handler.nodes(val)) elif current_parameter == "pv": try: pv.append(board.push_uci(token)) except ValueError: LOGGER.exception( "exception parsing pv from info: %r, position at root: %s", arg, self.board.fen()) elif current_parameter == "multipv": # Ignore multipv. It was already parsed before anything else. pass elif current_parameter == "score": if token in ["cp", "mate"]: score_kind = token elif token == "lowerbound": score_lowerbound = True elif token == "upperbound": score_upperbound = True elif score_kind == "cp": try: score_cp = int(token) except ValueError: LOGGER.exception( "exception parsing score cp value from info: %r", arg) elif score_kind == "mate": try: score_mate = int(token) except ValueError: LOGGER.exception( "exception parsing score mate value from info: %r", arg) elif current_parameter == "currmove": handle_move_token(token, lambda handler, val: handler.currmove(val)) elif current_parameter == "currmovenumber": handle_integer_token( token, lambda handler, val: handler.currmovenumber(val)) elif current_parameter == "hashfull": handle_integer_token( token, lambda handler, val: handler.hashfull(val)) elif current_parameter == "nps": handle_integer_token(token, lambda handler, val: handler.nps(val)) elif current_parameter == "tbhits": handle_integer_token(token, lambda handler, val: handler.tbhits(val)) elif current_parameter == "cpuload": handle_integer_token(token, lambda handler, val: handler.cpuload(val)) elif current_parameter == "refutation": try: if refutation_move is None: refutation_move = board.push_uci(token) else: refuted_by.append(board.push_uci(token)) except ValueError: LOGGER.exception( "exception parsing refutation from info: %r, position at root: %s", arg, self.board.fen()) elif current_parameter == "currline": try: if currline_cpunr is None: currline_cpunr = int(token) else: currline_moves.append(board.push_uci(token)) except ValueError: LOGGER.exception( "exception parsing currline from info: %r, position at root: %s", arg, self.board.fen()) elif current_parameter == "ebf": handle_float_token(token, lambda handler, val: handler.ebf(val)) end_of_parameter() if string: for info_handler in self.info_handlers: info_handler.string(" ".join(string)) # Notify info handlers of end. for info_handler in self.info_handlers: info_handler.post_info()
def _copyprotection(self, arg): LOGGER.error("engine copyprotection not supported")
def send_line(self, line): LOGGER.debug("%s << %s", self.process, line) return self.process.send_line(line)
def get(self, key): try: return self._features[key] except KeyError: LOGGER.exception("exception looking up feature")
def set_option(self, key, value): try: self._features["option"][key] = value except KeyError: LOGGER.exception("exception looking up option")
def get_option(self, key): try: return self._features["option"][key] except KeyError: LOGGER.exception("exception looking up option")