Browse Source

Added go borad simulator to remove dead stones.

master
FelixBrendel 8 years ago
parent
commit
dc93049be6
4 changed files with 240 additions and 35 deletions
  1. +1
    -0
      .gitignore
  2. +23
    -35
      kifugen.py
  3. BIN
     
  4. +216
    -0
      simpleGoBoard.py

+ 1
- 0
.gitignore View File

@@ -5,3 +5,4 @@
*.log
*.ps
*.pdf
__pycache__/

+ 23
- 35
kifugen.py View File

@@ -3,6 +3,9 @@ import os
import sys
from subprocess import check_call, DEVNULL, STDOUT, CalledProcessError
from shutil import copyfile, rmtree
from pprint import pprint

import simpleGoBoard

parser = argparse.ArgumentParser(description='Convert sgf go records into a kifu format.')

@@ -26,6 +29,8 @@ header = sgfData[0]
moves = sgfData[1:]

def format_date(date):
if date == "":
return ""
months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
ds = date.split("-") # year month day
ds.reverse()
@@ -67,45 +72,28 @@ def generate_title():

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 = []
for i in range(len(splitBoardAt)-1):
currentSplit = splitBoardAt[i]
nextSplit = splitBoardAt[i+1]

outText.append("\\begin{psgoboard}\n\t")

# 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")
board, finished = simpleGoBoard.produce_latex(currentSplit, nextSplit, args.cn)
outText.extend(board)
if finished:
break
elif not args.cn:
outText.append("\n\\setcounter{gomove}{0}\n")

return "".join(outText)

@@ -135,7 +123,7 @@ if parsedHeader["rankBlack"] != "":
playerBlack += f" ({parsedHeader['rankBlack']})"
if parsedHeader["rankWhite"] != "":
playerWhite += f" ({parsedHeader['rankWhite']})"
moves = generate_moves()
boards = generate_boards()

outText = f"""
\\documentclass[a4paper]{{article}}
@@ -167,7 +155,7 @@ outText = f"""
\\end{{tabularx}}
\\vspace{{3cm}}

{moves}
{boards}

\\end{{center}}
\\end{{document}}
@@ -195,4 +183,4 @@ if not args.t:
rmtree(f"{fileBase}/")
# hould output be opened?
if args.o:
os.system(f'"{fileBase}.pdf"')
os.startfile(f'"{fileBase}.pdf"')

BIN
View File


+ 216
- 0
simpleGoBoard.py View File

@@ -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()

Loading…
Cancel
Save