[英]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 個瓦片的水平、垂直和對角線。
因此,更快的方法是:
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]
從您的棋盤創建一個 2D 數組,其中玩家的所有圖塊都設置為 1,所有空/對手圖塊都設置為 0。
使用 Scipy 高度優化的 convolve2d 函數通過卷積操作運行電路板。
在卷積輸出形成的數組中,任何“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.