围棋引擎的GTP协议

1.GTP协议
2.GTP方式启动GNUGO
3.协议应用
4.Metamachine
5.增加新GTP 命令
6.GTP 命令参考
7.指令表

1 GTP协议

GNU GO 3.0引入了一个新接口——围棋文本协议, 英文缩写:GTP,其目的是建立一个比GMP(Go Modem Protocol)协议的ascii 接口更合适于双机通信、更简单、更有效、更灵活的接口。

该协议有两种版本。GNU GO 3.0 和3.2使用了版本1,GNU GO 3.4及以后的版本使用协议版本2。规格定义在http:http://www.lysator.liu.se/~gunnar/gtp
GNU GO3.4 参考实现了GTP 版本2,除了多数共同的命令也对这个协议进行了私有扩展。

GTP有很多用途。对GNU GO来说,第一个用途是回归测试(20回归测试),其次是利用GTP与NNGS围棋服务器连接,同自身或其它程序对弈进行自动测试。目前也有许多支持GTP的图形用户界面,用来桥接与NNGS类似的围棋服务器。

2 GTP方式启动GNUGO

以GTP 方式启动GNU GO, 只要用“–mode gtp” 参数启动GNUGO就可以。接着你不会得到提示或什么其它输出,但是GNU GO已经在默默地等待GTP命令。

一个GTP会话如下例:

virihaure 462% ./gnugo --mode gtp

1 boardsize 7

=1

 

2 clear_board

=2

 

3 play black D5

=3

 

4 genmove white

=4 C3

 

5 play black C3

?5 illegal move

 

6 play black E3

=6

 

7 showboard

=7

   A B C D E F G

 7 . . . . . . . 7

 6 . . . . . . . 6

 5 . . + X + . . 5

 4 . . . + . . . 4

 3 . . O . X . . 3

 2 . . . . . . . 2     WHITE (O) has captured 0 stones

 1 . . . . . . . 1     BLACK (X) has captured 0 stones

   A B C D E F G

 

8 quit

=8

命令单行输入,用可选的数字标识起始,后跟命令名和它的参数。

命令成功时返回等号(=)开始,接着是命令的数字标识(如果有的话)和结果。例子中多数结果都是空字符串,只有命令4的返回白着手C3、命令7的返回当前棋盘局面图,其它所有结果是空串。返回串由两个连续的换行结束。

失败的命令由问号”?”代替等号,如命令5的返回。

该协议的详细规格在 http://www.lysator.liu.se/~gunnar/gtp / 。可用的所有命令在GNU GO中以命令list_commands列出。文档参见。

3 协议应用

GTP是非对称协议,包括控制端和引擎两方面。控制端发送命令,引擎响应之。 GNU GO实现了这个协议的引擎端。

随GNU GO源代码一起也发布几个实现了控制端的应用。其中最有趣的一些:

  • regression/regress.awk

回归测试脚本,该脚本向引擎发送GTP 命令设定和评估局面,然后分析引擎的回应。 关于GTP基于回归测试的更多信息参见回归一章(20回归测试)。

  • regression/regress.pl

回归测试的Perl脚本,与CGI 脚本” regression/regress.plx “一起生成回归测试的HTML文件。

  • regression/regress.pike

回归测试的Pike脚本。比 “ regress.awk “更丰富、更有效。

  • regression/view.pike

通过图形棋盘检查单个回归测试项的Pike脚本。提供了一个检查GNU GO内核的简便方法。

  • interface/gtp_examples/twogtp

使两个引擎互相对弈的Perl 脚本。这个脚本实际上为两个引擎设置了棋盘尺寸、让子数和贴目,然后在引擎之间来回传送着手。

  • interface/gtp_examples/twogtp-a

可与twogtp互换的另一Perl脚本。

  • interface/gtp_examples/twogtp.py

twogtp的Python实现脚本。比其Perl实现功能更多。

  • interface/gtp_examples/twogtp.pike

twogtp的pike实现脚本。比Python实现功能更多。

  • interface/gtp_examples/2ptkgo.pl

包括一个图形棋盘的twogtp 变体。

更多GTP 应用列表,包括桥接到围棋服务器和图形用户界面:http://www.lysator.liu.se/~gunnar/gtp / 。

4 Metamachine

GTP 的一个有趣的应用是让GNU GO作为权威,指导其它程序。另一个计算机程序可以请求GNU GO生成后续局面并进行评估。

Santa Cruz的加州大学的David Doshay用基于GNU GO开发的SlugGo并行引擎做过一个有趣的实验。详细描述在http://lists.gnu.org/archive/html/gnugo-devel/2004-08/msg00060.html 。

” Metamachine ” 实验是一个更为普通的尝试,采用GTP与被作为权威使用的GNU GO程序通信。原理如下:

  • 使用GTP top_moves 命令请求GNU GO“权威”生成第一步着手。
  • 尝试双方着手并对当前盘面评分。
  • 选择评分较高局面作为引擎的着手。

该方案不会产生一个更强的引擎,但具有启发性,并且SlugGo实验展示了一个较为精致的方案,沿此路线可能会产生较强的引擎。

两种实现都随同GNU GO发布。都采用fork和pipe系统调用,因此需要一个类Unix环境。Metamachine 已在 GNU/Linux 之下测试。

注意:如果Metamachine 正常终止, GNU GO进程将被杀掉,但总会有出错的可能,所以运行完Metamachine后最好运行ps -A|grep gnugo或ps -aux|grep gnugo确认没有未终止的进程。(如果有, 就杀掉。)

4.1 独立的 Metamachine

“interface/gtp_examples/metamachine.c”是独立实现的Metamachine程序。用cc -o metamachine metamachine.c编译运行。它通过GTP与一个GNUGO进程沟通,并把GNUGO作为权威。

采用以下原理:

stdin pipe a

GTP client —-> Metamachine —–> GNU Go

         <----             <-----

        stdout             pipe b

大多数由client发布的命令通过Metamachine逐个传送给GNU GO。唯一例外是gg_genmove,该命令被截获并转发。Client并不知道这种情况,它只知道发出了一个gg_genmove 命令并收到了回应。因此Metamachine更像一个普通的GTP引擎。

用法:无参数给出标准的GTP行为。metamachine –debug将调试信息发送到stderr 。

4.2 GNU GO 作为Metamachine

另外,也可以使用配置选项 “–enable-metamachine”编译GNU GO 。这编译了包含Metamachine代码的文件oracle.c。除非运行GNU GO时使用了实时选项”–metamachine”,否则这对引擎没有影响。因此需要同时使用编译选项和实时选项获取Metamachine。

这个方法比独立程序好,因为可以使用GNU GO的工具。 例如这样可以用CGoban 或Ascii方式运行Metamachine。

增加命令行”-d0x1000000 “可以进行跟踪。在调试Metamachine时,危险在于编程中的一个小失误就可能导致通信进程和控制器挂起, 彼此都在等待对方的回应。如果这看来发生了,你可以把gdb放入运行过程,察看发生了什么,这很有用。

5 增加新GTP 命令

在GNU GO中GTP的实现分发三个文件,” interface/gtp.h “、” interface/gtp.c “和”interface/play_gtp.c “。前两个实现了一个小的辅助函数库,供其它程序使用。为了推广的需要,以最低的限制条件发放许可(参见A.3 The Go Text Protocol License 部分)。实际的GTP命令在”play_gtp.c”中实现,与引擎内核交互。

来看一个简单而相当典型的命令实现: gtp_countlib() (一个GNUGO的私有扩展命令):

static int

gtp_countlib(char *s)

{

  int i, j;

  if (!gtp_decode_coord(s, &i, &j))

    return gtp_failure("invalid coordinate");

 

  if (BOARD(i, j) == EMPTY)

    return gtp_failure("vertex must not be empty");

 

  return gtp_success("%d", countlib(POS(i, j)));

}

命令参数通过字符串s传递,在这里参数是一个棋盘点,故此调用”gtp.c”的gtp_decode_coord()读取。

一个正确格式化的回应应以”=“或”?”开始,接着是数字标识(如果传递了的话)和实际结果,最后是两个连续的换行符结束。正确地获取这种格式非常重要,因为对端的控制器依赖于它。当然结果本身不能包含两个连续的换行符,但可以用单个换行符分成多行。

假设要格式化的文本没用换行符结束,要生成正确格式化的回应,最容易的方法是使用函数gtp_failure() 和gtp_success()之一。

有时输出会过于复杂不适合使用gtp_success,如我们想打印棋盘点gtp_success()就不支持。这时只有回到构造,如gtp_genmove()

static int

gtp_genmove(char *s)

{

  [...]

  gtp_start_response(GTP_SUCCESS);

  gtp_print_vertex(i, j);

  return gtp_finish_response();

}

这里gtp_start_response()输出写等号和数字标识,gtp_finish_response()增加最后的两个换行符。下个例子来自gtp_list_commands()

static int

gtp_list_commands(char *s)

{

  int k;

  UNUSED(s);

 

  gtp_start_response(GTP_SUCCESS);

 

  for (k = 0; commands[k].name != NULL; k++)

    gtp_printf("%s\n", commands[k].name);

 

  gtp_printf("\n");

  return GTP_OK;

}

刚才说到,回应必须以两个换行符结束。这里我们只好自己来完成回应,因为在循环中最后一个命令已经输出了一个换行符。

为了增加一个新GTP 命令至GNU GO,需要在” play_gtp.c “中插入以下代码片断:

  1. 在第68行开始用DECLARE宏指令声明函数。
  2. 在第200行开始加入commands[]数组。
  3. 操作命令的代码实现。

“gtp.c”/”gtp.h”中有用的辅助函数:

  • gtp_printf() 基本格式打印
  • gtp_mprintf()棋盘点和棋子格式编码打印
  • gtp_success()和gtp_failure() 简单回应
  • gtp_start_response()和gtp_end_response() 较复杂的应答
  • gtp_print_vertex() 和gtp_print_vertices() 打印一个和多个棋盘点
  • gtp_decode_color()从命令参数中读出棋子
  • gtp_decode_coord() 从命令参数中读出棋盘点
  • gtp_decode_move()从命令参数中读出着手,即棋子加棋盘点

6 GTP 命令参考

本节列出GNU GO实现命令及其参考,每个命令入口包括以下的域:

  • Function: 该命令的功能
  • Arguments: 命令需要的其它信息,典型值包括none、vertex、integer等
  • Fails: 导致命令失败的详情
  • Returns: 在=和连续两个换行符间显示的内容,典型值包括nothing、a move coordinate、some status string等。
  • Status: 该命令与标准GTP第2版的关系,如果没有关联则是GNUGO的私有扩展.

细节不再赘述,所列为所有命令(没有特别顺序):

Argument:

N-None

V-Vertex

I-Integer

F-Float

C-Color “black”, “white”, or “empty”

NH- number of handicap stones

LVH-list of vertices with handicap stones

LVH-list of vertices

F-FileName

MN-Move Number

M-move (color + V)

Fails:

N-Never

IL-Illegal

IC-Incorrcect

IV- invalid

IM- illegal move

BNE-board not empty

BOL-Board outside limit

FF-missing filename or failure to open or parse file

EV-empty vertex

OV-occupied vertex

NV-Not Available

SE-stack empty

Returns:

N-Nothing

DSstatus (“alive”, “critical”, “dead”, or “unknown”)

US unconditional status (“undecided”, “alive”, “dead”,”white_territory”, “black_territory”).

ES Status in the form of one of the strings “alive”, “dead”,”seki”, “white_territory”, “black_territory”, or “dame”

着手列表color move (one move per line)

white_influence (float)

black_influence (float)

white_strength (float)

black_strength (float)

white_attenuation (float)

black_attenuation (float)

white_permeability (float)

black_permeability (float)

territory_value (float)

influence_regions (int)

non_territory (int)

The encoding of influence_regions is as follows:

4 white stone

3 white territory

2 white moyo

1 white area

0 neutral

-1 black area

-2 black moyo

-3 black territory

-4 black stone

Worm data formatted like A19:

color black

size 10

effective_size 17.83

origin A19

liberties 8

liberties2 15

liberties3 10

liberties4 8

attack PASS

attack_code 0

lunch B19

defend PASS

defend_code 0

cutstone 2

cutstone2 0

genus 0

inessential 0

B19:

color white

.

.

.

inessential 0

指令表(共125条指令)

NameFunctionArgumentsFailsReturnsStatus
quit退出NNNG2S
protocol_version报告协议版本号.NN协议版本号G2S
name报告程序名称.NN程序名称G2S
version报告程序版本号.NN版本号G2S
boardsize设置路数并清盘IBOLNG2S
equery_boardsiz询问当前棋盘路数NN路数G2S
clear_board清盘面.NNNG2S
orientation设置方向并清盘IILN
query_orientation查询当前方向NN方向
komi设置贴目FICNG2S
get_komi取贴目数NN贴目
black给定节点落黑子VIV/IMNOG1
playwhite给定节点落白子.VIV/IMNOG1
play给定节点给定落子C/VIV/IMNG2S
fixed_handicap设置固定位置让子NHIVLVHG2S
place_free_handicap设置自由位置让子NHIVLVHG2S
set_free_handicap放置自由位置让子LVHBNE/IVNG2S
get_handicap取让子数NNNH
loadsgf打开一个SGF文件至所给的手数或第一手F+MN/V/NVFFCG2S
color返回端点的子色VIVC
list_stones黑子或白子的端点列表CIVLV
countlib计算端点所在串的气数VIV/EV气数
findlib返回端点串的气点列表VIV/EV节点列表
accuratelib检查落子气点列表MIV/OV节点列表
accurate_approxlib检查落子气点列表MIV/OV节点列表
is_legal着手是否合法MIV1/0
all_legal所有合法着法节点列表CIV节点列表
captures返回提子数CIV提子数
last_move上一手的子色端点NNVM
move_history招法历史反序列表NN着手列表
trymove尝试落子MIV/IMN
tryko忽略劫争尝试落子MIV/IM
popgo取消trymove或trykoNSEN
clear_cache清高速缓存NNN
attack试吃一串VIV/EV攻击代码和评分
attack_either试吃两串之一2VIV/EV攻击代码
defend试防守一串VIV/EV防守代码和评分
ladder_attack试征吃一串VIV/EV攻击代码
increase_depths增加深度NNN
decrease_depths减少深度NNN
owl_attack试吃龙VIV/EV攻击代码
owl_defend试防守龙VIV/EV防守代码
owl_threaten_attack试两步吃龙VIV/EV防守代码
owl_threaten_defense试两步防守龙VIV/EV防守代码
owl_does_attack确定指定着法对指定的龙有攻击V,VIV/EV攻击代码
owl_does_defend确定指定着法对指定的龙有防守V,VIV/EV防守代码
owl_connection_defends确定指定着法连接指定的两条龙V,VIV/EV防守代码
defend_both试图防守两串2VIV/EV防守代码
owl_substantial确定是否吃住一串给活龙VIV/EV1/0
analyze_semeai对杀分析D,DIV/EV对杀防守、攻击结果、着手
analyze_semeai_after_move下过一手后的对杀分析C,V,D,DIV对杀防守、攻击结果、着手
tactical_analyze_semeai不使用OWL的对杀分析D,DIV/EV棋块状态
connect试连接两串V, VIV/EV联络结果
disconnect试断开两串V, VIV/EV分断结果
break_in试以串破空V, VsIV/EV结果和评分
block_off试对串守空V, VsIV/EV结果和评分
eval_eye眼空间评价VIV眼最大最小数
dragon_status龙状态OVIV/EVDS、攻击、防守评分
same_dragon确定两子属于同一条龙V, VIV/EV1/0
unconditional_status确定端点状态VIVUS
combination_attack按给定子色寻找通过组合攻击吃住某些子的着法CIV推荐着手
combination_defend如给定子色能通过组合攻击吃住对方,列表对方对此攻击的防守着法CIV推荐着手
aa_confirm_safety运行atari_atari_confirm_safety()M,OIIM成功代码
genmove_black产生并下出认为最好的黑着法NN着手或 “PASS”OG1
genmove_white产生并下出认为最好的白着法NN着手或 “PASS”OG1
genmove以给定子色产生并下出认为最好的着法CIV着手或 “PASS”G2S
reg_genmove以给定子色产生并下出认为最好的着法CIV着手或 “PASS”G2S
gg_genmove以给定子色产生并下出认为最好的着法C,OIIV着手或 “PASS”
restricted_genmove只在给定的端点中选择,并以给定子色产生并下出认为最好的着法C,VsIV着手或 “PASS”
kgs-genmove_cleanup以给定子色产生并下出认为最好的着法,在对手死子未清除前不PASSCIV着手或 “PASS”KGS
level设置棋力IntICN
undo悔一手NIVNG2S
gg-undo悔N手OIIVN
time_settings设时间I,I,IIVNG2S
time_left报告剩余时间C,C,I,IIVNG2S
final_score记谱完成的棋局OINSGF评分G2S
final_status报告下完棋局的端点最终状态V,OIIVES
final_status_list按指定最终状态报告下完棋局的端点列表ES,OIIV节点列表G2S
estimate_score记录评比NN评分上下限
experimental_score重视下一手谁走的估计评分CIV评分
reset_life_node_counter重设活的节点计数NNN
get_life_node_counter取活的节点数NN活节点数
reset_owl_node_counter重设OWL节点计数NNN
get_owl_node_counter取OWL节点数NNOwl节点数
reset_reading_node_counter重设计算节点数NNN
get_reading_node_counter取计算节点数NN识别节点数
reset_trymove_counter重设trymoves/trykos计数NNN
get_trymove_counter取trymoves/trykos计数NNtrymoves/trykos数
reset_connection_node_counter重设连接节点计数NNN
get_connection_node_counter取连接节点计数NN联络节点数
test_eyeshape为矛盾的评估测试眼形VsIV故障保护
analyze_eyegraph对眼图计算眼值和要点SIV眼值
cputime以秒返回共用CPU时间NN
showboard向stdout写盘面NNNG2S
dump_stack向stderr转储堆栈NNN
move_influence落子后返回有关初始的影响函数信息M,InfN影响数据
move_probabilities列出欲下的每着及概率,如前面没有genmove命令,则此命令结果无效NN着手配对
move_uncertainty返回着法的不确定成份NN不确定位
followup_influence返回一着后产生的影响信息M,InfN影响数据
worm_data返回串数据结构中的信息OVN棋串数据
worm_stones列表串的子VEV棋子列表
worm_cutstone返回串数据结构中的cutstone域VN分断子
dragon_data返回龙数据结构中的信息OVN棋块数据
dragon_stones列表龙的子VIV棋子列表
eye_data返回眼数据结构中的信息C,VN眼数据
half_eye_data返回后手眼数据结构中的信息VN后手眼数据
start_sgftrace开始在内存中以SGF树存储计算期的招法NNN
finish_sgftrace完成存储着法的SGF树,并写入文件FNN
printsgf当前局面输出到SGFFMFN
tune_move_ordering调谐局部计算的着法命令参数IsIVN
echo显示参数SNN
echo_err显示参数至stdout及stderrSNN
help列表所支持的命令NN命令列表G2S
known_command报告一条命令是否支持CMDN“true” /”false”G2S
report_uncertainty从from owl_attack and owl_defend调谐不确定报告开或关“on” / “off”IVN
get_random_seed取随机种子NN随机数
set_random_seed设随机种子IIVN
is_surrounded确定龙是否被围VIV/EV0/1/2
does_surround确定一着是否能围住龙V,VIV/EV1
surround_map报告给定端点的龙的包围图V,VIV/EV包围值
set_search_diamond限制搜索,建立搜索菱形PosIVN
reset_search_mask为限定搜索清盘面标志NNN
limit_search设置限定搜索全局变量ValueIVN
set_search_limit为限定搜索标志一个端点PositionIVN
draw_search_area画搜索区,写至stderNNN

作者:

喜欢围棋和编程。

发表评论

邮箱地址不会被公开。