#!/usr/bin/env python import sys import os import re # give up in despair on errors def die(message, *args): if args: sys.stderr.write("%s\n" % (message % tuple(args),)) else: sys.stderr.write("%s\n", message) sys.exit(1) # given an .sgf file name, the path to the file and the os file separator # Might be '\' on Windows), scan the file reconstructing the board for each # move in the file and counting doubles thrown, and usable doubles for # both players # outut begins with a line beginnin ## file-name # for each game in a match, outputs one line of statistics for the winner # of the game. # col 1 - doubles for the winner minus doubles for the loser # col 2 - as above, but only usable doubles # col 3 - total doubles for the winner # col 4 - total usable doubles for te winner # col 5 - total doubles for the loser # col 6 - total usable doubles for te loser # # at the end of the match, prints the same statistics for winner and loser # totalled over the whole match. This line begins with a '#' def scan_file(fn): game = -1 match_tots = [] game_tots = [] # regex to find start of a game within a match r_sog = re.compile(r'^\(;FF.*RE\[(.).*\].*') # regex to identify a roll of a double. Returns two match items # the player ('W' or 'B') and the .sgf annotation of what move was # made, if any. Only matches rolls of a double r_dbl = re.compile(r';([BW])\[((?:11|22|33|44|55|66)[^]]*)\]') # identify the file being processed print '## ', fn f = open(fn, "r") # initialise match totals (m_dbl_w, m_use_w, m_dbl_b, m_use_b) = (0, 0, 0, 0) # scan the file, reading lines and looking for the start of a gam while True: l = f.readline() if not l: break l = l.rstrip(); r = r_sog.match(l) if r: # start of a game. Report results of the previous game # (unless this is the first game in the match) if game >= 0: if winner == 'W': print "%4d %4d %4d %4d %4d %4d" % ( dbl_w - dbl_b, use_w - use_b, dbl_w, use_w, dbl_b, use_b) else: print "%4d %4d %4d %4d %4d %4d" % ( dbl_b - dbl_w, use_b - use_w, dbl_b, use_b, dbl_w, use_w) m_dbl_w += dbl_w m_use_w += dbl_w m_dbl_b += dbl_b m_use_b += dbl_b # come here for start of all games, including first # intialise game totals (dbl_w, use_w, dbl_b, use_b) = (0, 0, 0, 0) game += 1 winner = r.groups()[0] continue # not start of game, simply process the move r = r_dbl.match(l) # we return to the while if the move wasn't a rolled double if r: plyr = r.groups()[0] ################################## # CHANGE THIS TO DEFINE USABLE DOUBLES # 0 = the player could use at least one value of the dice # 2 = " two " # 4 = " three " # 6 = " all four values of the dice ################################## usable = len(r.groups()[1]) > 2 if plyr == 'B': dbl_b += 1 m_dbl_b += 1 if usable: use_b += 1 m_use_b += 1 else: dbl_w += 1 m_dbl_w += 1 if usable: use_w += 1 m_use_w += 1 # reached end of file, add in stats of last game if winner == 'W': print "%4d %4d %4d %4d %4d %4d" % ( dbl_w - dbl_b, use_w - use_b, dbl_w, use_w, dbl_b, use_b) else: print "%4d %4d %4d %4d %4d %4d" % ( dbl_b - dbl_w, use_b - use_w, dbl_b, use_b, dbl_w, use_w) # by definition, winner of last game is winner of match, so if winner == 'W': print "# %4d %4d %4d %4d %4d %4d" % ( m_dbl_w - m_dbl_b, m_use_w - m_use_b, m_dbl_w, m_use_w, m_dbl_b, m_use_b) else: print "# %4d %4d %4d %4d %4d %4d" % ( m_dbl_b - m_dbl_w, m_use_b - m_use_w, m_dbl_b, m_use_b, m_dbl_w, m_use_w) f.close() def main(): if len(sys.argv) != 2: sys.stderr.write("invoke with path to direcotry with .sgf files\n") sys.exit(1) # get a list of files in .sgf directory sgf_path = sys.argv[1] flist = os.listdir(sgf_path) # and process any .sgf files found for f in flist: (name, ext) = os.path.splitext(f) if ext != '.sgf': continue scan_file("%s%s%s" % (sgf_path, os.sep, f)) main()