Skip to content

Instantly share code, notes, and snippets.

@fogleman
Created March 21, 2016 01:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fogleman/7d647ef583ffad7bc919 to your computer and use it in GitHub Desktop.
Save fogleman/7d647ef583ffad7bc919 to your computer and use it in GitHub Desktop.
SGF Parser & Board State for Go / Baduk
import sys
class Board(object):
def __init__(self, size):
self.size = size
self.grid = {}
def move(self, color, x, y):
self.set(color, x, y)
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
nx = x + dx
ny = y + dy
cell = self.get(nx, ny)
if cell and cell != color:
group, liberties = self.group(nx, ny)
if liberties == 0:
self.remove_group(group)
def get(self, x, y):
return self.grid.get((x, y))
def set(self, color, x, y):
self.grid[(x, y)] = color
def remove_group(self, group):
for x, y in group:
self.grid.pop((x, y))
def group(self, x, y):
color = self.get(x, y)
if not color:
return []
result = set()
perimeter = {}
self._group(x, y, color, result, perimeter)
liberties = perimeter.values().count(None)
return sorted(result), liberties
def _group(self, x, y, color, result, perimeter):
if x < 0 or y < 0 or x >= self.size or y >= self.size:
return
if (x, y) in result:
return
cell = self.get(x, y)
if cell != color:
perimeter[(x, y)] = cell
return
result.add((x, y))
self._group(x - 1, y, color, result, perimeter)
self._group(x + 1, y, color, result, perimeter)
self._group(x, y - 1, color, result, perimeter)
self._group(x, y + 1, color, result, perimeter)
def __str__(self):
rows = []
for y in range(self.size):
row = []
for x in range(self.size):
row.append(self.get(x, y) or '.')
rows.append(' '.join(row))
return '\n'.join(rows)
def parse(filename):
result = []
with open(filename) as fp:
for line in fp:
line = line.strip()
if line.startswith(';B') or line.startswith(';W'):
color = line[1]
x = ord(line[3]) - ord('a')
y = ord(line[4]) - ord('a')
result.append((color, x, y))
return result
def main():
moves = parse(sys.argv[1])
board = Board(19)
for i, (color, x, y) in enumerate(moves):
board.move(color, x, y)
black = [k for k, v in board.grid.items() if v == 'B']
white = [k for k, v in board.grid.items() if v == 'W']
print board
print black
print white
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment