2012-08-08 69 views
1

嗨!我正在製作一個象棋引擎,並且在make/unmake方法中遇到了一些問題。國際象棋編程make and unmake move

我有一個Piece類,它包含了棋子類型(pawn,queen等等)和棋子的位置,以及一個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 !? 
+5

你應該保留一個移動列表。這樣,你可以將最後一步移出堆棧,做相反的事情,而你是金。你可能需要一個'reverseMove'方法和一個'uncapturePiece'方法。 – 2012-08-08 21:09:01

+3

閱讀[紀念圖案](http://en.wikipedia.org/wiki/Memento_pattern) – 2012-08-08 21:10:05

+0

@FredLarson:良好的聯繫。我以前不知道這一點。 – 2012-08-08 21:12:25

回答

2

基於我的評論和弗雷德·拉森貼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)形式的元組。