| 1 | #!/usr/bin/env python |
|---|
| 2 | |
|---|
| 3 | try: |
|---|
| 4 | from sgfpars import Node, Cursor, SGFError, SGFescape |
|---|
| 5 | except: |
|---|
| 6 | from sgfparser import Node, Cursor, SGFError, SGFescape |
|---|
| 7 | |
|---|
| 8 | import os, sys, getopt, re |
|---|
| 9 | from sys import stdout |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | def writeheader(rootnode, filename): |
|---|
| 14 | global boardsize |
|---|
| 15 | print 'File', filename |
|---|
| 16 | if (rootnode.has_key('PW')): |
|---|
| 17 | print "White: " + rootnode['PW'][0] |
|---|
| 18 | if (rootnode.has_key('PB')): |
|---|
| 19 | print "Black: " + rootnode['PB'][0] |
|---|
| 20 | if (rootnode.has_key('RE')): |
|---|
| 21 | print "# Result: " + rootnode['RE'][0] |
|---|
| 22 | for el in ['DT', 'EV', 'RO']: |
|---|
| 23 | if (rootnode.has_key(el)): |
|---|
| 24 | print rootnode[el][0] |
|---|
| 25 | print |
|---|
| 26 | |
|---|
| 27 | if (rootnode.has_key('SZ')): |
|---|
| 28 | try: |
|---|
| 29 | boardsize = int(rootnode['SZ'][0]) |
|---|
| 30 | except TypeError: |
|---|
| 31 | print "SGF trouble: Don't understand board size." |
|---|
| 32 | sys.exit(2) |
|---|
| 33 | |
|---|
| 34 | def sgfpos2coord(pos): |
|---|
| 35 | if len(pos) == 0 or pos == 'tt': |
|---|
| 36 | return "PASS" |
|---|
| 37 | elif len(pos) != 2: |
|---|
| 38 | raise SGFError("Couldn't parse coordinate.") |
|---|
| 39 | x, y = ord(pos[0])-ord('a'), ord(pos[1])-ord('a') |
|---|
| 40 | return x, y |
|---|
| 41 | |
|---|
| 42 | |
|---|
| 43 | def writeposition(cursor, color): |
|---|
| 44 | board = [['.' for x in range(0, boardsize)] for y in range(0, boardsize)] |
|---|
| 45 | nodenum = 0 |
|---|
| 46 | while nodenum < movenum and not cursor.atEnd: |
|---|
| 47 | try: |
|---|
| 48 | thisnode = cursor.next() |
|---|
| 49 | except SGFError: |
|---|
| 50 | break |
|---|
| 51 | if thisnode.has_key('AB'): |
|---|
| 52 | for pos in thisnode['AB']: |
|---|
| 53 | x, y = sgfpos2coord(pos) |
|---|
| 54 | board[x][y] = 'X' |
|---|
| 55 | if thisnode.has_key('AW'): |
|---|
| 56 | for pos in thisnode['AW']: |
|---|
| 57 | x, y = sgfpos2coord(pos) |
|---|
| 58 | board[sgfpos2coord(pos)] = 'O' |
|---|
| 59 | if thisnode.has_key('B'): |
|---|
| 60 | x, y = sgfpos2coord(thisnode['B'][0]) |
|---|
| 61 | board[x][y] = 'X' |
|---|
| 62 | elif thisnode.has_key('W'): |
|---|
| 63 | x, y = sgfpos2coord(thisnode['W'][0]) |
|---|
| 64 | board[x][y] = 'O' |
|---|
| 65 | else: |
|---|
| 66 | continue |
|---|
| 67 | nodenum = nodenum + 1 |
|---|
| 68 | |
|---|
| 69 | stdout.write('{{{#!goban\n+') |
|---|
| 70 | for x in range(0, boardsize): |
|---|
| 71 | stdout.write('-') |
|---|
| 72 | print '+' |
|---|
| 73 | for y in range(boardsize-1, -1, -1): |
|---|
| 74 | stdout.write('|') |
|---|
| 75 | for x in range(0, boardsize): |
|---|
| 76 | stdout.write(board[x][-y-1]) |
|---|
| 77 | print '|' |
|---|
| 78 | stdout.write('+') |
|---|
| 79 | for x in range(0, boardsize): |
|---|
| 80 | stdout.write('-') |
|---|
| 81 | print '+\n}}}' |
|---|
| 82 | |
|---|
| 83 | |
|---|
| 84 | # Main Program. |
|---|
| 85 | ############### |
|---|
| 86 | |
|---|
| 87 | help_string = """ |
|---|
| 88 | sgf2gtp.py converts .sgf-files to an ASCII output that is usable for |
|---|
| 89 | GNU Go's trac Wiki. |
|---|
| 90 | Usage: |
|---|
| 91 | sgf2ascii.py --move=<movenum> <file> |
|---|
| 92 | """ |
|---|
| 93 | |
|---|
| 94 | color = [] |
|---|
| 95 | start = 0 |
|---|
| 96 | to = 100000 |
|---|
| 97 | boardsize = 19 |
|---|
| 98 | movenum = 0 |
|---|
| 99 | maxauto = 300 |
|---|
| 100 | |
|---|
| 101 | try: |
|---|
| 102 | opts, args = getopt.getopt(sys.argv[1:], "", |
|---|
| 103 | ["help", "move="]) |
|---|
| 104 | except getopt.GetoptError: |
|---|
| 105 | print "Unrecognized option. Try sgf2gtp.py --help" |
|---|
| 106 | sys.exit(2) |
|---|
| 107 | |
|---|
| 108 | |
|---|
| 109 | for o, a in opts: |
|---|
| 110 | if (o == "--help"): |
|---|
| 111 | print help_string |
|---|
| 112 | sys.exit() |
|---|
| 113 | if (o == "--move"): |
|---|
| 114 | try: |
|---|
| 115 | movenum = int(a) |
|---|
| 116 | except TypeError: |
|---|
| 117 | print "Cannot convert", a, "into a number." |
|---|
| 118 | sys.exit(2) |
|---|
| 119 | |
|---|
| 120 | if not len(args) == 1: |
|---|
| 121 | print "Error: Need exactly one file as argument." |
|---|
| 122 | sys.exit(2) |
|---|
| 123 | |
|---|
| 124 | filename = args[0] |
|---|
| 125 | try: |
|---|
| 126 | file = open(filename) |
|---|
| 127 | sgf = file.read() |
|---|
| 128 | file.close() |
|---|
| 129 | cursor = Cursor(sgf, 1) |
|---|
| 130 | rootnode = cursor.getRootNode(0) |
|---|
| 131 | except IOError: |
|---|
| 132 | print "Couldn't read file %s." % filename |
|---|
| 133 | sys.exit(2) |
|---|
| 134 | except SGFError, message: |
|---|
| 135 | print "Couldn't parse SGF in file %s: %s" % (filename, message) |
|---|
| 136 | sys.exit(2) |
|---|
| 137 | |
|---|
| 138 | |
|---|
| 139 | writeheader(rootnode, filename) |
|---|
| 140 | writeposition(cursor, color) |
|---|