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