From b960104fbe44f1cbae007c9967e1ce70dc153aa1 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 1 Dec 2016 16:28:43 +0100 Subject: Initial import --- tsumego | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100755 tsumego diff --git a/tsumego b/tsumego new file mode 100755 index 0000000..9b92aa0 --- /dev/null +++ b/tsumego @@ -0,0 +1,293 @@ +#!/usr/bin/env python3 + +import sys +import sgf +import string +from random import randint + +class Board: + + board = {} + xs = 0 + xe = 19 + ys = 0 + ye = 19 + to_play = "B" + finished = False + + def to_move(self): + if self.to_play == "B": + return "◯" + return "⬤" + + def board_symbol(self, x, y): + if x+y in self.board: + if self.board[x+y] == "W": + if x=="a": + return " ⬤ " + else: + return "─⬤ " + if self.board[x+y] == "B": + if x=="a": + return " ◯ " + else: + return "─◯ " + if (y=="d") or (y=="p") or (y=="j"): + if (x=="d") or (x=="p") or (x=="j"): + return "─*─" + if (x=="a"): + if (y=="s"): + return " └─" + if (y=="a"): + return " ┌─" + return " ├─" + if (x=="s"): + if (y=="s"): + return "─┘ " + if (y=="a"): + return "─┐ " + return "─┤ " + if (y=="s"): + return "─┴─" + if (y=="a"): + return "─┬─" + return "─┼─" + + def l2n(self,l): + return str(string.ascii_lowercase[0:19].index(l)+1) + + def n2l(self,n): + return string.ascii_lowercase[n-1] + + def check_liberties(self,x,y,c,checked): + k = self.n2l(x)+self.n2l(y) + if k in checked: + return 0 + checked.append(k) + if not k in self.board: + return 1 + if self.board[k] == c: + return self.liberties(x, y, c, checked) + return 0 + + def liberties(self,x,y,c,checked): + lib = 0 + if x > 1: + lib += self.check_liberties(x-1, y, c, checked) + if y > 1: + lib += self.check_liberties(x, y-1, c, checked) + if x < 19: + lib += self.check_liberties(x+1, y, c, checked) + if y < 19: + lib += self.check_liberties(x, y+1, c, checked) + return lib + + def process_captures(self,c): + captured = [] + for x in range(1,20): + for y in range(1,20): + k = self.n2l(x)+self.n2l(y) + if not k in self.board: + continue + if self.board[k] == c: + if self.liberties(x,y,c,[]) == 0: + captured.append(k) + for capture in captured: + del self.board[capture] + + def add_node(self,node): + for key in node.properties.keys(): + val = node.properties[key] + if key == "AB": + for pos in val: + self.board[pos] = "B" + if key == "AW": + for pos in val: + self.board[pos] = "W" + if key == "B": + for pos in val: + self.board[pos] = "B" + self.process_captures("W") + self.to_play = "W" + if key == "W": + for pos in val: + self.board[pos] = "W" + self.process_captures("B") + self.to_play = "B" + if key == "PL": + if val[0] == "1" or val[0] == "b" or val[0] == "B": + self.to_play = "B" + if val[0] == "2" or val[0] == "w" or val[0] == "W": + self.to_play = "W" + if key == "C": + print("---> "+val[0]) + if not node.variations: + self.current_node = node.next + if not node.next: + self.finished = True + else: + i = randint(0,len(node.variations)-1) + self.current_node = node.variations[i] + + def is_move(self,node): + for key in node.properties.keys(): + val = node.properties[key] + if key == "B" or key == "W": + return True + return False + + def add_next(self,nmoves): + nm = 0 + if nmoves == 0: + while self.is_move(self.current_node.next): + self.add_node(self.current_node) + return + while 1: + if not self.current_node: + print("Finished!") + break + if self.is_move(self.current_node): + if nm == nmoves: + return + nm += 1 + self.add_node(self.current_node) + + def __init__(self,root): + self.current_node = root + + def set_node(self,root): + self.current_node = root + + def fit_board(self): + self.ys = 0 + self.ye = 19 + self.xs = 0 + self.xe = 19 + + for y in string.ascii_lowercase[0:18]: + blank = 1 + for x in string.ascii_lowercase[0:18]: + if x+y in self.board: + blank = 0 + break + if not blank: + break + self.ys += 1 + + for y in string.ascii_lowercase[18:0:-1]: + blank = 1 + for x in string.ascii_lowercase[0:18]: + if x+y in self.board: + blank = 0 + break + if not blank: + break + self.ye -= 1 + + for x in string.ascii_lowercase[0:18]: + blank = 1 + for y in string.ascii_lowercase[0:18]: + if x+y in self.board: + blank = 0 + break + if not blank: + break + self.xs += 1 + + for x in string.ascii_lowercase[18:0:-1]: + blank = 1 + for y in string.ascii_lowercase[0:18]: + if x+y in self.board: + blank = 0 + break + if not blank: + break + self.xe -= 1 + + if self.xs > 0: + self.xs -= 1 + if self.ys > 0: + self.ys -= 1 + if self.xe < 19: + self.xe += 1 + if self.ye < 19: + self.ye += 1 + + def header(self): + print(" ",end="") + for x in string.ascii_lowercase[self.xs:self.xe]: + print(x+" ",end="") + print("") + + def show(self): + self.header() + for y in string.ascii_lowercase[self.ys:self.ye]: + print(self.l2n(y).rjust(3)+" ",end="") + for x in string.ascii_lowercase[self.xs:self.xe]: + print(self.board_symbol(x,y),end="") + print(" "+self.l2n(y)) + self.header() + + def find_variation(self,move): + + print("Looking for ",move) + print(self.current_node.properties) + + # Is it just the next move? + if self.current_node.properties[self.to_play][0] == move: + return self.current_node + + # Is it in one of the variations? + for var in self.current_node.variations: + print("Checking ",var.properties) + if not self.to_play in var.properties: + print("No move in this variation!") + print(var.properties) + if var.properties[self.to_play][0] == move: + return var + + +def n2l(n): + return string.ascii_lowercase[n-1] + + +def coord_to_sgf(a): + n2 = ''.join([i for i in a if i.isdigit()]) + if not n2: + return + numbers = int(n2) + letters = ''.join([i for i in a if not i.isdigit()]) + if not letters: + return + return letters+n2l(numbers) + +if len(sys.argv) < 2: + fn = "/home/taw/tmp/tsumego/qjzm-a.sgf" +else: + fn = sys.argv[1] + +with open(fn) as f: + c = sgf.parse(f.read()) + +i=randint(0,len(c.children)-1) + +puzzle = c.children[i] +board = Board(puzzle.root) +board.add_next(0) +board.fit_board() +board.show() +print(board.to_move()+" to move.") + +while not board.finished: + + ans = input("-> ") + move = coord_to_sgf(ans) + + var = board.find_variation(move) + if not var: + print("Incorrect.") + exit(0) + + board.set_node(var) + board.add_next(2) + board.show() -- cgit v1.2.3