- 中國象棋電腦應用規范(五)
- 中國象棋通用引擎協議 版本: 3.0
- 象棋百科全書網 ( webmaster@xqbase.com )
- 2004年 12月初稿, 2007年 11月修訂
- 一、概述
- 中國象棋通用引擎協議 (Universal Chinese Chess Protocol,簡稱 UCCI),是一種象棋界面和象棋引擎之間的基於文本的通訊協議。設立中國象棋通用引擎協議的目的有:
- (1) 使一個“可視化象棋軟件”可以使用不同的“核心智能部件”,這些核心智能部件稱為“引擎”,凡是遵循 UCCI的引擎,都可以被該可視化象棋軟件 (也稱為“界面” )所調用;
- (2) 針對所有遵循 UCCI的引擎,都可以開發不同的界面,使其具有不同的功能。
- 這樣,“可視化象棋軟件”和“核心智能部件”實現了分離,使得一部分程序設計師能專注於前者 (界面 )的開發,而另一部分程序設計師能專注於后者 (引擎 )的開發,讓中國象棋軟件的設計工作系統化、分工化,提高軟件設計效率。
- UCCI是模仿國際象棋的 UCI來制定的。 UCCI是開放式的協議,並且具有 UCI的所有特點,具體反映在象棋百科全書網所收錄的以下文章中:
- (1) 國際象棋引擎:穿越困惑(轉載自《國際象棋譯文苑》) ;
- (2) 國際象棋引擎協議歷史(轉載自《國際象棋譯文苑》) ;
- (3) 國際象棋通用引擎協議 。
- UCCI 自誕生以來不斷在發展和更新,但保持了對早期版本的兼容。
- 3.0 版較 2.3 版改進的內容有:
- 建議取消option反饋中的repetition和drawmoves選項,將selectivity選項改成randomness,增加promotion選項。
- 2.3 版較 2.2 版改進的內容有:
- 建議采用“毫秒”作為唯一的時間單位,參閱option反饋中的usemillisec選項。
- 以后 UCCI 還會不定期地更新,並繼續保持對早期版本的兼容。 UCCI 界面和引擎設計者可訪問以下資源,來獲得最新的 UCCI 版本:
- http://www.xqbase.com/protocol/cchess_ucci.htm
- 二、通訊方法
- 不管是 Windows還是 UNIX平台,能被界面調用的引擎都必須是編譯過的可執行文件,它跟界面之間通過“標准輸入”和“標准輸出” (即 C/C++語言中的 stdin和 stdout)通道來通訊。如果引擎從 Windows平台移植到 UNIX平台,那么需要重新編譯源代碼 (管道操作的程序也需要作適當修改 ),或使用跨平台接口。
- 作為界面的設計,要啟動一個引擎, Windows平台下可用 CreateProcess()函數, UNIX平台下可用 fork()和 exec()函數,然后重定向到一個輸入管道和一個輸出管道,具體操作可參閱 WinBoard/XBoard源程序的 StartChildProcess()函數,或參閱中國象棋引擎 ElephantEye源程序的 <pipe.cpp>模塊。
- 作為引擎的設計,通訊比界面略為簡單 (只需要對 stdin和 stdout操作 ),只在檢查 stdin是否有輸入時較為麻煩,具體操作可參閱 Crafty源程序的 <utility.c>模塊的 CheckInput()函數,或參閱中國象棋引擎 ElephantEye源程序的 <pipe.cpp>模塊。
- 通常,界面向引擎發送的信息稱為“指令”,而引擎向界面發送的信息稱為“反饋”。在 UCCI中,不管是指令還是反饋,都是以“行”為單位的,即每條指令和反饋都必須以“回車” (即 C/C++語言中的 '\n')結束。
- 注意:引擎用緩沖方式發出反饋 (即 C/C++語言中直接將字符串寫入 stdout),那么每輸出一行都必須用 fflush()語句刷新緩沖區。
- 三、引擎的狀態
- UCCI引擎在啟動后,有三種狀態。
- (1) 引導狀態。
- 引擎啟動時,即進入引導狀態。此時引擎只是等待和捕捉界面的輸入,而界面必須用 ucci指令讓引擎進入接收其他 UCCI指令的空閑狀態 (稍后會提到 )。當然,引擎也可以保留使用其他協議的權利,例如引擎允許第一條有效指令是 cxboard,這樣引擎就轉而進入 CXBoard狀態。
- 收到 ucci只后,引擎要完成一系列初始化工作,以輸出 ucciok的反饋作為初始化結束的標志,進入空閑狀態。如果引導狀態下 UCCI引擎收到其他指令,則可以退出。
- (2) 空閑狀態。
- 該狀態下引擎沒有思考 (即幾乎不占用 CPU資源 ),而只是等待和捕捉界面的輸入 (和引導狀態類似 ),接收這樣幾類指令: A. 設置引擎選項 ( setoption指令 ), B. 設置引擎的內置局面 (即讓引擎思考的局面 )及其禁止着法 ( position和 banmoves指令 ), C. 讓引擎思考 ( go指令 ), D. 退出 ( quit指令 )。
- (3) 思考狀態。
- 引擎收到 go指令后,即進入思考狀態,以輸出 bestmove或 nobestmove的反饋作為思考狀態結束的標志 (回到空閑狀態 )。該狀態下引擎將滿負荷運轉 (CPU資源占用率接近 100%),但仍舊需要捕捉界面的輸入 (只有在批處理模式下不會捕捉界面的輸入 ),接收兩類指令: A. 中止思考 ( stop指令 ), B. 改變思考方式 ( ponderhit指令 )。
- go指令只決定了引擎將按照什么思考方式來思考 (即限定思考的深度,或限定思考的局面個數,或限定思考的時間 ),而思考的局面則必須通過前面輸入的 position指令來告訴引擎。
- 其他注意事項有:
- (1) 引擎只有在接收到 go指令后才開始思考。即便引擎支持后台思考,在輸出着法 (反饋 bestmove )后也不會自動進行,而是要由界面發送 go ponder指令,讓引擎以后台思考方式進行思考。
- (2) bestmove的反饋並不改變引擎的內置局面,如果界面讓引擎走棋,就必須讀取 bestmove反饋的着法,並在界面的局面上走完這一步 (當然,界面也可以走別的着法 ),再由 position指令把新的局面告訴引擎。
- (3) 如果對局是計時的,那么每次思考時都必須用 go指令設定時鍾,引擎僅僅根據時鍾來決定分配多少時間來思考,回到空閑狀態后時鍾就失效了,必須由界面扣去引擎思考的時間 (從發送 go指令起到收到 bestmove反饋結束 ),在下次發送 go指令時把新的時鍾告訴引擎。
- (4) 啟用“批處理”模式時,引擎在思考狀態下就不接收指令。批處理模式適合用重定向方式調試引擎,例如一個輸入文件含有以下指令集:
- 1: ucci
- 2: setoption batch true
- 3: position fen <fen_1>
- 4: go depth 10
- 5: position fen <fen_2>
- 6: go depth 10
- 7: quit
- 第 4行以后引擎即進入思考狀態,由於處於批處理模式,引擎反饋 bestmove后回到空閑狀態,才會繼續接收以后的指令。如果沒有第 2行的啟用批處理模式,那么第 4行以后的指令都將在思考狀態接收,而對於思考狀態,這些指令都是無效的。
- (5) 如果界面搞錯了引擎的狀態,在引擎的思考狀態向界面發送 quit指令,那么引擎最好能終止思考並立即退出,以避免界面無休止地等待引擎的退出。
- (6) 如果界面搞錯了引擎的狀態,在引擎的空閑狀態向引擎發送 stop指令,那么引擎最好能反饋一個 nobestmove,以避免界面無休止地等待引擎的反饋。
- 四、着法和棋盤的表示
- 界面告訴引擎哪些着法是禁手 ( banmoves指令 ),或者引擎回答界面應該走哪個着法 ( bestmove反饋 ),這樣的着法都用 4個字符 (簡化的 ICCS格式,參閱《 中國象棋電腦應用規范(二):着法表示》一文 )表示,即 ICCS格式去掉中間的橫線,並改成小寫,例如 h2e2。
- 界面用 position指令把局面告訴引擎時,應該使用 FEN串 (寫法參閱《 中國象棋電腦應用規范(三):FEN文件格式》一文 )。但是對局中會遇到循環局面,引擎也必須考慮其對策,因此 FEN串並不能完全反映局面信息,必須使用 FEN串 (當前局面前第一個不吃子的局面 )和后續着法相結合的方法表示局面。例如,開局以后走了以下 4步:
-
1. 炮二平五 炮8平5 2. 炮五進四 士4進5
- 如果把這 4步棋涉及的 5個局面都告訴引擎,那么指令依次是:
- 1: position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
- 2: position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2
- 3: position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2 h7e7
- 4: position fen rnbakabnr/9/1c2c4/p1p1C1p1p/9/9/P1P1P1P1P/1C7/9/RNBAKABNR b - - 0 2
- 5: position fen rnbakabnr/9/1c2c4/p1p1C1p1p/9/9/P1P1P1P1P/1C7/9/RNBAKABNR b - - 0 2 moves d9e8
- 其中第 4行更換了 FEN串,因為該局面前一個着法是吃子着法。
- 五、指令和反饋
- 按照慣例,指令用紅色表示,反饋用藍色表示。
- 1. ucci
- 引導狀態的指令。這是引擎啟動后,界面需要給引擎發送的第一條指令,通知引擎現在使用的協議是 UCCI。
- 2. id {name | copyright | author | user} < 信息 >
- 引導狀態的反饋。顯示引擎的版本號、版權、作者和授權用戶,例如:
- id name ElephantEye 1.6 Beta,說明引擎的版本號是 ElephantEye 1.6 Beta;
- id copyright 2004-2006 www.xqbase.com,說明引擎的版權屬於 www.xqbase.com所有;
- id author Morning Yellow,說明引擎的作者是 Morning Yellow;
- id user ElephantEye Test Team,說明引擎授權給用戶 ElephantEye Test Team使用。
- 3. option < 選項 > type < 類型 > [min < 最小值 >] [max < 最大值 >] [var < 可選項 > [var < 可選項 > [...]]] [default < 默認值 >]
- 引導狀態的反饋。顯示引擎所支持的選項, <option>指選項的名稱 (后面會介紹 ),選項的類型是 label (標簽,非選項 )、 button (指令 )、 check (是或非 )、 combo (多選項 )、 spin (整數 )、 string (字符串 )中的一種。
- 通常的 UCCI引擎支持以下選項:
- (1) usemillisec(check),通知界面采用毫秒模式。建議引擎始終采用毫秒模式 (即 go指令的時間單位是“毫秒” ),並總是在 ucciok前輸出 option usemillisec ... 的反饋信息。除非引擎不發送 option usemillisec ... 的反饋信息,否則界面將自動使用毫秒模式,並向引擎發送 setoption usemillisec true 的指令。目前已知的 UCCI界面程序 (如象棋巫師、 UCCI引擎聯賽模擬器等 )都采用這種做法;
- (2) batch(check),批處理模式 (前面介紹過 ),默認是關閉的;
- (3) debug(check),調試模式,默認是關閉的,打開后引擎會輸出更多的信息 ( info反饋 ),以幫助調試;
- (4) ponder(check),是否使用后台思考的時間策略,默認是關閉的,設定該參數的目的僅僅是讓引擎改變時間分配策略,而后台思考則仍然需要界面發出指令,參閱 go ponder和 ponderhit指令;
- (5) usebook(check),是否使用開局庫的着法,默認是啟用的,如果關閉的話,即便當前局面在開局庫中有着法,引擎也會不顧開局庫而思考的;
- (6) useegtb(check),是否使用殘局庫,默認是啟用的,和 usebook類似;
- (7) bookfiles(string),設定開局庫文件的名稱,可指定多個開局庫文件,用分號“ ;”隔開,如不讓引擎使用開局庫,除了可以關閉 usebook選項外,還可以把 bookfiles設成空值;
- (8) egtbpaths(string),設定殘局庫路徑的名稱,和 bookfiles類似;
- (9) evalapi(string),設定局面評價 API函數庫文件的名稱,和 bookfiles類似,但只能是一個文件 (例如, Windows下默認值是 EVALUATE.DLL, Linux下默認值是 libeval.so);
- (10) hashsize(spin),以 MB為單位規定 Hash表的大小, 0表示讓引擎自動分配 Hash表;
- (11) threads(spin),支持多處理器並行運算 (SMP)的引擎可指定線程數 (即最多可運行在多少處理器上 ), 0表示讓引擎自動分配線程數;
- (12) idle(combo),設定處理器的空閑狀態,通常有 none (滿負荷 )、 small (高負荷 )、 medium (中負荷 )、 large (低符合 )四種選項,引擎默認總是以滿負荷狀態運行的,而設置比較大的空閑狀態,可以在人機對弈時留出適當的處理器資源,讓用戶運行其他程序;
- (13) promotion(check),是否允許仕 (士 )相 (象 )升變成兵 (卒 ),這是一種中國象棋的改良玩法,默認是不允許的 (即默認采用常規走法 );
- (14) pruning(combo),設定裁剪程度,裁剪越多則引擎的搜索速度越快,但搜索結果不准確的可能性越大,通常有 none (無 )、 small (小 )、 medium (中 )、 large (大 )四種,一般都設為 large以充分展示引擎的搜索速度,但在處理一些刁難性的排局時,用 large或 medium不一定能解出,可嘗試 small或 none;
- (15) knowledge(combo),設定知識大小,通常知識量越多則程序的靜態局面評價越准確,但的運算速度會變慢,該選項和 pruning一樣有四種設定,一般都使用 large,但在解殺局時不需要靜態局面評價,可以把知識量設置得小些;
- (16) randomness(combo),設定隨機性系數,和 pruning一樣有四種設定,一般都設為 none,以保證引擎走出它認為最好的着法,但為了增強走棋的趣味性,可以把這個參數調高,允許引擎走出它認為不是最好的着法,以豐富走棋的樣式;
- (17) style(combo),設定下棋的風格,通常有 solid (保守 )、 normal (均衡 )和 risky (冒進 )三種;
- (18) newgame(button),設置新局或新的局面,引擎收到該指令時,可以執行導入開局庫、清空 Hash表等操作, UCCI界面《象棋巫師》在每次新建棋局或重新編輯局面時都會發送 setoption newgame 這條指令。
- 需要注意的是,各種引擎提供的選項內容是不一樣的,也並不是所有的 UCCI界面支持這些選項的,例如目前的 UCCI界面《象棋巫師》沒有對 batch、 debug等選項的設置 (它們只供調試時使用 )。
- 4. ucciok
- 引導狀態的反饋,此后引擎進入空閑狀態。
- 5. isready
- 空閑狀態和思考狀態的指令。檢測引擎是否處於就緒狀態,其反饋總是 readyok,該指令僅僅用來檢測引擎是否能夠正常接收指令。
- 6. readyok
- 空閑狀態和思考狀態的反饋。表明引擎處於就緒狀態 (可正常接收指令 )。
- 7. setoption < 選項 > [< 值 >]
- 空閑狀態的指令。設置引擎參數,這些參數都應該是 option反饋的參數,例如:
- setoption usebook false,不讓引擎使用開局庫;
- setoption selectivity large,把選擇性設成最大;
- setoption style risky,指定冒進的走棋風格;
- setoption loadbook,初始化開局庫。
- 但是,設置 option反饋沒有給出的參數,並不會出錯。例如 UCCI界面《象棋巫師》就從不識別 option反饋,而直接根據用戶的設置發送 setoption指令。
- 8. position {fen <FEN 串 > | startpos} [moves < 后續着法列表 >]
- 空閑狀態的指令。設置“內置棋盤”的局面,用 fen來指定 FEN格式串, moves后面跟的是隨后走過的着法,例如:
- position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2 h9g7
- FEN格式串的寫法參閱《 中國象棋電腦應用規范(三):FEN文件格式》一文。
- moves選項是為了防止引擎着出長打着法而設的, UCCI界面傳遞局面時,通常 fen選項為最后一個吃過子的局面 (或開始局面 ),然后 moves選項列出該局面到當前局面的所有着法。
- startpos表示開始局面,它等價於 fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 。
- 9. banmoves < 禁止着法列表 >
- 空閑狀態的指令。為當前局面設置禁手,以解決引擎無法處理的長打問題。當出現長打局面時,棋手可以操控界面向引擎發出禁手指令。例如:
- position fen 1r2kab1r/2c1a4/n1c1b1n2/4p2N1/p1p6/1C4P2/P1P1P4/2N1B3C/4A4/1RBAK2R1 w - - 0 1 moves h6i4 i9h9 i4h6 h9i9
- banmoves h6i4
- 本例取自《 象棋競賽規則》 (1999年版 )棋例圖三,由於大多數象棋引擎無法識別紅方這種方式的長捉,所以在采用中國象棋協會的比賽規則時,遇到這種局面就必須給引擎發出禁手指令。下一次發送 position指令后,前面設置過的禁止着法就取消了,需要重新設置禁止着法。
- 目前 UCCI界面《象棋巫師》不識別長打禁手,所以不會向引擎發送 banmoves指令。
- 10. go [ponder | draw] < 思考模式 >
- 空閑狀態的指令,此后引擎進入思考狀態。讓引擎根據 position指令設定的棋盤來思考,各選項為思考方式,有三種模式可供選擇:
- (1) depth < 深度 > | infinite:限定搜索深度, infinite表示無限制思考 (直到找到殺棋或用 stop指令中止 )。如果深度設定為 0,那么引擎可以只列出當前局面靜態評價的分數,並且反饋 nobestmove。
- (2) nodes < 結點數 >:限定搜索結點數。
- (3) time < 時間 > [movestogo < 剩余步數 > | increment < 每步加時 >] [opptime < 對方時間 > [oppmovestogo < 對方剩余步數 > | oppincrement < 對方每步加時 >]]:限定時間,時間單位是秒 (默認 )或毫秒 (啟用毫秒制時 ), movestogo適用於時段制, increment適用於加時制。 opptime、 oppmovestogo和 oppincrement可以讓界面把對方的用時情況告訴引擎。
- 如果指定 ponder選項,則引擎思考時時鍾不走,直到接受到 ponderhit指令后才計時,該選項用於后台思考,它只對限定時間的思考模式有效。
- 指定 draw選項表示向引擎提和,引擎以 bestmove提供的選項作為反饋,參閱 bestmove指令。
- 注意: ponder和 draw選項不能同時使用,如果界面向正在后台思考中的引擎求和,則使用 ponderhit draw指令。
- 11. info < 思考信息 >
- 思考狀態的反饋。顯示引擎思考信息,通常有以下幾種信息:
- (1) time < 已花費的時間 > nodes < 已搜索的結點數 >:思考信息中給出的時間通常以毫秒為單位,結點數和時間相除就是引擎的速度 (NPS值 ),單位是 K。
- (2) depth < 當前搜索深度 > [score < 分值 > pv < 主要變例 >]:輸出引擎思考到的深度及其思考路線和好壞。例如在起始局面下,《象棋巫師》收到引擎的反饋: info depth 6 score 4 pv b0c2 b9c7 c3c4 h9i7 c2d4 h7e7,那么界面上應該輸出: 6 (+4) 馬八進七 馬2進3 兵七進一 馬8進9 馬七進六 炮8平5。分值通常以一個輕子 (馬或炮 )為 100分記,以上信息說明此時當前要走的一方占有相當於 0.04個輕子的優勢。
- (3) currmove < 當前搜索着法 >:輸出引擎正在思考的着法。
- (4) message < 提示信息 >:輸出引擎要直接告訴用戶的信息,建議界面程序直接將提示信息顯示在界面上。
- 12. ponderhit [draw]
- 思考狀態的指令。告訴引擎后台思考命中,現在轉入正常思考模式 (引擎繼續處於思考狀態,此時 go指令設定的時限開始起作用 )。
- 指定 draw選項表示向引擎提和,引擎以 bestmove提供的選項作為反饋,參閱 bestmove指令。
- 13. stop
- 思考狀態的指令。中止引擎的思考。另外,后台思考沒有命中時,就用該指令來中止思考,然后重新輸入局面。
- 注意:發出該指令並不意味着引擎將立即回到空閑狀態,而是要等到引擎反饋 bestmove或 nobestmove后才表示回到空閑狀態,引擎應盡可能快地作出這樣的反饋。
- 14. bestmove < 最佳着法 > [ponder < 后台思考的猜測着法 >] [draw | resign]
- 思考狀態的反饋,此后引擎返回空閑狀態。顯示思考結果,即引擎認為在當前局面下的最佳着法,以及猜測在這個着法后對手會有怎樣的應對 (即后台思考的猜測着法 )。通常,最佳着法是思考路線 (主要變例 )中的第一個着法,而后台思考的猜測着法則是第二個着法。
- 在對手尚未落子時,可以根據該着法來設定局面,並作后台思考。當對手走出的着法和后台思考的猜測着法吻合時,稱為“后台思考命中”。
- draw選項表示引擎提和或者接受界面向引擎發送的提和請求,參閱 go draw和 ponderhit draw指令。 resign選項表示引擎認輸。 UCCI界面在人機對弈方式下,根據不同情況,可以對引擎的 bestmove反饋中的 draw和 resign選項作出相應的處理:
- (1) 如果用戶提和,界面向引擎發出 go draw或 ponderhit draw指令,而引擎反饋帶 draw的 bestmove,那么界面可終止對局並判議和;
- (2) 如果用戶沒有提和,而引擎反饋帶 draw的 bestmove,那么界面可向用戶提和,用戶接受提和則可終止對局並判議和;
- (3) 如果引擎反饋帶 resign的 bestmove,那么界面可終止對局並判引擎認輸。
- 引擎應該根據當前局面的情況 (由 position指令給出 ),以及界面是否發送了帶 draw的 go或 ponderhit指令,來考慮是否反饋帶 draw或 resign的 bestmove。
- 15. nobestmove
- 思考狀態的反饋,此后引擎返回空閑狀態。顯示思考結果,但引擎一步着法也沒計算,表示當前局面是死局面,或者接收到諸如 go depth 0 等只讓引擎給出靜態局面評價的指令。
- 16. probe {fen <FEN 串 > | startpos} [moves < 后續着法列表 >]
- 空閑狀態和思考狀態的指令。獲取 Hash表中指定局面的信息,引擎必須立刻在 Hash表中查找該局面的狀態,由 pophash指令反饋。
- 該指令僅用於引擎的調試,設計者可以向引擎發送一系列 probe指令,捕獲到搜索樹的大致信息。
- 17. pophash [bestmove < 最佳着法 >] [lowerbound <Beta 值 > depth < 深度 >] [upperbound <Alpha 值 > depth < 深度 >]
- 空閑狀態和思考狀態的反饋。輸出由 probe所指定的局面在 Hash表中信息。
- 如果該局面沒有記錄在 Hash表中,那么只反饋 pophash即可。
- 18. quit
- 空閑狀態的指令。讓引擎退出運轉。
- 19. bye
- 接收到 quit指令后的反饋。引擎完成了退出運轉前的准備工作,通知界面,引擎將在瞬間正常退出運轉。界面收到該指令后,即可關閉輸入輸出通道。
- 六、用例
- 下面是一個后台思考的例子,描述了 UCCI引擎中最難處理的部分。 (從界面到引擎的 )指令用紅色表示, (從引擎到界面的 )反饋用藍色表示。
- ucci
- id name ElephantEye Demo
- option usemillisec type check default false
- option usebook type check default true
- ucciok
- setoption usemillisec true
- setoption usebook false
- position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
- go time 300000 increment 0
- info depth 6 score 4 pv b0c2 b9c7 c3c4 h9i7 c2d4 h7e7
- info nodes 5000000 time 5000
- bestmove b0c2 ponder b9c7
- 在這個例子中,引擎執紅,用戶執黑,采用 5分鍾包干的時限。引擎啟動后,界面即讓引擎分析初始局面 (不用開局庫 ),引擎給出最佳着法“馬八進七”,然后是用戶走子,引擎按照猜測着法“馬2進3”作后台思考。此時,引擎消耗了 5秒鍾,還剩余 295秒的時間。
- position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves b0c2 b9c7
- go ponder time 295000 increment 0
- info depth 6 score 4 pv c3c4 h9i7 c2d4 h7e7 h0g2 i9h9
- 此時用戶走子了,下面分兩種情況討論。
- (1) 如果用戶走了引擎的猜測着法“馬2進3”,那么后台思考命中:
- ponderhit
- info nodes 10000000 time 10000
- info depth 7 score 4 pv c3c4 h9i7 c2d4 h7e7 h0g2 i9h9 i0h0
- info nodes 15000000 time 15000
- bestmove c3c4 ponder h9i7
- 現在引擎走“兵七進一”,並且猜測對方會走“馬8進9”。盡管這着棋引擎思考了 15秒鍾,但是前 10秒鍾用的是對手的時間,自己的時間是從 ponderhit到 bestmove的部分,所以自己的時間只消耗了 5秒鍾,因此還剩余 290秒的時間。然后引擎繼續后台思考。
- position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves b0c2 b9c7 c3c4 h9i7
- go ponder time 290000 increment 0
- ……
- (2) 如果用戶走了其他的着法 (比如“卒3進1” ),那么后台思考沒有命中,必須根據這個着法重新思考。
- stop
- info nodes 10000000 time 10000
- bestmove c3c4 ponder h9i7
- position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves b0c2 c6c5
- go time 295000 increment 0
- ……
- 如希望獲得更詳細的關於 UCCI操作上的細節,可參考 UCCI引擎 ElephantEye的源程序及其說明材料,這里不再作過多的介紹。
- 七、電腦象棋聯賽
- 電腦象棋聯賽使用 UCCI引擎,但是參賽引擎並不一定要支持 UCCI的全部內容,只需要能跟“ UCCI引擎聯賽模擬器”正常通訊就可正常比賽了,模擬器相當於一個支持 UCCI的界面。參賽引擎必須能夠識別並正確處理的指令有:
- (1) ucci;
- (2) position fen ... [moves ...];
- (3) banmoves ...;
- (4) go [draw] time ... increment ... [opptime ... oppincrement ...];
- (5) quit。
- 參賽引擎必須能夠反饋的信息有:
- (1) ucciok;
- (2) bestmove ... [draw | resign]。
- 為了更好地讓引擎適應模擬器,引擎最好能夠實現以下功能:
- (1) 支持毫秒制。即啟動時有 option usemillisec的反饋,能夠識別並處理 setoption usemillisec true的指令。啟用毫秒制以后,在時間非常緊缺的情況下,模擬器就會准確地把時間告訴引擎,否則只會粗略地給出秒數。
- (2) 支持認輸和提和,即當引擎覺得沒有機會獲勝時,可以用 bestmove ... draw提和或接受提和,當引擎覺得沒有能力抵抗時,可以用 bestmove ... resign認輸,節約比賽時間。
- (3) 支持 stop指令。當引擎超時后,模擬器會發送 stop指令讓引擎立即給出着法 (立即反饋 bestmove ),超過一定時間 (如超過 0.2秒 )才判超時負。
- 另外,識別 setoption指令不是必須的,但在聯賽中也會有用。例如,如果引擎需要用 setoption bookfiles ...來導入開局庫,而模擬器不會自動向引擎發送這條指令,那么引擎必須建立配置文件,其中有 setoption bookfiles ...這行指令,模擬器在啟動引擎后,會把配置文件中的每行都作為指令發送給引擎的。
- 八、和 UCI 的區別
- UCCI是從國際象棋通用引擎協議 UCI移植過來的,沿用了大部分 UCI的指令和反饋,但是為了適應中國象棋軟件的需要,作了以下幾點改動:
- (1) 增加了 banmoves指令,因為中國象棋有長打作負的規則。
- (2) 把 UCI的反饋 option name < 選項 > type < 類型 > ...簡化為 option < 選項 > type < 類型 > ...。例如, UCI中有 option name Hash Size type spin這條反饋,而在 UCCI中則是 option hashsize type spin。這里去掉了 name關鍵字,因為它總是跟在 option后面,顯得多此一舉。另外, UCI允許選項由多個有大小寫的單詞組成 (如 Hash Size ),這是因為 UCI界面會直接把這個選項名稱顯示在對話框上。而 UCCI中的選項只用一個全部由小寫字母組成的單詞,因為中國象棋的 UCCI界面使用中文,因此界面上不能輸出 Hash Size,而用“置換表”或其他可以看得懂的中文術語。這樣,界面還不如識別一個更簡單的 hashsize (一個全部由小寫字母組成的單詞 ),再翻譯成“置換表”。
- (3) 把 UCI的指令 setoption name < 選項 > [value < 值 >]簡化為 setoption < 選項 > [< 值 >]。由於 UCCI的選項是一個單詞,所以第二個空格后的內容肯定是選項的值,因此 name和 value就顯得多此一舉了。
- (4) UCCI明確了引擎所處的三種狀態,以及這三種狀態下適用的指令和反饋,為界面和引擎的程序設計提供了清晰的思路。
- (5) UCCI以 go time < 時間 > opptime < 時間 >的形式把雙方的時間信息傳達給引擎,而不是 UCI的 go wtime < 時間 > btime < 時間 >,這樣可以簡化引擎解析時間的操作,如果引擎在指定用時策略時不考慮對方的用時,那么可以不理會 opptime < 時間 >。
- (6) UCCI明確了 4種思考模式,使得指令的解析簡單化了。
- (7) UCCI規定 position fen ... [moves ...]指令中的 FEN串是當前局面前第一個不吃子的局面,后面再跟該局面的后續着法。而 UCI則是用 position startpos moves ...指令,把棋局從頭到尾的着法全都列出來,會增加通訊通道的壓力。