国际象棋通用引擎协议

UCI协议的特点

UCI协议,全称是国际象棋通用引擎协议(Universal Chess Interface,直译作通用象棋接口)。它是开放的象棋引擎协议,所谓“开放的”引擎协议,指的是:
  (1) 协议内容是公开的,并且可以免费使用;
  (2) 你可以根据该协议自己编写象棋引擎,凡是支持该协议的界面,都可以使用你编写的引擎;
  (3) 你可以根据该协议自己编写象棋界面,凡是支持该协议的引擎,都可以被你编写的界面调用。
  UCI协议的前身是象棋引擎SOS和Shredder使用的引擎协议,在他们的作者Rudolf Huber和Stefan Meyer-Kahlen对该协议的改进下,2000年11月28日UCI协议问世了。
 
  UCI协议具有以下特点:
  (1) 引擎程序是可执行文件,它同界面程序之间通过“标准输入”和“标准输出”(即C语言中的stdin和stdout)来通讯。
  (2) 输入和输出是以“行方式”来完成的,界面发给引擎的每条指令都必须以“回车”(即C语言中的'\n')结束,界面接收引擎的反馈也一样。
  注:引擎不能跨平台使用,如果引擎从一个平台(如Windows)移植到另一平台(如Unix),需要重新编译源代码,或使用跨平台接口。引擎的平台通常由三类:
  A. DOS平台,但是由于DOS平台过于陈旧,现在很难找到这样的引擎;
  B. Windows平台,需要在Windows下用Console方式编译引擎源代码,WinBoard只能使用这类引擎;
  C. Unix/Linux平台;需要在Unix或Linux下编译源代码(也用Console方式),XBoard能够使用Linux的引擎。
  (3) 引擎启动时,必须用“uci”指令让引擎进入UCI协议状态。当然,引擎也可以保留不使用UCI协议的权利,只要它接受的第一条有效指令允许不是“uci”。例如,很多UCI引擎允许第一条有效指令是“xboard”,这样引擎就转而进入WinBoard协议状态。
  (4) 无论引擎是否在思考,都必须随时接收指令,这样界面程序就可以随时中断引擎的工作或改变引擎的思考方式了。每条指令都以特定的关键字开头,关键字和参数之间必须用空格隔开,这样可以简化引擎识别指令的过程。
  (5) 界面必须随时接收引擎的反馈信息,每条反馈信息也都以特定的关键字开头(空格后面才是信息的实质内容),这样可以让界面更方便地识别每一条反馈信息。
  (6) 引擎在搜索一个局面前,先要让界面把局面的位置告诉引擎,作为“内置局面”;
  (7) 引擎必须接收到"go"指令后才开始思考(搜索);
  (8) 如果对局是计时的,那么每次思考时都必须设定时钟,引擎仅仅根据时钟来决定思考策略,时钟的改变需要界面来完成;
  (9) 当引擎完成一个局面的搜索,得到一步最佳着法后,并不改变“内置局面”,只是把这个着法反馈给界面,界面来完成这一步(当然,界面也可以让引擎走别的着法),再把走完这一步后的局面告诉引擎;
  (10) 开局库通常由界面来指定给引擎,即通常引擎是不自带开局库的,当然引擎也可以自带开局库,此时界面可以让引擎根据引擎自己的开局库来完成开局的某步。
  以上10个特点中,前5点和WinBoard协议是类似的,而后5点WinBoard协议和UCI协议则完全相反,因此WinBoard协议和UCI协议的指令也截然不同。

走棋格式

UCI协议用的走棋格式是“长代数格式”,即走动子的起始位置和到达位置,这里有几点需要注意:
(1) 不要标明“到达记号”、“吃子记号”、“将军记号”以及其他评注记号,例如第一步走e4,则记作e2e4,而不是e2-e4;
(2) 不要标明所走的子,例如走Nf6,则记作g8f6,而不是Ng8f6;
(3) 王车易位时只标明王的路线,例如走O-O,则记作e1g1;
(4) 兵升变时在最后注明只用一个字母注明升变的子,例如走e8=Q,则记作e7e8q。

输入和输出协议

输入协议就是界面向引擎发送指令的协议,协议内容通常由一系列指令集组成(\color{red}{用红色表示}),输出协议则规定了引擎反馈给界面的信息,以及这些信息具体的含义(\color{blue}{用蓝色表示})。

  1. \color{red}{uci}
      这是引擎启动后,界面需要给引擎发送的第一条指令,通知引擎现在使用的是UCI协议。
  2. \color{blue}{id {name <x> | author <x>}}
      这是\color{red}{uci}指令的反馈信息,显示引擎的版本号和作者。
  3. \color{blue}{option name <id> type <t> [default <x>] [min <x>] [max <x>] [var <x> [var <x> [...]]]}
      也是\color{red}{uci}指令的反馈信息,表示引擎所支持的选项,<id>指选项的名称(后面会介绍),<t>指选项的类型,可以是以下5种:
      (1) \color{blue}{check},检查框,取值只能是true或false;
      (2) \color{blue}{spin},旋钮,取值是整数,可以用min和max来限定范围;
      (3) \color{blue}{combo},列表框,取值是由var来指定;
      (4) \color{blue}{button},按钮,没有取值,仅仅用来触发某个事件;
      (5) \color{blue}{string},字符串,取值可以是任何字符串。
      通常的UCI引擎支持以下选项:
      (1) \color{blue}{Hash(spin)},以MB为单位规定Hash表的大小;
      (2) \color{blue}{NalimovPath(string)},指定Nalimov残局库的路径,可以设置多个路径,用';'隔开;
      (3) \color{blue}{NalimovCache(spin)},以MB为单位规定Nalimov残局库的缓冲区;
      (4) \color{blue}{Ponder(check)},指定引擎是否后台思考(Ponder),设定该参数的目的仅仅是让引擎改变时间分配策略,后台思考仍然需要界面发出指令;
      (5) \color{blue}{OwnBook(check)},指定引擎是否要使用引擎自带的开局库;
      (6) \color{blue}{MultiPV(spin)},引擎给出多少步最佳着法,Alpha-Beta搜索通常只给出一步,增加这个数值会降低引擎的运行效率,但扩大了界面对引擎提供着法的选择空间;
    4.\color{blue}{uciok}
      这是\color{red}{uci}指令的最后一条反馈信息,表示引擎已经进入用uci协议通讯的状态。
  4. \color{red}{setoption name <id> [value <x>]}
      设置引擎参数,这些参数必须是option反馈信息所列出的。
  5. \color{red}{isready}
      检测引擎是否处于“就绪”状态,如果引擎发送回readyok信息,则说明引擎已经就绪,可以界面可以向引擎发出其他指令。
  6. \color{blue}{readyok}
      这是\color{red}{isready}的反馈信息,仅仅表示引擎可以接收指令了。即使引擎在思考,接收到\color{red}{isready}指令后也会返回\color{blue}{readyok}
  7. \color{red}{position {fen <fenstring> | startpos } [moves <move1> .... <moven>]}
      设置“内置棋盘”的局面,用\color{red}{fen}来指定FEN格式串,或用\color{red}{startpos}来指定起始局面,它等价于
    \color{red}{fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1}
      一般来说,界面发送给引擎的<fenstring>是最近一次吃子或进兵后的局面(称为“不可逆局面”),该局面到当前局面的一系列着法则跟在\color{red}{moves}后,目的是让引擎掌握重复检测的策略。FEN格式串的写法参阅 国际象棋-关于PGN和FEN记谱规范(上)国际象棋-关于PGN和FEN记谱规范(下)
  8. \color{red}{go ...}
      让引擎根据内置棋盘的设置和设定的搜索方式来思考,有以下搜索方式可供选择(可以多选,直接跟在go后面):
      (1) \color{red}{searchmoves <move1> .... <moven>},只让引擎在这几步中选择一步;
      (2) \color{red}{wtime <x>},白方剩余时间(单位是毫秒);
        \color{red}{btime <x>},黑方剩余时间;
        \color{red}{winc <x>},白方每步增加的时间(适用于Fischer制);
        \color{red}{binc <x>},黑方每步增加的时间;
        \color{red}{movestogo <x>},还有多少回合进入下一时段(适用于时段制);
      这些选项用来设定时钟,它决定了引擎的思考时间;
      (3) \color{red}{ponder},让引擎进行后台思考(即对手在用时,引擎的时钟不起作用);
      (4) \color{red}{depth <x>},指定搜索深度;
      (5) \color{red}{nodes <x>},指定搜索的节点数(即分析的局面数,一般它和时间成正比);
      (6) \color{red}{mate <x>},在指定步数内只搜索杀棋;
      (7) \color{red}{movetime <x>},只花规定的时间搜索;
      (8) \color{red}{infinite},无限制搜索,直到杀棋。
  9. \color{blue}{info ...}
      显示引擎思考信息,信息有以下内容(可以是很多信息,都跟在\color{blue}{info}后面):
      (1) \color{blue}{depth <x>},当前搜索到的深度;
      (2) \color{blue}{seldepth <x>},选择性搜索(不完全搜索)达到的深度,通常会跟在depth后面;
      (3) \color{blue}{pv <move1> ... <moven>},已经搜索到的最佳路线;
      (4) \color{blue}{multipv <num>},这只会出现在设定了MultiPV选项以后,紧跟在pv后面,说明它是最佳的路线中的第几条(排名第几);
      (5) \color{blue}{time <x>},已经搜索的时间,它往往跟在pv后面;
      (6) \color{blue}{score {pv <x> | mate <y>} [lowerbound | upperbound]},引擎对当前局面的评价,\color{blue}{pv <x>}指当前局面的评分,单位是“百分兵值”,\color{blue}{mate <y>}指在多少步之内会形成杀棋,\color{blue}{lowerbound}指该评价是最低估计(为白方估计),\color{blue}{upperbound}指该评价是最高估计(为黑方估计);
      (7) \color{blue}{currmovenumber <x>},当前搜索着法的序号;
      (8) \color{blue}{currmove <move>},当前搜索的着法,它往往跟在\color{blue}{currmovenumber <x>}的后面;
      (9) \color{blue}{nodes <x>},已经搜索的节点数(即分析的局面数,它会隔一定时间显示出来;
      (10) \color{blue}{hashfull <x>},Hash表的占用率(单位是千分之一),它也会隔一定时间显示出来;
      (11) \color{blue}{nps <x>},引擎速度,用每秒搜索的节点数,它也会隔一定时间显示出来;
      (12) \color{blue}{tbhits <x>},在残局库中找到局面的数目;
      (13) \color{blue}{cpuload <x>},处理器的占用率(单位是千分之一);
      (14) \color{blue}{string <str>},其他信息,通常是调试信息。
  10. \color{red}{stop}
      中断引擎的思考;
  11. \color{red}{ponderhit}
      在后台思考(\color{red}{go ponder})还没有输出结果(\color{blue}{bestmove <x>})时,告诉引擎后台思考命中(正在后台思考的着法正好是对手的着法),随后引擎就自动转入正常思考(时钟开始有效)。如果后台思考没有命中,就必须用\color{red}{stop}中止思考,重新设置局面让引擎思考。
  12. \color{blue}{bestmove <move1> [ponder <move2>]}
      引擎思考结束后(不管是否被\color{red}{stop}中断)所显示的结果,\color{blue}{ponder}指为对手思考的结果,通常引擎会提供此信息。
  13. \color{red}{quit}
      让引擎退出运转,无论引擎思考与否。

举例

在下面的例子中,输入部分(从界面到引擎)用红色表示,输出部分(从引擎到界面)用蓝色表示。


image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容