【问题标题】:Chess programming make and unmake move国际象棋编程成败
【发布时间】:2012-09-24 13:46:07
【问题描述】:

嗨!我正在制作一个国际象棋引擎,但 make/unmake 方法有一些问题。

我有一个 Piece 类来保存棋子的类型(棋子、皇后等)和位置,还有一个 Move 类来保存目标方格、移动的棋子和捕获的棋子。

问题是,当我调用 makeMove 方法时,它会将棋子的位置更改为 Piece 对象内的目标正方形。但是现在,我不能用 Move 对象调用 unmakeMove,因为现在我没有关于移动来自哪里的信息,因为我刚刚改变了棋子的位置。您将如何解决这个问题?

非常感谢!

class Board:
# Previous methods omitted. 

    def makeMove(self, move, player):
        """ Makes a move on the board and changes Piece object. Returns None. """
        self.moved_piece = move.getPiece()
        self.captured_piece = move.getCapturedPiece(self)

        if self.captured_piece:  # Remove captured piece from player's piece dict. 
            player.removePiece(self.captured_piece)

        self.setPiece(move.getTargetSquare(), self.moved_piece)  # Set moved piece on target square.
        self.setPiece(self.moved_piece.getPosition(), EMPTY)  # Make the origin square empty.
        self.moved_piece.changePosition(move.getTargetSquare())  # Change piece object's position.

    def unmakeMove(self, move, player):
        """ Unmakes a move. Returns None. """
        self.moved_piece = move.getPiece()
        self.captured_piece = move.getCapturedPiece(self)

        self.setPiece(self.moved_piece.getPosition(), captured_piece)  # Set captured piece or empty square to target square.
        # Set piece to original square. HOW !?

【问题讨论】:

  • 你应该保留一个移动列表。这样,您只需将最后一步从堆栈中弹出,然后执行相反的操作,您就可以了。您可能需要一个reverseMove 方法和一个uncapturePiece 方法。
  • @FredLarson:很好的链接。我以前不知道这一点。
  • 如果您保留所有移动的列表,您还可以从列表中删除最后一个移动,然后将移动应用到起始位置的棋盘。这可以避免需要任何单独的撤消逻辑。

标签: python chess


【解决方案1】:

根据我的评论和 Fred Larson 发布的 link on the Memento pattern,以下是您可能想做的示例实现:

class Engine(object):
    def __init__(self):
        self.board = Board()
        self.move_list = []

    def make_move(self, from, to):
        #board.makeMove returns a "memento object".
        self.move_list.append(board.makeMove(from, to))
        ...

    def undo_move(self):
        board.undo(self.move_list.pop())
    ...
    ...

假设你有一个这种结构的移动对象:

class Move(object):
    def __init__(self, from_coords, to_coords, capture=None):
        self.from = from_coords
        self.to = to_coords
        self.capture = capture

你是Board 对象将实现以下方法:

class Board(object):
    ...
    def make_move(self, from_coords, to_coords):
        #move logic here
        return Move(from_coords, to_coords, capturedPiece)

    def undo_move(self, move_object):
        self.make_move(move_object.to_coords, move_object.from_coords)
        self.uncapture(move_object.capture, move_object.to_coords)

显然,上面的代码只是概念性的。实际实现将取决于其余代码的结构。

注意:我为Move 对象使用了一个类,因为属性访问是明确的并且易于理解。实际上,像这样基本的对象可能只是 (from, to, capturedpiece) 形式的元组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2022-06-17
    • 1970-01-01
    • 2023-03-11
    • 2014-03-02
    • 2013-05-24
    • 1970-01-01
    相关资源
    最近更新 更多