def go(self): """Tell the engine to decide what move it would play. This is used when the engine is playing in a game. With the "go" command the computer is limited by both the maximum search depth and the time remaining in the game. Required: The engine responds with "=== {move}" where move is e.g. "F5" Best: The engine responds with "=== {move:String}/{eval:float}/{time:float}". Eval may be omitted if the move is forced. The engine also sends back thinking output as in the "hint" command. Important: The engine does not update the board with this move, instead it waits for a "move" command from NBoard. This is because the user may have modified the board while the engine was thinking. Note: To make it easier for the engine author, The NBoard gui sets the engine's status to "" when it receives the response. The engine can override this behaviour by sending a "status" command immediately after the response. """ self.tell_status("thinking...") gr = self.engine.go() move = convert_action_to_move(gr.action) self.engine.reply(f"=== {move}/{gr.eval * 10}/{gr.time}") self.tell_status("waiting")
def move(self, env, action): """ :param ReversiEnv env: :param ActionWithEvaluation action: :return: """ if action.action is None: return # resigned if len(self.moves) % 2 == 0: if env.next_player == Player.white: self.moves.append(convert_action_to_move(None)) else: if env.next_player == Player.black: self.moves.append(convert_action_to_move(None)) move = f"{convert_action_to_move(action.action)}/{action.q*10}/{action.n}" self.moves.append(move)
def report_hint(self, hint_list): for hint in reversed( hint_list): # there is a rule that the last is best? move = convert_action_to_move(hint.action) self.engine.reply( f"search {move} {hint.value} 0 {int(hint.visit)}")
def test_convert_action_to_move(): eq_("A1", convert_action_to_move(0)) eq_("H8", convert_action_to_move(63)) eq_("F5", convert_action_to_move(44)) eq_("PA", convert_action_to_move(None))