HarmonyOS 小游戏《对战五子棋》开发第8篇 - GomokuEngine核心引擎设计(三):五子连珠判定算法

从一个点出发,向四个方向延伸------五子棋胜负判定的核心算法

截图如下:

checkWin算法详解

typescript 复制代码
checkWin(row: number, col: number, player: number): boolean {
  const directions: number[][] = [
    [0, 1],   // 水平 →
    [1, 0],   // 垂直 ↓
    [1, 1],   // 主对角线 ↘
    [1, -1]   // 副对角线 ↙
  ];

  for (const dir of directions) {
    let count = 1;  // 包含当前落子
    
    // 正方向计数
    for (let i = 1; i < 5; i++) {
      const r = row + dir[0] * i;
      const c = col + dir[1] * i;
      if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) break;
      if (this.board[r][c] === player) count++;
      else break;
    }
    
    // 反方向计数
    for (let i = 1; i < 5; i++) {
      const r = row - dir[0] * i;
      const c = col - dir[1] * i;
      if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) break;
      if (this.board[r][c] === player) count++;
      else break;
    }
    
    if (count >= 5) return true;
  }
  return false;
}

算法思路

五子棋的获胜条件是:同一颜色的棋子在水平、垂直或对角线方向上连续排列5个或以上。

判定算法的核心思想:

  1. 以最新落子位置为中心
  2. 沿4个方向(水平、垂直、两条对角线)分别检查
  3. 每个方向向正反两个方向延伸,统计连续同色棋子数
  4. 如果任一方向的总数≥5,则获胜

四个方向的向量

复制代码
方向1: [0, 1]  →  水平方向(行不变,列递增)
方向2: [1, 0]  ↓  垂直方向(行递增,列不变)
方向3: [1, 1]  ↘  主对角线(行列同时递增)
方向4: [1, -1] ↙  副对角线(行递增,列递减)

用向量表示方向的好处是统一的计算公式:

  • 正方向:r = row + dir[0] * i,c = col + dir[1] * i
  • 反方向:r = row - dir[0] * i,c = col - dir[1] * i

图解计数过程

假设黑棋在(7,7)落子,向左有2个黑棋,向右有2个黑棋:

复制代码
水平方向 [0,1]:
←反方向               正方向→
  ○ ○ ● ←(7,7)→ ● ○ ○
        count=1
  ←延伸           延伸→
  count=3         count=5  → 获胜!

为什么只需要检查4个方向

五子棋有8个方向(上下左右+4个对角线),但每对相反方向是同一条线。检查4个方向的正反两侧就覆盖了所有8个方向:

复制代码
      ↖ ↑ ↗
       \ | /
    ← --- ● --- →
       / | \
      ↙ ↓ ↘

4个方向 × 2侧 = 8个方向

为什么只需检查最近一手

这是算法的关键优化------只检查最新落子位置的胜负。

原因:之前的状态没有产生五连(否则游戏已结束),新落子只可能在其所在的4条线上形成五连。因此不需要全盘扫描。

时间复杂度:O(4 × 4 × 2) = O(32) ≈ O(1),常数时间!

边界处理

typescript 复制代码
if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) break;

每次延伸都要检查是否越界。这是防止数组越界的标准做法。

AIPlayer中的checkWin

AIPlayer中有一个独立的checkWin实现(因为AI不持有GomokuEngine实例):

typescript 复制代码
private checkWin(board: number[][], row: number, col: number, player: number): boolean {
  const directions: number[][] = [[0, 1], [1, 0], [1, 1], [1, -1]];
  for (const dir of directions) {
    let count = 1;
    for (let i = 1; i < 5; i++) {
      const r = row + dir[0] * i;
      const c = col + dir[1] * i;
      if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) break;
      if (board[r][c] === player) count++;
      else break;
    }
    for (let i = 1; i < 5; i++) {
      const r = row - dir[0] * i;
      const c = col - dir[1] * i;
      if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) break;
      if (board[r][c] === player) count++;
      else break;
    }
    if (count >= 5) return true;
  }
  return false;
}

逻辑完全一致,区别在于接收board参数而非使用this.board。

总结

五子连珠判定算法是游戏引擎中最精巧的部分之一:

  1. 以点带面:只检查最新落子,O(1)复杂度
  2. 向量方向:4个方向向量统一处理
  3. 正反延伸:每个方向检查正反两侧
  4. 边界安全:每次延伸都验证越界

这个算法是棋类游戏胜负判定的经典范式,可以推广到四子棋、六子棋等变体。

相关推荐
学代码的CJY10 分钟前
从代码出发理解时间复杂度与空间复杂度
数据结构·算法
白帽攻防录31 分钟前
SRC 挖洞:WSO2 JWT 算法混淆绕过深度复盘,CVE-2026-5430 不支持的算法怎么变成管理员
网络·算法·安全·网络安全·jwt
李游Leo40 分钟前
《HarmonyOS 7 ArkGraphics 3D 空间设计开发实战》03:glTF模型加载、实例复用与资源生命周期【鸿蒙心迹】
3d·harmonyos
小O的算法实验室1 小时前
IEEE TEVC,基于精确与DQN群智能调度方法用于多目标异构USV
算法
李游Leo1 小时前
HarmonyOS 7 + ArkTS-HUKS:精准碰一碰载荷的签名校验与重放窗口【鸿蒙心迹】
华为·harmonyos
花花_12 小时前
HarmonyOS 7 状态手记 01|页面状态别乱放
华为·harmonyos
可乐ea2 小时前
AI Agent 工具调用准确性评测:选择错误与参数错误分开测
大数据·人工智能·算法·大模型·工具调用·ai智能体·agent评测
上位机妹子2 小时前
C 语言 数组删除指定元素(快慢指针法)
c语言·数据结构·算法
心中有你02142 小时前
【路径规划】A*寻路算法最通俗易懂讲解(C语言完整实现+详细注释)
c语言·开发语言·算法
李游Leo2 小时前
HarmonyOS 7 + Hvigor-Localization Kit:多语言资源占位符签名与回退链路预检【鸿蒙心迹】
harmonyos