7 from sgflib
import SGFParser
11 parser
= argparse
.ArgumentParser(description
="""
12 This script converts SGF files to GTP format so that you can feed them
13 to Pachi, insert genmove at the right places etc. Might not work on
16 When called with FILENAMES argument, it will create according output files
17 with .gtp extension instead of .sgf, unless --no-gtp option is specified.
20 parser
.add_argument('FILENAMES', help='List of sgf games.', nargs
='*', default
=[])
21 parser
.add_argument('-g', help='Automatically append genmove command for the other color.', action
='store_true')
22 parser
.add_argument('-n', help='Output at most first MOVENUM moves.', metavar
='MOVENUM', type=int, default
=10**10)
23 parser
.add_argument('--no-gtp', help='Do not create the .gtp files.', action
='store_true')
24 args
= vars(parser
.parse_args())
26 class UnknownNode(Exception):
29 def get_atr(node
, atr
):
31 return node
.data
[atr
].data
[0]
35 def col2num(column
, board_size
):
36 a
, o
, z
= map(ord, ['a', column
, 'z'])
38 return a
+ board_size
- o
39 raise Exception( "Wrong column character: '%s'"%(column
,) )
41 def is_pass_move(coord
, board_size
):
42 # the pass move is represented either by [] ( = empty coord )
43 # OR by [tt] (for boards <= 19 only)
44 return len(coord
) == 0 or ( board_size
<= 19 and coord
== 'tt' )
46 def process_gametree(gametree
, fout
):
47 # cursor for tree traversal
49 # first node is the header
52 handicap
= get_atr(header
, 'HA')
53 board_size
= int(get_atr(header
, 'SZ'))
54 komi
= get_atr(header
, 'KM')
55 player_next
, player_other
= "B", "W"
57 print >>fout
, "boardsize", board_size
58 print >>fout
, "clear_board"
60 print >>fout
, "komi", komi
61 if handicap
and handicap
!= '0':
62 print >>fout
, "fixed_handicap", handicap
63 player_next
, player_other
= player_other
, player_next
65 def print_game_step(coord
):
66 if is_pass_move(coord
, board_size
):
67 print >>fout
, "play", player_next
, "pass"
70 # The reason for this incredibly weird thing is that
71 # the GTP protocol excludes `i` in the coordinates
72 # (do you see any purpose in this??)
75 y
= str(col2num(y
, board_size
))
76 print >>fout
, "play", player_next
, x
+y
79 # walk the game tree forward
81 # sgf2gtp.pl ignores n = 0
82 if c
.atEnd
or (args
['n'] and movenum
>= args
['n']):
87 coord
= get_atr(c
.node
, player_next
)
89 print_game_step(coord
)
91 # MAYBE white started?
92 # or one of the players plays two time in a row
93 player_next
, player_other
= player_other
, player_next
94 coord
= get_atr(c
.node
, player_next
)
96 print_game_step(coord
)
98 # TODO handle weird sgf files better
101 player_next
, player_other
= player_other
, player_next
104 print >>fout
, "genmove", player_next
106 def process_sgf_file(fin
, fout
):
108 col
= SGFParser(sgfdata
).parse()
112 process_gametree(gametree
, fout
)
114 # Try next game tree in this file
116 print >>sys
.stderr
, "Unknown Node"
119 if __name__
== "__main__":
120 if not len(args
['FILENAMES']):
121 process_sgf_file(sys
.stdin
, sys
.stdout
)
123 for in_filename
in args
['FILENAMES']:
127 if re
.search('sgf$', in_filename
):
128 filename_base
= in_filename
[:-3]
130 filename_base
= in_filename
132 out_filename
= filename_base
+ 'gtp'
134 fout
= open(out_filename
, 'w')
136 fin
= open(in_filename
, 'r')
138 process_sgf_file(fin
, fout
)
141 if not args
['no_gtp']: