中國象棋計算機博弈發展史研究報告
系統梳理中國象棋計算機博弈從 1980 年代到 2026 年的技術演進、代表引擎與社群生態。 索引C:版本索引 → 第五章 置換表與哈希技術
索引C:版本索引
將族 - 1989年ICGA奪冠, 1992年DOS發佈 棋隱 - 1997年發佈 象棋奇兵 - 2005年ICGA奪冠 棋天大聖 - 2006年ICGA奪冠, 2006年CCMC奪冠 象棋旋風 - 2005年首版, 2008年CCMC奪冠 倚天象棋 - 2008年ICGA奪冠 象棋名手 - 2009年CCMC奪冠, 2010-2014年統治時期 佳佳象棋 - 2009年發佈 GGzero - 佳佳象棋的RL分支 小蟲象棋 - 2013年ICGA奪冠 皮卡魚 - 2022年GitHub發佈 皮卡魚2022-10-22版 - 殘局修復 皮卡魚2022-12-26版 - 60步規則/WDL引入 皮卡魚2023版 - 多項小版本優化 皮卡魚2024-08-31版 - ATT++架構 皮卡魚2025-06-23版 - AVX512優化 Orange引擎 - 2024年發佈
文檔結束
本報告將持續更新。最新版本可在以下地址獲取:[待定]
報告日期:2026年7月
第七卷 中國象棋引擎核心技術深度解析
第一章 局面表示技術的演進
1.1 數組表示法
最早的中國象棋引擎(將族、棋隱、早期ElephantEye等)使用10x9的二維數組來表示棋盤。每個數組元素存儲一個整數,表示該位置上的棋子類型和顏色。
典型的數組表示編碼方式:
- 0:空位
- 正數(1-7):紅方棋子(帥、士、象、馬、車、炮、兵)
- 負數(-1到-7):黑方棋子(將、士、象、馬、車、炮、卒)
數組表示的優點:直觀易懂、實現簡單、調試方便。缺點:效率低、緩存不友好、並行性能差。
1.2 位棋盤(Bitboard)表示法
現代引擎(如皮卡魚)使用位棋盤(Bitboard)表示法。位棋盤使用多個64位整數來表示棋盤狀態。每個位(bit)表示棋盤上的一個交叉點。
中國象棋棋盤有90個交叉點,14種棋子(7種紅方+7種黑方)各使用一個64位位棋盤。位棋盤的第0位表示棋盤的左上角,第9位表示左下角,第81位表示右上角。
位棋盤的優勢:
- 着法生成速度快——通過預計算和位運算
- 內存訪問高效——數據結構緊湊,緩存友好
- 並行性好——位運算天然支持並行執行
- 增量更新容易——通過AND/OR/XOR對位棋盤進行位操作
位棋盤的挑戰:調試困難(位棋盤的值是二進制整數,不直觀);中國象棋棋盤尺寸與64位整數不完全適配(90位 vs 64位)。
第二章 着法生成器(Move Generator)的深度解析
2.1 中國象棋棋子的走法規則
中國象棋7種棋子的走法規則各不相同:
帥/將(King):在九宮格內(行0-2或7-9,列3-5)移動一格(上下左右),不能與對方帥/將在同一直線上無棋子相隔(將帥照面)。
士/仕(Advisor):在九宮格內沿斜線移動一格,只能在九宮格的5個交叉點上移動。
象/相(Bishop):沿斜線走田字(移動2格),有塞象眼的制約,不能過河。
馬(Knight):走日字(走2格+1格的組合),有蹩馬腿的制約。
車(Rook):沿直線(橫或豎)移動任意步數,不能跳過其他棋子。
炮(Cannon):不喫的走法沿直線移動任意步數,不能跳過其他棋子;喫子的走法沿直線移動,跨過一個棋子(炮架)後喫掉遇到的第一個對方棋子。
兵/卒(Pawn):未過河只能向前走一格;過河後可以向前或橫向走一格,不能後退。
2.2 着法生成僞代碼
中國象棋各棋子的着法生成邏輯:
車的着法生成:對每個方向(上下左右),從當前位置沿方向逐格枚舉。格子爲空時加入非喫着法並繼續;格子爲對方棋子時加入喫子着法並停止;格子爲己方棋子時停止。格子超出棋盤邊界時停止。
炮的着法生成:對每個方向沿方向逐格枚舉。使用炮架計數器:計數器爲0時,空格加入非喫着法,有棋子則計數器設爲1;計數器爲1時,對方棋子加入喫子着法並停止,己方棋子停止,空格繼續。
馬的着法生成:對馬的8個目標方向,計算目標位置和絆腳位置。絆腳位置有棋子(蹩馬腿)則跳過;目標位置爲己方棋子跳過;對方棋子加入喫子着法;空格加入非喫着法。
兵的着法生成:確定前進方向,目標爲空或對方棋子時加入着法。兵已過河時,左右方向同規則。
2.3 喫子着法的優先生成機制
在PVS搜索中,喫子着法的生成順序對搜索效率有重要影響。引擎按照以下優先級:
- 置換表最佳着法(如果存在於置換表中)
- 喫子勝算着法(SEE評估爲正的喫子着法)
- 贏子喫子着法(用低價值喫子喫掉高價值子)
- 同級喫子着法(用同價值子喫掉同價值子)
- 輸子喫子着法(用高價值子喫掉低價值子)
- 非喫子着法(先殺手着法、歷史啓發着法,後其他着法)
第三章 評估函數的深度剖析
3.1 手工評估函數的設計
中國象棋引擎的手工評估函數是一系列位置特徵的線性組合。典型的評估函數包含:子力價值評估、位置價值評估、棋子活動性評估、將帥安全性評估、局面結構評估、棋子協調性評估、戰術調整值。
子力價值評估中,不同棋子的基礎價值如下:
- 帥/將:10000(不可量化價值)
- 車:600
- 馬:270
- 炮:285
- 士/象:120
- 兵:30-150(隨局面階段變化)
位置價值表是每個棋子在棋盤上每個位置的預設價值。例如,紅方兵的位置價值:在己方陣地低分(兵尚未過河),在過河後位置高分,在中路(將帥附近)特別高分。
棋子活動性評估包括馬的可走方向數、車的可控制線數、炮的炮架數量和質量等。
將帥安全性評估包括保護將帥的士象數量、將帥周圍的控制空間、將帥是否暴露在對方棋子攻擊下等。
局面結構評估包括士象完整性、兵的陣型、河界和九宮的控制程度等。
3.2 評估函數的調優過程
手工評估函數的調優是一個系統性的工程:
基礎調優:根據已知象棋理論和經驗設定基礎參數,運行引擎自戰多局收集評估偏差,根據偏差調整參數。
局面類型調優:針對特定局面類型(開局、中局、殘局、優勢、劣勢)分別收集測試數據,分析各類型下的評估偏差,調整對應類型下的參數。
精細調優:使用Fishtest或類似統計測試框架進行大規模測試,每次調整一個參數觀察ELO變化,只保留ELO提升顯著的調整,重複直到參數達到局部最優。
3.3 手工評估函數的體系結構
手工評估函數具有層級結構:
第一層(靜態評估):子力價值、位置價值、棋子活動性。
第二層(動態評估):攻擊與防守關係、威脅檢測、戰術組合。
第三層(局面理解):局面階段性判斷、子力交換策略評估、將殺威脅評估。
第四層(規則約束):將帥照面檢測、長將長捉檢測、困斃檢測。
3.4 NNUE評估網絡的結構
NNUE評估網絡的結構如下:
輸入層使用稀疏的HalfKP特徵集。輸入向量維度約爲40,000(中國象棋適配版本)。特徵爲(己方將帥位置,對方棋子類型+位置),利用棋盤對稱性減少特徵數量。
隱藏層爲1-2層全連接網絡。第一層寬度通常爲512或1024個神經元,激活函數爲Clipped ReLU(裁剪到0-127範圍)。第二層(如果存在)寬度通常爲32或64個神經元。輸出層爲一個神經元,輸出局面評估值(以百分之一兵爲單位)。
NNUE的增量更新特性:每次走棋後,只需要更新與移動棋子相關的輸入特徵(通常是幾個到幾十個特徵),而不需要重新計算整個網絡。這種增量更新的計算複雜度爲O(特徵變更數 x 隱藏層寬度),遠低於O(輸入維度 x 隱藏層寬度)。
3.5 評估函數從手工到NNUE的變遷
中國象棋引擎的評估函數經歷了從手工到NNUE的根本性變遷:
傳統手工評估時代(1989-2021):
- 評估函數由開發者手動設計和調整
- 特徵數量有限(幾十到幾百個)
- 調優依賴開發者經驗和對棋理的理解
- 評估精度有限,但搜索效率高
NNUE評估時代(2022-至今):
- 評估函數由神經網絡自動學習
- 特徵數量巨大(數萬個輸入特徵)
- 調優依賴訓練數據質量和網絡結構設計
- 評估精度顯著提高,但推理計算量增加
NNUE對手工評估的優勢:
- 評估精度更高——NNUE可以發現手工評估難以編碼的細微模式
- 自動學習——不需要手動設計特徵和權重
- 持續改進——只要有更好的訓練數據,評估精度就能提升
- 通用性強——同一網絡結構可以適配不同的規則和局面類型
NNUE對手工評估的劣勢:
- 計算量較大——神經網絡推理比線性組合慢
- 訓練依賴數據——需要大規模高質量的訓練數據
- 解釋性差——難以理解NNUE爲何做出特定的評估
- 特定模型——不同局面類型可能需要不同的模型
第四章 搜索算法的深度解析
4.1 從Minimax到Alpha-Beta
Minimax搜索是計算機博弈的理論基石。其基本思想是:在博弈樹中,每一層代表一個玩家的走棋決策,假設雙方都選擇對自己最有利的走法。己方(MAX)選擇評估值最大的走法,對方(MIN)選擇評估值最小的走法。
Minimax的形式化定義:
Minimax(s) =
- 如果s是終局局面:返回評估值
- 如果輪到MAX走棋:max(Minimax(s') for s' in s的所有後繼局面)
- 如果輪到MIN走棋:min(Minimax(s') for s' in s的所有後繼局面)
Alpha-Beta剪枝是對Minimax的優化。它維護兩個值:
- alpha:MAX玩家當前最佳保證值(下限)
- beta:MIN玩家當前最佳保證值(上限)
當一個分支的搜索返回值超出了[alpha, beta]區間時,該分支可以被剪枝(因爲不會影響最終的決策結果)。
Alpha-Beta的理想複雜度爲O(b^(d/2)),其中b是分支因子(中國象棋約40),d是搜索深度。這意味着在同等時間內,Alpha-Beta可以搜索約兩倍深度的局面。
4.2 PVS(主變搜索)的引入
PVS(Principal Variation Search)是Alpha-Beta的高效變體。其核心思想是:假設搜索找到的第一個走法(主變)就是最佳走法,然後使用零窗口(null-window)驗證其他分支是否比主變更優。
零窗口搜索的關鍵:在搜索非主變分支時,使用(alpha, alpha+1)的窗口。如果搜索結果大於alpha(即窗口被突破),說明該分支可能比主變更優,此時使用完全窗口(alpha, beta)重新搜索。
PVS在中國象棋引擎中的實際應用:PVS將搜索效率提高了約10-20%。在分支因子高的中國象棋中,效果尤其顯著。
4.3 迭代加深的實踐
迭代加深搜索(IDS)是中國象棋引擎的標準搜索策略。其基本流程是從depth=1開始逐層增加搜索深度。
迭代加深的優勢:
- 時間可控:可以在任何時刻返回最佳着法
- 置換表預熱:淺層搜索結果可以被深層搜索利用
- 搜索穩定性:避免深層搜索的劇烈波動
- 着法排序改善:淺層找到的主變爲深層搜索提供順序參考
迭代加深的成本:每次加深需要重新搜索整棵樹。但在實際中,由於着法排序的改善和置換表的預熱,迭代加深的總成本只比直接最深搜索多約5-15%。
4.4 主要剪枝技術
空着裁剪(Null Move Pruning):假設讓對方連續走兩步,己方仍然不處於劣勢,則當前局面不值得深入搜索。空着裁剪在中國象棋中的使用需要設置安全閾值(R值,通常爲2-3層),並避免在危急局面下使用。
LMR(Late Move Reductions):對排序靠後的着法減少搜索深度。因爲排序靠後的着法質量較低,不值得全面搜索。LMR的縮減量根據搜索深度、着法類型(喫子/非喫子)和局面類型(是否被將軍)動態調整。
SEE(Static Exchange Evaluation):評估喫子交換序列的淨得失。SEE在中國象棋中的適配包括喫子價值順序、炮的跳喫處理、以及將帥不能暴露在將軍下的規則約束。
Futility裁剪:在淺層深度(通常是最後幾層),如果局面優勢或劣勢足夠大,直接結束搜索。
Razoring:類似於Futility,但在更深的層面上使用。
這些剪枝技術綜合使用,中國象棋引擎的搜索效率比基礎Alpha-Beta提高了數百倍。
第五章 置換表與哈希技術
5.1 Zobrist哈希的增量更新
Zobrist哈希是中國象棋引擎中最廣泛使用的局面哈希技術。它的增量更新特性使得每次走棋後更新哈希值的計算複雜度爲O(1)。
增量更新的過程:
- 從哈希值中異或掉移動棋子在原位置的隨機數
- 如果喫子,異或掉被喫棋子在原位置的隨機數
- 異或上移動棋子在新位置的隨機數
- 異或上走權標誌(表示輪到對方走棋)
- 如果將帥照面狀態改變,更新照面標誌
增量更新的高效性使得引擎可以在每次遞歸搜索調用中快速更新哈希值。
5.2 置換表的管理策略
置換表的大小和替換策略對搜索引擎性能有直接影響。
條目結構:每個條目包含哈希值簽名、搜索深度、節點類型(精確值/Alpha上限/Beta下限)、最佳走法和評估值。
替換策略:
- 深度優先替換:保留搜索深度更大的條目(即使它是舊的)
- Always Replace:總是用新條目替換舊條目
- 混合策略:考慮深度和年齡的加權組合
皮卡魚使用深度優先的替換策略,因爲深度更大的條目提供的信息價值更高。
哈希衝突處理:引擎通常使用32位或64位簽名來檢測衝突。較大的簽名空間可以減少衝突概率,但增加條目大小。