首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言五子棋勝負判定演算法:掃描四方向 O(1) 高效實作

     編輯:關於C語言

問題背景

五子棋盤面 15×15 或 19×19,每落一子需即時判斷是否形成五連珠。暴力掃描全盤 O(N²) 過慢,**僅掃描最新落子周圍四方向** 可達 O(1) (常數時間,與盤面大小無關)。

核心演算法

  1. 新落子座標 (x, y),顏色 color (1=黑, 2=白)。
  2. 四方向向量:(1,0) 橫、(0,1) 直、(1,1) 右斜、(1,-1) 左斜。
  3. 對每方向,以新子為中心,向正負兩側延伸計數同色子總數。
  4. 任一方向總數 ≥ 5 即獲勝。

邊界處理技巧:擴展棋盤法

宣告 BOARD_SIZE + 8 陣列 (四周各擴 4 格),落子座標偏移 (4,4),掃描時**無需邊界判斷**,超出實際盤面區域預設為 0 (無子),自然終止計數。

完整 C 實作 (含擴展棋盤)


#include 
#include 

#define N 15
#define EXT 4
#define SZ (N + 2*EXT)     // 15+8=23
#define EMPTY 0
#define BLACK 1
#define WHITE 2

int board[SZ][SZ] = {0};   // 全域零初始化,擴展區自動為 0

/* 方向向量:右、下、右下、右上 */
const int dx[4] = {1, 0, 1,  1};
const int dy[4] = {0, 1, 1, -1};

bool check_win(int x, int y, int color) {
    for (int dir = 0; dir < 4; ++dir) {
        int count = 1;  // 含新落子自己
        /* 正向延伸 */
        for (int step = 1; step < 5; ++step) {
            int nx = x + dx[dir] * step;
            int ny = y + dy[dir] * step;
            if (board[nx][ny] == color) ++count;
            else break;
        }
        /* 反向延伸 */
        for (int step = 1; step < 5; ++step) {
            int nx = x - dx[dir] * step;
            int ny = y - dy[dir] * step;
            if (board[nx][ny] == color) ++count;
            else break;
        }
        if (count >= 5) return true;
    }
    return false;
}

int main(void) {
    /* 簡易測試:黑棋在 (7,7) 形成橫向五連 */
    int moves[][2] = {{7,7},{7,8},{7,9},{7,10},{7,11}};
    for (int i = 0; i < 5; ++i) {
        int x = moves[i][0] + EXT, y = moves[i][1] + EXT;
        board[x][y] = BLACK;
        if (check_win(x, y, BLACK)) {
            printf("第 %d 手獲勝!\n", i+1);
            break;
        }
    }
    return 0;
}

關鍵細節解析

技巧作用
擴展棋盤 + 偏移消除邊界 `if`,簡化邏輯、提升分支預測率
方向向量表驅動四方向統一迴圈,無重複代碼,易維護
雙向延伸計數以新子為中心,正負各延伸 4 格,覆蓋所有含新子的五連組合
提早結束任一方向達 5 即返回,避免多餘計算

效能分析

  • 時間複雜度:O(1) — 固定 4 方向 × 最多 8 步 = 32 次陣列存取。
  • 空間複雜度:O(N²) 棋盤陣列,擴展區常數倍開銷。
  • 分支預測友善:迴圈次數固定,無資料相關分支。

進階優化:位板

將每列/行/對角線編碼為 64-bit 整數,落子相當於 `board |= (1ULL << pos)`,判斷五連珠轉為位運算 (board & (board >> 1) & (board >> 2) & (board >> 3) & (board >> 4)) != 0,極致高效,適合 AI 引擎。

常見錯誤

錯誤修正
只掃描正向需雙向延伸,否則漏判新子在五連中間的情況
未處理邊界導致越界用擴展棋盤或加 `if (nx<0||nx>=N||ny<0||ny>=N) break;`
重複掃描已檢查方向四方向向量正交,無重複
長連珠 (六連、七連) 判定邏輯錯誤規則通常「五子以上即勝」,`count >= 5` 正確涵蓋

結語

五子棋勝負判定的核心是**局部增量檢查**。善用擴展棋盤消除邊界、方向向量表驅動、雙向延伸計數,可寫出簡潔、高效、無 Bug 的判定邏輯。此模式廣泛適用於連連看、圍棋氣計算、消消樂匹配等格盤遊戲。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved