OMOK游戏:如何检测2D棋盘任意方向的五子连珠?
五子棋连珠检测优化方案
核心思路:聚焦落子点周边定向检测
不用全局遍历,只围绕落子的(x,y)点,在横向、纵向、左斜、右上斜四个方向上,分别统计同色棋子的总数量。每个方向分正反两个延伸方向(比如横向是左+右),把两个方向的计数加当前棋子,总数≥5就判定获胜。
具体步骤
- 定义四组检测方向的偏移量,对应四个连珠方向:
- 横向:左
(-1,0)、右(1,0) - 纵向:上
(0,-1)、下(0,1) - 左斜:左上
(-1,-1)、右下(1,1) - 右上斜:右上
(-1,1)、左下(1,-1)
- 横向:左
- 对每组方向:
- 沿第一个偏移方向延伸,统计同色棋子数量,直到碰边界或异色棋子
- 沿第二个偏移方向重复统计
- 总计数 = 两个方向的统计数 + 1(当前落子),若≥5则直接判定胜利
- 四个方向只要有一组满足条件,就返回获胜结果
伪代码实现
def check_win(board, x, y, player): rows = len(board) cols = len(board[0]) if rows else 0 # 四组方向对,每组对应一个连珠方向的正反延伸 direction_pairs = [ [(-1, 0), (1, 0)], # 横向 [(0, -1), (0, 1)], # 纵向 [(-1, -1), (1, 1)], # 左上-右下斜 [(-1, 1), (1, -1)] # 右上-左下斜 ] for pair in direction_pairs: count = 1 # 当前落子本身算1个 for dx, dy in pair: curr_x, curr_y = x + dx, y + dy # 持续延伸检测 while 0 <= curr_x < rows and 0 <= curr_y < cols: if board[curr_x][curr_y] == player: count += 1 curr_x += dx curr_y += dy else: break if count >= 5: return True return False
解决中间连珠漏判的关键
之前的代码只检测单方向(比如只向右或只向左),导致落子在连珠中间时,无法统计到两侧的棋子。现在通过正反方向的累计计数,不管落子在连珠的哪个位置(边缘、中间),都能把所有同色连子数统计完整。
备选:全局检测方案
如果周边检测有实现障碍,全局遍历的思路是逐个遍历棋盘上的棋子,对每个棋子执行上述方向检测。但要注意避免重复检测(比如已经检测过(x,y)的横向,就不用再检测(x+1,y)的横向),适合小棋盘场景,效率比周边检测低。
内容的提问来源于stack exchange,提问作者Pipopi
相关产品推荐
相关产品推荐

