簡體   English   中英

Python連接4檢查win函數

[英]Python connect 4 check win function

我正在編寫一個連接 4 游戲,您可以在其中選擇棋盤的大小。 該游戲適用於大多數棋盤尺寸,但當棋盤比它高時會給我帶來問題。 我不斷得到索引超出范圍的錯誤,我不確定我做錯了什么。 這就是我現在擁有的檢查功能,因為它是唯一給我帶來問題的部分。

def checkOWin(board):

    boardHeight = len(board)
    boardWidth = len(board[0])
    tile = 'O'
    # check horizontal spaces
    for y in range(boardHeight):
        for x in range(boardWidth - 3):
            if board[x][y] == tile and board[x+1][y] == tile and board[x+2][y] == tile and board[x+3][y] == tile:
                return True

    # check vertical spaces
    for x in range(boardWidth):
        for y in range(boardHeight - 3):
            if board[x][y] == tile and board[x][y+1] == tile and board[x][y+2] == tile and board[x][y+3] == tile:
                return True

    # check / diagonal spaces
    for x in range(boardWidth - 3):
        for y in range(3, boardHeight):
            if board[x][y] == tile and board[x+1][y-1] == tile and board[x+2][y-2] == tile and board[x+3][y-3] == tile:
                return True

    # check \ diagonal spaces
    for x in range(boardWidth - 3):
        for y in range(boardHeight - 3):
            if board[x][y] == tile and board[x+1][y+1] == tile and board[x+2][y+2] == tile and board[x+3][y+3] == tile:
                return True

    return False

任何幫助或建議將不勝感激。 提前致謝!

盡管連續嵌套的 for 循環是檢測獲勝的明顯解決方案,但在 Python 等語言中這是一種相當慢的方法。 該問題實際上可以同化為 Connect 4 板的兩個維度上的卷積操作,其卷積核旨在匹配 4 個瓦片的水平、垂直和對角線。

因此,更快的方法是:

  1. 創建用於水平、垂直和對角線獲勝檢測的內核。
 horizontal_kernel = np.array([[ 1, 1, 1, 1]]) vertical_kernel = np.transpose(horizontal_kernel) diag1_kernel = np.eye(4, dtype=np.uint8) diag2_kernel = np.fliplr(diag1_kernel) detection_kernels = [horizontal_kernel, vertical_kernel, diag1_kernel, diag2_kernel]
  1. 從您的棋盤創建一個 2D 數組,其中玩家的所有圖塊都設置為 1,所有空/對手圖塊都設置為 0。

  2. 使用 Scipy 高度優化的 convolve2d 函數通過卷積操作運行電路板。

  3. 在卷積輸出形成的數組中,任何“4”表示棋盤中有4個連接的瓦片。

卷積運算的圖示示例

 from scipy.signal import convolve2d def winning_move(board, player): for kernel in detection_kernels: if (convolve2d(board == player, kernel, mode="valid") == 4).any(): return True return False

這可以極大地加速檢測獲勝條件,這對於在博弈樹上實施類似樹搜索的算法至關重要。 我還發現這個解決方案更加優雅和可讀。

您剛剛混淆了尺寸,您應該這樣設置它們:

def checkOWin(board):
    boardHeight = len(board[0])
    boardWidth = len(board)

因為當你提到 board[x] 時,這是計算板中列表的數量,而當你提到 board[x][y] 時,它只是指板中特定行的長度。

if board[x][y] == tile and board[x+1][y] == tile and board[x+2][y] == tile and board[x+3][y] == tile:

當我翻轉這些值時,函數運行沒有錯誤。

好的,這是 3 年后,我正在學習編程和 Python,並在做我自己的 Connect Four 項目,所以請耐心等待……但我認為問題在於條件。

這是一個示例輸入,應該類似於 OP 使用的內容:

board = [['_','_','_','_','_','_','_'],
         ['_','_','_','_','_','_','_'],
         ['_','_','_','X','_','_','_'],
         ['_','_','_','O','_','_','_'],
         ['_','X','X','O','O','O','O'],
         ['X','X','X','O','O','X','O']]

我已經將條件修改為:

  for x in range(boardWidth):
    for y in range(boardHeight):
      try:
        if board[y][x] == tile and board[y][x+1] == tile and board[y][x+2] == tile and board[y][x+3] == tile:
          return True
      except IndexError:
        next

我們在板列表中存儲了 6 個不同的列表。 訪問板時 y 排在最前面,因為它首先告訴我們需要使用這 6 個列表中的哪個列表,在板列表中向上或向下移動我們。 現在 x 索引將我們移動到我們訪問過的任何 y 列表中。

try 和 except 允許您刪除for x in range(boardWidth - 3)因為如果收到索引錯誤,我們知道我們已經到達游戲板的邊緣並且無法滿足獲勝條件。 所以我們繼續下一個測試點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM