Added go borad simulator to remove dead stones.
This commit is contained in:
@@ -5,3 +5,4 @@
|
|||||||
*.log
|
*.log
|
||||||
*.ps
|
*.ps
|
||||||
*.pdf
|
*.pdf
|
||||||
|
__pycache__/
|
||||||
|
|||||||
+23
-35
@@ -3,6 +3,9 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from subprocess import check_call, DEVNULL, STDOUT, CalledProcessError
|
from subprocess import check_call, DEVNULL, STDOUT, CalledProcessError
|
||||||
from shutil import copyfile, rmtree
|
from shutil import copyfile, rmtree
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
import simpleGoBoard
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Convert sgf go records into a kifu format.')
|
parser = argparse.ArgumentParser(description='Convert sgf go records into a kifu format.')
|
||||||
|
|
||||||
@@ -26,6 +29,8 @@ header = sgfData[0]
|
|||||||
moves = sgfData[1:]
|
moves = sgfData[1:]
|
||||||
|
|
||||||
def format_date(date):
|
def format_date(date):
|
||||||
|
if date == "":
|
||||||
|
return ""
|
||||||
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
||||||
ds = date.split("-") # year month day
|
ds = date.split("-") # year month day
|
||||||
ds.reverse()
|
ds.reverse()
|
||||||
@@ -67,45 +72,28 @@ def generate_title():
|
|||||||
|
|
||||||
return "".join(out)
|
return "".join(out)
|
||||||
|
|
||||||
def generate_moves():
|
|
||||||
finished = False
|
def init_simpleGoBoard():
|
||||||
|
for move in moves:
|
||||||
|
if len(move) == 5:
|
||||||
|
coordinates = (ord(move[2].lower())-ord("a")+1, parsedHeader["boardSize"]-ord(move[3].lower())+ord("a"))
|
||||||
|
if move[0].lower() == "w":
|
||||||
|
simpleGoBoard.whiteMoves.append(coordinates)
|
||||||
|
elif move[0].lower() == "b":
|
||||||
|
simpleGoBoard.blackMoves.append(coordinates)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_boards():
|
||||||
|
init_simpleGoBoard()
|
||||||
outText = []
|
outText = []
|
||||||
for i in range(len(splitBoardAt)-1):
|
for i in range(len(splitBoardAt)-1):
|
||||||
currentSplit = splitBoardAt[i]
|
currentSplit = splitBoardAt[i]
|
||||||
nextSplit = splitBoardAt[i+1]
|
nextSplit = splitBoardAt[i+1]
|
||||||
|
|
||||||
outText.append("\\begin{psgoboard}\n\t")
|
board, finished = simpleGoBoard.produce_latex(currentSplit, nextSplit, args.cn)
|
||||||
|
outText.extend(board)
|
||||||
# old moves
|
|
||||||
for j in range(currentSplit):
|
|
||||||
firstCoordinate, secondCoordinate = extract_coordinates(moves[j])
|
|
||||||
if not (firstCoordinate == -1 or secondCoordinate == -1):
|
|
||||||
outText.append(f"\\move*{{{firstCoordinate}}}{{{secondCoordinate}}} ")
|
|
||||||
if j % 5 == 4:
|
|
||||||
outText.append("\n\t")
|
|
||||||
elif secondCoordinate < 10: # nice spacing
|
|
||||||
outText.append(" ")
|
|
||||||
|
|
||||||
# new moves
|
|
||||||
for j in range(nextSplit-currentSplit):
|
|
||||||
firstCoordinate, secondCoordinate = extract_coordinates(moves[currentSplit+j])
|
|
||||||
if not (firstCoordinate == -1 or secondCoordinate == -1):
|
|
||||||
outText.append(f"\\move{{{firstCoordinate}}}{{{secondCoordinate}}} ")
|
|
||||||
if j % 5 == 4:
|
|
||||||
outText.append("\n\t")
|
|
||||||
elif secondCoordinate < 10: # nice spacing
|
|
||||||
outText.append(" ")
|
|
||||||
|
|
||||||
# was it the last move?
|
|
||||||
if currentSplit+j == len(moves)-1:
|
|
||||||
finished = True
|
|
||||||
break
|
|
||||||
|
|
||||||
outText.append("\n\\end{psgoboard}\n")
|
|
||||||
if finished:
|
if finished:
|
||||||
break
|
break
|
||||||
elif not args.cn:
|
|
||||||
outText.append("\n\\setcounter{gomove}{0}\n")
|
|
||||||
|
|
||||||
return "".join(outText)
|
return "".join(outText)
|
||||||
|
|
||||||
@@ -135,7 +123,7 @@ if parsedHeader["rankBlack"] != "":
|
|||||||
playerBlack += f" ({parsedHeader['rankBlack']})"
|
playerBlack += f" ({parsedHeader['rankBlack']})"
|
||||||
if parsedHeader["rankWhite"] != "":
|
if parsedHeader["rankWhite"] != "":
|
||||||
playerWhite += f" ({parsedHeader['rankWhite']})"
|
playerWhite += f" ({parsedHeader['rankWhite']})"
|
||||||
moves = generate_moves()
|
boards = generate_boards()
|
||||||
|
|
||||||
outText = f"""
|
outText = f"""
|
||||||
\\documentclass[a4paper]{{article}}
|
\\documentclass[a4paper]{{article}}
|
||||||
@@ -167,7 +155,7 @@ outText = f"""
|
|||||||
\\end{{tabularx}}
|
\\end{{tabularx}}
|
||||||
\\vspace{{3cm}}
|
\\vspace{{3cm}}
|
||||||
|
|
||||||
{moves}
|
{boards}
|
||||||
|
|
||||||
\\end{{center}}
|
\\end{{center}}
|
||||||
\\end{{document}}
|
\\end{{document}}
|
||||||
@@ -195,4 +183,4 @@ if not args.t:
|
|||||||
rmtree(f"{fileBase}/")
|
rmtree(f"{fileBase}/")
|
||||||
# hould output be opened?
|
# hould output be opened?
|
||||||
if args.o:
|
if args.o:
|
||||||
os.system(f'"{fileBase}.pdf"')
|
os.startfile(f'"{fileBase}.pdf"')
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 132 KiB |
@@ -0,0 +1,216 @@
|
|||||||
|
import itertools
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
blackMoves = []
|
||||||
|
whiteMoves = []
|
||||||
|
boardSize = 19
|
||||||
|
|
||||||
|
board = []
|
||||||
|
blackGroups = []
|
||||||
|
whiteGroups = []
|
||||||
|
|
||||||
|
def get_neighbouring_coordinates(point):
|
||||||
|
neighbours = []
|
||||||
|
potentialNeighbours = [
|
||||||
|
(point[0]-1,point[1]),
|
||||||
|
(point[0]+1,point[1]),
|
||||||
|
(point[0],point[1]-1),
|
||||||
|
(point[0],point[1]+1)
|
||||||
|
]
|
||||||
|
|
||||||
|
for point in potentialNeighbours:
|
||||||
|
if 1 <= point[0] <= 19 and 1 <= point[1] <= 19:
|
||||||
|
neighbours.append(point)
|
||||||
|
|
||||||
|
return neighbours
|
||||||
|
|
||||||
|
def get_neighbouring_groups(position, color):
|
||||||
|
groups = whiteGroups if color == "w" else blackGroups
|
||||||
|
|
||||||
|
neighbouringGroups = set()
|
||||||
|
neighbours = get_neighbouring_coordinates(position)
|
||||||
|
|
||||||
|
for point in neighbours:
|
||||||
|
for index, group in enumerate(groups):
|
||||||
|
if point in group:
|
||||||
|
neighbouringGroups.add(index)
|
||||||
|
|
||||||
|
return list(neighbouringGroups)
|
||||||
|
|
||||||
|
|
||||||
|
def get_liberties(group):
|
||||||
|
ret = set()
|
||||||
|
for point in group:
|
||||||
|
neighbours = get_neighbouring_coordinates(point)
|
||||||
|
for neighbour in neighbours:
|
||||||
|
if board[neighbour[0]-1][neighbour[1]-1] == "":
|
||||||
|
ret.add(neighbour)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def remove_dead_groups(color):
|
||||||
|
bothGroups = []
|
||||||
|
|
||||||
|
# get the order right so that black can kill a white
|
||||||
|
# group by playing into whites only eye (and not killing himself first)
|
||||||
|
if color == "w":
|
||||||
|
bothGroups = whiteGroups + blackGroups
|
||||||
|
else:
|
||||||
|
bothGroups = blackGroups + whiteGroups
|
||||||
|
|
||||||
|
# remove dead from board
|
||||||
|
for group in bothGroups:
|
||||||
|
if len(get_liberties(group)) == 0:
|
||||||
|
for pos in group:
|
||||||
|
board[pos[0]-1][pos[1]-1] = ""
|
||||||
|
|
||||||
|
# remove dead from groups lists
|
||||||
|
whiteGroups[:] = [ group for group in whiteGroups if len(get_liberties(group)) != 0 ]
|
||||||
|
blackGroups[:] = [ group for group in blackGroups if len(get_liberties(group)) != 0 ]
|
||||||
|
|
||||||
|
def play_move(color, move):
|
||||||
|
playerGroups = whiteGroups if color == "w" else blackGroups
|
||||||
|
|
||||||
|
neighbouringGroups = get_neighbouring_groups(move, color)
|
||||||
|
|
||||||
|
# no neighbouring groups make new one
|
||||||
|
if len(neighbouringGroups) == 0:
|
||||||
|
playerGroups.append([(move[0], move[1])])
|
||||||
|
else:
|
||||||
|
# we want to merge everything into the first group and then pop the others in
|
||||||
|
# reverse index order so no indecies are getting wrong
|
||||||
|
neighbouringGroups.sort()
|
||||||
|
neighbouringGroups[1:] = neighbouringGroups[1:][::-1]
|
||||||
|
|
||||||
|
# 1 or more neighbouring groups -> extend first one
|
||||||
|
playerGroups[neighbouringGroups[0]].append((move[0], move[1]))
|
||||||
|
|
||||||
|
# if also more than one group -> merge with others
|
||||||
|
for i, group in enumerate(neighbouringGroups[1:]):
|
||||||
|
playerGroups[neighbouringGroups[0]].extend(playerGroups.pop(group))
|
||||||
|
|
||||||
|
board[move[0]-1][move[1]-1] = color
|
||||||
|
remove_dead_groups("w" if color == "b" else "b")
|
||||||
|
|
||||||
|
|
||||||
|
def simulate_board_up_to(lastMoveNumber):
|
||||||
|
global board
|
||||||
|
global whiteGroups
|
||||||
|
global blackGroups
|
||||||
|
|
||||||
|
# reset board and groups
|
||||||
|
blackGroups = []
|
||||||
|
whiteGroups = []
|
||||||
|
board = [ [ "" for i in range(boardSize) ] for y in range(boardSize) ]
|
||||||
|
moveSequence = [ j for i in itertools.zip_longest(blackMoves,whiteMoves) for j in i ]
|
||||||
|
|
||||||
|
for i in range(len(blackMoves) + len(whiteMoves)):
|
||||||
|
if i == lastMoveNumber:
|
||||||
|
break
|
||||||
|
|
||||||
|
# blacks turn
|
||||||
|
if i % 2 == 0:
|
||||||
|
if len(blackMoves) == 0: continue
|
||||||
|
play_move("b", blackMoves[i//2])
|
||||||
|
else:
|
||||||
|
if len(whiteMoves) == 0: continue
|
||||||
|
play_move("w", whiteMoves[i//2])
|
||||||
|
|
||||||
|
|
||||||
|
def show_board():
|
||||||
|
print(" "*3 + "A B C D E F G H J K L M N O P Q R S T")
|
||||||
|
i = 0
|
||||||
|
for y in range(boardSize):
|
||||||
|
i += 1
|
||||||
|
if boardSize-i+1 < 10:
|
||||||
|
print(f" {boardSize-i+1}", end="")
|
||||||
|
else:
|
||||||
|
print(f"{boardSize-i+1}", end="")
|
||||||
|
|
||||||
|
for x in range(boardSize):
|
||||||
|
if board[x][boardSize-y-1] == "":
|
||||||
|
print(" .", end="")
|
||||||
|
else:
|
||||||
|
print(" " + board[x][boardSize-y-1], end ="")
|
||||||
|
|
||||||
|
print(f" {boardSize-i+1}")
|
||||||
|
print(" "*3 + "A B C D E F G H J K L M N O P Q R S T")
|
||||||
|
|
||||||
|
def get_latex_at_move(fromMove):
|
||||||
|
latexList = []
|
||||||
|
|
||||||
|
simulate_board_up_to(fromMove)
|
||||||
|
# just dumping the baord, nothing special
|
||||||
|
for y in range(len(board)):
|
||||||
|
for x in range(len(board)):
|
||||||
|
if board[x][y] != "":
|
||||||
|
color = "white" if board[x][y] == "w" else "black"
|
||||||
|
if ord("a")+x < ord("i"):
|
||||||
|
firstCoordinate = chr(ord("a")+x)
|
||||||
|
else:
|
||||||
|
firstCoordinate = chr(ord("a")+x+1)
|
||||||
|
latexList.append(f"\\stone{{{color}}}{{{firstCoordinate}}}{{{y+1}}}\n")
|
||||||
|
|
||||||
|
return latexList
|
||||||
|
|
||||||
|
def produce_latex(fromMove, toMove, continousCounting):
|
||||||
|
# old moves
|
||||||
|
latexList = ["\\begin{psgoboard}\n\t"]
|
||||||
|
latexList.extend(get_latex_at_move(fromMove))
|
||||||
|
|
||||||
|
finished = False
|
||||||
|
moveCount = 1
|
||||||
|
if continousCounting:
|
||||||
|
moveCount = fromMove + 1
|
||||||
|
|
||||||
|
# new moves
|
||||||
|
for i in range(fromMove, len(blackMoves) + len(whiteMoves)):
|
||||||
|
if i == toMove: break
|
||||||
|
moves = []
|
||||||
|
color = ""
|
||||||
|
|
||||||
|
if i % 2 == 0: # blacks turn
|
||||||
|
moves = blackMoves
|
||||||
|
color = "black"
|
||||||
|
else: # whites turn
|
||||||
|
moves = whiteMoves
|
||||||
|
color = "white"
|
||||||
|
|
||||||
|
# if this player has no moves left -> continue
|
||||||
|
if len(moves) == 0: continue
|
||||||
|
|
||||||
|
x, y = moves[i//2]
|
||||||
|
|
||||||
|
# skip the 'i' coordinate
|
||||||
|
if ord("a")+x-1 < ord("i"):
|
||||||
|
firstCoordinate = chr(ord("a")+x-1)
|
||||||
|
else:
|
||||||
|
firstCoordinate = chr(ord("a")+x)
|
||||||
|
|
||||||
|
latexList.append(f"\\stone[\\marklb{{{moveCount}}}]{{{color}}}{{{firstCoordinate}}}{{{y}}}")
|
||||||
|
moveCount += 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
# played the last move
|
||||||
|
finished = True
|
||||||
|
|
||||||
|
latexList.append("\n\\end{psgoboard}\n")
|
||||||
|
return latexList, finished
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
blackMoves.append((4,4))
|
||||||
|
whiteMoves.append((4,3))
|
||||||
|
blackMoves.append((5,3))
|
||||||
|
whiteMoves.append((5,4))
|
||||||
|
blackMoves.append((3,3))
|
||||||
|
whiteMoves.append((3,4))
|
||||||
|
blackMoves.append((4,2))
|
||||||
|
whiteMoves.append((4,5))
|
||||||
|
blackMoves.append((10,10))
|
||||||
|
whiteMoves.append((4,3))
|
||||||
|
blackMoves.append((4,4))
|
||||||
|
whiteMoves.append((4,3))
|
||||||
|
|
||||||
|
produce_latex(7, 200)
|
||||||
|
show_board()
|
||||||
Reference in New Issue
Block a user