2016-03-01 66 views
0

我正在製作一款國際象棋遊戲,並具有計算所有法律動作的類函數。它通過將棋子作爲參數並獲得所有可能的攻擊動作來實現。然後,通過這些舉動循環和他們的臨時移動一塊,看看是否能移動把自己檢查,如果是的話那麼它是不是一個合法的移動:無法從python通過對象引用傳遞

def calculate_legal_moves(self, piece): 
    """Get all the legal moves of a piece and returns them""" 
    legal_moves = [] 
    if not isinstance(piece, Pawn): 
     possible_legal_moves = self.get_attacking_moves(piece) 
     for move in possible_legal_moves: 
      if isinstance(self.board[move[0]][move[1]], Piece): 
       if not piece.colour == self.board[move[0]][move[1]].colour: 
        possible_board = self.preliminary_move_piece(self.board, piece.position, move) 
        if not self.is_in_check(piece.colour, possible_board): 
         legal_moves.append(move) 
      else: 
       possible_board = self.preliminary_move_piece(self.board, piece.position, move) 
       if not self.is_in_check(piece.colour, possible_board): 
        legal_moves.append(move) 
    else: 
     if piece.colour == "White": 
      legal_moves.append([piece.position[0]-1, piece.position[1]]) 
      if piece.position[0] == 6: 
       legal_moves.append([piece.position[0]-2, piece.position[1]]) 
     else: 
      legal_moves.append([piece.position[0]+1, piece.position[1]]) 
      if piece.position[0] == 1: 
       legal_moves.append([piece.position[0]+2, piece.position[1]]) 
    return legal_moves 

def preliminary_move_piece(self, chess_board, old_coords, new_coords): 
    chess_board[new_coords[0]][new_coords[1]] = self.board[old_coords[0]][old_coords[1]] 
    chess_board[old_coords[0]][old_coords[1]] = 0 
    if isinstance(chess_board[new_coords[0]][new_coords[1]], Piece): 
     chess_board[new_coords[0]][new_coords[1]].position = [new_coords[0], new_coords[1]] 
    return chess_board 

的問題是,我通過在(二維數組),並暫時移動一個片斷,看看是否讓他進入檢查狀態,但它似乎是通過引用傳遞實例變量,所以實際上是永久性地改變片斷位置,因此我的片斷會自動移動到當我點擊它時最後一次可能的合法舉動。有沒有辦法,我可以離開我的實例變量(self.board)觸摸時,我使用了preliminary_move_piece函數

+0

列表在python中是可變的。可變對象的參數始終通過引用傳遞。是否可以製作一個chess_board的副本並將副本傳遞給preliminary_move_piece? –

+0

這就是我試圖做的,但無濟於事(original_board = self.board)。但是,當我回家時,我會盡可能嘗試所有這些建議 – user2867973

+0

original_board = self.board使original_board成爲self.board的參考。我的意思是創建一個新列表並將self.board的每個元素複製到它。 original_board = [[x for x in y] for y in self.board] –

回答

2

由於列表在python中是可變的,它通過引用傳遞給函數。要弄清楚,你可以:
一)將其轉換成元組:tuple(your_list)因爲元組是不可變的和值
b)複製列表過去了,在different ways之一,例如: copied_list = your_list[:] 的非常類似的問題有關實際上相同問題: Python passing list as argument

+0

我不認爲我可以嘗試一個元組,但是如果可以的話,我會稍後再看看,但是我幾乎不知道爲什麼b)不工作,因爲我現在正在嘗試它,它只是仍在複製。它是否有所不同,它是一個類變量和函數,這就是爲什麼它自動複製,因爲如果我必須轉換爲元組,那麼我不得不重構很多cocde – user2867973

+1

@ user2867973在這種情況下,只需在函數內複製傳入列表(請參閱答案中的鏈接以檢查如何執行此操作)。例如。你可以使用我提到的例子或者'import copy'來製作'copy.copy(incoming_list)' –

+1

謝謝,我只是想爲將來的讀者寫一份說明,對我來說只有copy.deepcopy()爲我工作,我不知道爲什麼,也許有人可以評論這是爲什麼。 – user2867973