[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[computer-go] Implementing and using GTP (in windows)
Here is my experience of using GTP in windows. It is long and perhaps not so well structured but I hope it might help anyone who knows as litlle as I did before I started gtp. I like gtp. But until you get your first command through it can be hours of agonizing pain with no reinforcing rewards. In the end you get so much things for free so you will not regret it. Automatic play and reports against any gtp program you can run on you computer (and in theory any computer on the network). Automatic testing scripts with reports and 100´s of test available. The possibility to connect to KGS and meet in the computer go room and discuss things live with interested players and programmers.
*Windows vs Unix*
Contrary to popular belief Windows does have pipes, redirection, commandline parameters and stuff like that just as UNIX has. The problem is that Windows programs do not use these features, and documentation is not easy to find. If you type "cmd" after clicking Run in the Start-Menu you will get a console which will work as Unix do. Most commands are different but < > | which is used in Unix can be used here as well.
I implemented GTP in order to use KGSgtp which is a controller that connects a go program to the KGS go server. This is something I really do recommend. My program has for example been online for a week straight now and has played 100's of rated games.
What do you need to do? To connect with GTP. I did not try pigeons but I have implemented the communication in three different ways using a) standard input/output, b) named pipes, and c) TCP/IP.
Was it easy? No. Is it easy if you know how to do it? Yes.
Since I never communicated between programs before I had to learn all these things from scratch.
I program in Object Pascal (which by the way is the ideal language for go programming (for me :-) )) using Delphi 5 Std.
My problems initally come from that it seems as if Delphi assumes by default that standard input/output should not be used. The way to do it is to call the windows API directly and avoid the Delphi libraries. THe problem with this is that not only does windows have pipes for example but you also get complete control of almost everything involved and you have to read a lot before you find some good functions to use, understand what they do, and which parameters you should use. Some commands take up to 10 parameters and but if you are lucky you can use nil-values for most of them.
If your programming environment/language has standard input output implemented then use it. If you are on windows you need a controller.
My choice is GoGui which is a java program. Included with GoGui is also a bunch of othere programs that are really nice to have. My general advice is:
Download gogui (if you (like me) are not used to java and starting java programs from the command line sounds exotic you might have a hard time doing that too but this is another story).
For example when I want to play a match between my program and gnugo I use the java program twogtp. I have the following line in .bat fil:
java -jar twoGtp.jar -black "..\..\Viking\KGSClient\vikinggtp.exe nosgfdb console time 20 rand 42" -white "gnugo.exe --mode gtp" -size 9 -auto -sgffile s9\g -games 500 -alternate
THis will play up to 500 games on 9x9 and save the sgf's in the directory s9 as g-1.sgf, g-2-sgf, ... It also generates some summary files with statistics from the games. This is great! This is the only quick and reliable way I know of to measure if a program become better or not. Although relative one program you could also do this against for example Aya which uses GTP as well and not only gnugo.
Included with GoGui is also gtpregress which can be used for scripted tests
the .bat looks as:
java -jar gtpregress.jar "..\..\..\Viking\KGSClient\vikinggtp.exe nosgfdb console verbose time 10 rand 42 cgtclog" *.tst
and when this program is run my program is started and asked to load 542 different positions and generate a move for each postion. THe ouput is a bunche of html-files integrated by a single index.html where you get statistics for each .tst file included (it is easy to make your own tests which I will start doing from now on), and can see where your program made a mistake or not.
The only trouble with gtpregress is that your program has to be able to read complicated sgf-files that setup positions by adding black and white stones in the root node. If your program only can read vanilla games, then you can still use it if you do your own tests. (I never made a real sgf-parser. I just added more and more code too a simple hack each time I had to read an sgf it could not parse... dont do that...).
---
What you have to do to use GTP:
First if you can get gogui to start your program and read the first string that gogui send to your program from standard input, then you are almost done.
The problem might be that you might not be able to debug your program in a debugger as usual doing this. THus you might invest some time in a good logfile system. (Another idea might be to use TCP/IP and use the gtpadapter program between your program and GOGUi or any other gtp program. I have not tried that.)
The second part is to implement the parsing of gtp-commands. I do it quick and dirty. It works and I am happy. Look out for the newline problem! Read the gtpspecification carefully. When you send text back to GOGui you need to add some extra stuff in the end of each line according to the protocol. Some GTP programs are picky about this. (GoGUi complains about at least one way of doing it more or less wrong). Different programming languages and operating systems has different problems. My solution in windows is to use WriteFile() which is a lowlevel function where you set up a buffer of bytes to send and get complete control.
Here is the beginning of the main loop
It reads a string s using a ReadFunc which is a procedural variable depending
on how the program is connected. All the complexity of connecting is not seen here.
----
while not FAbort do
begin
s := ReadFunc;
if (s <> '') then
begin
-----
The parsing is done by first removing some GTP junk I do not find useful,
but you have to do it. There some line numbers you have to remove and the reuse in the response. THis is in the variable Id.
Other than that you can simply search for commands in s and do whatever you need to do.
Here are the code for Undo which is simple as it can get (if your program can do it...) and Play which one of the more complex commands.
I wrote an GTP interface for my program that translates coordinates and stuff like that, so this code only keeps track which substring goes where.
-----
else
if StrSearch('undo', s) > 0 then
begin
// UNDO
if not Assigned(viking) then
SendError('no game to play in', id)
else
begin
viking.GTP_Undo;
SendEnd('', id);
end;
end
else
if StrSearch('play', s) > 0 then
begin
// PLAY
StrToStrings(s, ' ', strings);
if strings.Count < 2 then
SendError('', id)
else
if not Assigned(viking) then
SendError('no game to play in', id)
else
if strings.Count = 3 then
begin
if Trim(strings[2]) = 'pass' then
begin
viking.GTP_Pass;
SendEnd('', id);
end
else
begin
viking.GTP_Play(Trim(strings[1]), Trim(strings[2]), FGameSize);
Inc(Fmovenum);
SendEnd('', id);
end;
end
else
SendError('', id);
end
else
----
If you implement the commands used by kgsGTP you have almost everything you need.
Smartgo need undo and it is an alternative to gogui in some ways.
gtpregress needs that your program can load (relatively complex) sgf files.
I hope this will be useful!
Best wishes
Magnus
_______________________________________________
computer-go mailing list
computer-go@xxxxxxxxxxxxxxxxx
http://www.computer-go.org/mailman/listinfo/computer-go/