皮卡魚是目前我知道的中國象棋開源引擎中最強的,因為我還不知道其它的開源引擎,如果有知道的請留言告知。
皮卡魚開源地址:
https://github.com/official-pikafish/Pikafish/
皮卡魚網頁版:
那麼,既然已經有了皮卡魚網頁版,為什麼我還是希望在本地跑皮卡魚引擎?
原因是,我想不到皮卡魚的引擎文件才幾百K那麼小,就幾百K的文件就能成為目前最強的中國象棋AI?這引起了我很大的好奇心。當然後來我知道了它依賴一個五十多M的nnue文件,即便如此,它的體積仍然是非常的小。
還有一個原因是,我熱衷於收集單機軟體,不需要聯網也能執行。雖然我主要還是會去用皮卡魚網頁版,但是在本地留存一份單機版,對我而言是必須的。
2026-03-19補充:後來發現,本地版比網頁版要快很多,本地版只用7到12秒,就能算到網頁版一分鐘才得出的結果。
在linux,只需要加上chmod +x pikafish-sse41-popcnt,再把nnue放到同一個目錄中,就能跑起來了。
Android也很簡單,安裝好termux後,把android版執行檔和nnue文件,複製到其根目錄的一個文件夾中,添加執行權限,就能開始玩了。
我主要使用的指令
> ucinewgame
> isready
readyok
> position fen r2akabr1/9/1cn1b1nc1/p3p1pRp/2p6/6P2/P1P1P3P/NC2C1N2/9/R1BAKAB2 b
> go movetime 12000
> d
> position fen r2akabr1/9/1cn1b1nc1/p3p1pRp/2p6/6P2/P1P1P3P/NC2C1N2/9/R1BAKAB2 b moves a6a5
> go movetime 3600
> d
輸入 uci 並回車,讓引擎進入 UCI 模式。
輸入以下指令調整哈希表大小(例如設置為 4GB):
setoption name Hash value 4096
更改最佳路徑數量(例如改為 3 條):
setoption name MultiPV value 3
UCI指令說明
expand
中文翻譯
UCI & Commands (UCI 與指令)
通用象棋介面 (Universal Chess Interface, UCI) 是一種標準的文本協定,用於與象棋引擎進行通訊。對於一般的圖形使用者介面 (GUI) 或象棋工具,這是建議的使用方式。Pikafish 實作了大部分的 UCI 選項。
開發者可以在終端機輸入 ./pikafish uci 來查看 Pikafish 中可用 UCI 選項的預設值,但大多數使用者通常應使用象棋 GUI 來與 Pikafish 互動。
Standard commands (標準指令)
quit (退出)
儘快退出程式。
uci (進入 UCI 模式)
告訴引擎使用 UCI 協定。 這通常由 GUI 在程式啟動後發送的第一條指令,用來告訴引擎切換到 UCI 模式。 收到 uci 指令後,引擎會透過 id 指令識別身份,並發送 option 指令告知 GUI 引擎支援哪些設定。 之後,引擎會發送 uciok 以確認已進入 UCI 模式。 如果在一定時間內沒有發送 uciok,GUI 將會終止引擎程序。
setoption (設定選項)
用法:setoption name <id> [value <x>]
當使用者想要更改引擎的內部參數時,會將此指令發送到引擎。對於「按鈕 (button)」類型的選項,不需要數值 (value)。 每個參數都會發送一個字串,且這只會在引擎處於等待狀態時發送。
範例:
setoption name Threads value 6setoption name EvalFile value pikafish.nnuesetoption name UCI_ShowWDL value truesetoption name Clear Hash
選項列表:
-
Debug Log File (類型:string,預設:無) 將與引擎之間的所有通訊記錄到文字檔中。
-
NumaPolicy (類型:string,預設:auto) 綁定執行緒以確保在特定的 NUMA 節點上執行。這能提升多 CPU 系統或具有多個 NUMA 網域的 CPU 效能。可以使用以下值:
-
system:從系統獲取 NUMA 節點資訊(包括使用者或 GUI 預設的親和性),並將每個執行緒綁定到單個 NUMA 節點。 -
none:假設只有 1 個 NUMA 節點,不進行執行緒綁定。 -
auto:預設值,根據設定的執行緒數和可用的 NUMA 節點自動選擇system或none。僅在執行緒數達到系統特定閾值時才會選擇system。 -
hardware:獲取底層硬體的 NUMA 節點資訊(無視並覆蓋使用者或 GUI 預設的親和性),並將每個執行緒綁定到單個 NUMA 節點。 -
[[custom]]:精確指定每個 NUMA 網域可用的 CPU。:用於分隔節點;,用於分隔 CPU 索引;支援first-last範圍語法,例如0-15,32-47:16-31,48-63。
-
-
Threads (類型:spin,預設:1,最小:1,最大:1024) 搜尋局面時使用的 CPU 執行緒數量。為了獲得最佳效能,請將此值設為可用的 CPU 核心數。
-
Hash (類型:spin,預設:16,最小:1,最大:33554432) Hash 表(雜湊表)的大小,單位為 MB。建議在設定
Threads之後再設定Hash。 -
Clear Hash (類型:button) 清除 Hash 表。
-
Ponder (類型:check,預設:false) 讓 Pikafish 在對手思考時進行預判思考 (Ponder)。
-
MultiPV (類型:spin,預設:1,最小:1,最大:500) 搜尋時輸出前 N 條最佳路徑 (PV)。為了獲得最佳效能,請保持為 1。
-
Move Overhead (類型:spin,預設:10,最小:0,最大:5000) 假設由於網路和 GUI 造成的延遲為 毫秒。這有助於避免在這些情況下超時判負。
-
nodestime (類型:spin,預設:0,最小:0,最大:10000) 告知引擎使用搜尋的節點數而非實際牆鐘時間 (wall time) 來計算經過的時間。這對引擎測試很有用。設定此選項後,引擎僅受限於每局遊戲搜尋的總節點數;該限制每局計算一次。 初始時間控制值(以毫秒為單位的
time時間和每步增量inc)作為計算總節點數 (totalnodes) 的輸入。計算公式為: 假設你指定nodestime = 600,且每局的時間控制為 300 秒加 3 秒增量(即 300,000 毫秒 + 3,000 毫秒)。在這種情況下,無論實際花費多少牆鐘時間,引擎每局搜尋的最大總節點數為 個節點。 -
UCI_ShowWDL (類型:check,預設:false) 若啟用,則在引擎輸出中顯示大約的 WDL (勝/平/負) 統計數據。這些 WDL 數據是根據給定的評估值和步數,模擬引擎在 fishtest LTC 條件下(每局 60+0.6s)自我對弈的預期結果。
-
EvalFile (類型:string,預設:pikafish.nnue) NNUE 評估參數檔案的名稱。取決於 GUI,檔案名稱可能需要包含指向該檔案資料夾的完整路徑。引擎也會搜尋包含執行檔的目錄和當前工作目錄。
position (局面)
用法:position [fen <fenstring> | startpos ] moves <move1> .... <movei>
設定 fenstring 中描述的局面。
注意: 如果此局面來自與上次發送給引擎的不同對局,GUI 應在中間發送 ucinewgame。
範例:
position startposposition fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2 h9g7 h0g2 g6g5
ucinewgame (開始新對局)
當下一次搜尋(使用 position 和 go 啟動)來自不同的對局時,會將此指令發送給引擎。這可以是一個新對局,也可以是從測試集中取出的一個新局面。 如果 GUI 在第一個 position 指令前沒有發送 ucinewgame,引擎將不再預期任何進一步的 ucinewgame 指令,因為該 GUI 可能不支援此功能。 因此,儘管所有新的 GUI 都應支援此指令,引擎不會完全依賴它。 由於引擎對 ucinewgame 的反應可能需要一些時間,GUI 應在 ucinewgame 之後發送 isready 以等待引擎完成操作。引擎會以 readyok 回應。
這會清除 Hash 表以及之前搜尋過程中收集的所有資訊。
isready (準備就緒)
這用於將引擎與 GUI 同步。 當 GUI 發送了一個或多個可能需要時間完成的指令時,可以使用此指令等待引擎再次進入就緒狀態,或者用於 Ping 引擎以查看其是否仍有反應。 例如:在設定桌庫路徑後應發送此指令,因為這可能需要一些時間。 此外,在要求引擎進行任何搜尋之前,也必須發送一次此指令,以等待引擎完成初始化。 此指令一律會以 readyok 回答,即使引擎正在計算時發送也可以,在這種情況下,引擎會立即回答 readyok 而不會停止搜尋。
範例:
isreadyreadyok
go (開始搜尋)
開始對使用 position 指令設定的當前局面進行計算。 此指令後面可以跟隨許多參數,所有參數都會在同一個字串中發送。 如果沒有發送參數,則會執行 go depth 245。
範例:
-
go infinite -
go depth -
go mate -
MultiPV -
UCI_ShowWDL
參數:
-
searchmoves .... 僅限於搜尋這些走法。
-
ponder 在預判思考模式下開始搜尋。在此模式下,即使出現將死 (mate) 也不會結束搜尋!這意味著
position字串中發送的最後一步是預判步。引擎可以隨意運作,但在收到ponderhit指令後,它將執行建議的預判步。 -
wtime :白方時鐘剩餘 毫秒。
-
btime :黑方時鐘剩餘 毫秒。
-
winc :如果 ,白方每步增量為 毫秒。
-
binc :如果 ,黑方每步增量為 毫秒。
-
movestogo :距離下一個時控還有 步。注意:僅在 時發送,若未收到此參數且收到了時鐘時間,則為「突然死亡」模式。
-
depth :僅搜尋 層(半回合)。
-
nodes :僅搜尋 個節點。
-
mate :搜尋 步內的將死。
-
movetime :精確搜尋 毫秒。
-
infinite:持續搜尋直到收到
stop指令。在此模式下,不被告知就不會結束搜尋。 -
perft :一個偵錯功能,走過嚴格合規的移動生成樹,以統計特定深度的所有葉節點。
stop (停止)
儘快停止計算。
ponderhit (預判命中)
使用者走出了預期的棋步。 如果告知引擎預判的棋步與使用者實際走的棋步相同,就會發送此指令。引擎將繼續搜尋,但從預判模式切換為正常搜尋。
Non-standard commands (非標準指令)
bench (基準測試)
在預先選擇的一組局面(測評集)上執行標準搜尋基準測試。它會印出搜尋的總合併節點數以及花費的時間。此指令有兩個主要用途:
-
作為基礎的「每秒節點數」(NPS) 速度基準。
-
搜尋的總節點數可作為二進制檔案中確切搜尋算法版本的「特徵碼」或「指紋」。
節點數特徵碼的主要效用是確保在 Fishtest 上測試新的補丁時,作者和測試者的代碼完全一致。它也可用於驗證本地擁有的版本。Pikafish 提交歷史中的每個功能性提交都包含一個標準化的節點數特徵碼。(例如,Pikafish 2023-03-05 的節點數特徵碼是 1146720。)
可以使用多個參數來微調基準測試的執行方式: 用法:bench [ttSize] [threads] [limit] [fenFile] [limitType]
注意: 所有參數都是可選的。使用所有預設參數可獲得版本的標準化節點數特徵碼。
注意:
-
字串參數區分大小寫。若字串參數值無效,不會給出錯誤,且行為未定義。
-
[檔案路徑]可以包含一個或多個局面,每行一個。
d (顯示)
顯示當前局面,包含 ASCII 圖形和 FEN 字串。
eval (評估)
顯示當前局面的靜態評估。
compiler (編譯器)
提供有關用於構建二進制檔的編譯器和環境資訊。
export_net [filename] (匯出網路)
將目前加載的網路匯出到檔案。如果目前加載的是嵌入式網路且未指定檔名,則網路將儲存到與 evaluate.h 中定義的嵌入式網路名稱匹配的檔案中。如果加載的不是嵌入式網路(透過 UCI setoption 設定的某個網路),則需要提供檔名參數。
flip (翻轉)
翻轉走子方。