diff --git a/board/go_board.py b/board/go_board.py index bfea2b7..a1cbe82 100644 --- a/board/go_board.py +++ b/board/go_board.py @@ -1,6 +1,6 @@ """碁盤のデータ定義と操作処理。 """ -from typing import List, NoReturn +from typing import List, Tuple, NoReturn from collections import deque import numpy as np @@ -481,6 +481,14 @@ def get_to_move(self) -> Stone: last_move_color, _, _ = self.record.get(self.moves - 1) return Stone.get_opponent_color(last_move_color) + def get_move_history(self) -> List[Tuple[Stone, int, np.array]]: + """着手の履歴を取得する。 + + Returns: + [(Stone, int, np.array), ...]: (着手の色、座標、ハッシュ値) のリスト。 + """ + return [self.record.get(m) for m in range(1, self.moves)] + def count_score(self) -> int: # pylint: disable=R0912 """領地を簡易的にカウントする。 diff --git a/gtp/client.py b/gtp/client.py index e7e2f42..a595621 100644 --- a/gtp/client.py +++ b/gtp/client.py @@ -164,6 +164,19 @@ def _play(self, color: str, pos: str) -> NoReturn: respond_success("") + def _undo(self) -> NoReturn: + """undoコマンドを処理する。 + """ + # 一旦クリアして初手から直前手まで打ち直す非効率実装 + history = self.board.get_move_history() + if not history: + respond_failure("cannot undo") + return + self._clear_board() + for (color, pos, _) in history[:-1]: + self.board.put_stone(pos, color) + respond_success("") + def _genmove(self, color: str) -> NoReturn: """genmoveコマンドを処理する。 入力された手番で思考し、着手を生成する。 @@ -432,6 +445,8 @@ def run(self) -> NoReturn: # pylint: disable=R0912,R0915 self._komi(command_list[1]) elif input_gtp_command == "play": self._play(command_list[1], command_list[2]) + elif input_gtp_command == "undo": + self._undo() elif input_gtp_command == "genmove": self._genmove(command_list[1]) elif input_gtp_command == "boardsize":