90 lines
3.3 KiB
Python
90 lines
3.3 KiB
Python
import base
|
|
import sys
|
|
|
|
|
|
class GridManager:
|
|
# orphans from earlier attempt
|
|
offsetter = lambda x: x // 2
|
|
get_internal = lambda index: (index[0] + GridManager.offsetter(index[1]), index[1])
|
|
get_hex = lambda index: (index[0] - GridManager.offsetter(index[1]), index[1])
|
|
|
|
def __init__(self, size):
|
|
self.grid = [
|
|
[0 for _ in range(size)] for _ in range(size)
|
|
] # orphan from earlier attempt
|
|
self.board = base.Board(size)
|
|
|
|
def internalize(self, stones: list) -> list: # orphan from earlier attempt
|
|
return [list(map(self.get_internal, stone)) for stone in stones]
|
|
|
|
def hexize(self, stones: list) -> list: # orphan from earlier attempt
|
|
return [list(map(self.get_hex, stone)) for stone in stones]
|
|
|
|
def place_stones(self, stones: list, placed: list, output_file: str) -> bool:
|
|
if len(placed) == len(stones):
|
|
return True
|
|
curr = stones[len(placed)]
|
|
color: int = stones.index(curr) + 1
|
|
for rotation in range(6):
|
|
for p in range(-self.board.size, self.board.size):
|
|
for q in range(-self.board.size, self.board.size):
|
|
if self.board.inBoard(p, q) and self.check(curr, p, q):
|
|
self.place_stone(curr, color, p, q)
|
|
placed.append((p, q, rotation))
|
|
if self.place_stones(stones, placed, output_file):
|
|
return True
|
|
self.remove_stone(curr, p, q)
|
|
placed.pop()
|
|
curr = self.rotate_stone(curr)
|
|
return False
|
|
|
|
def rotate_stone(self, stone: list) -> list:
|
|
rotated_stone = [(self.board.rotateLeft(x, y)) for (x, y) in stone]
|
|
return rotated_stone
|
|
|
|
def check(self, stone: list, *index: (int, int)) -> bool:
|
|
for cell in stone:
|
|
x, y = cell
|
|
if (
|
|
not self.board.inBoard(index[0] + x, index[1] + y)
|
|
or self.board.board[index[0] + x][index[1] + y] != 0
|
|
):
|
|
return False
|
|
return True
|
|
|
|
def place_stone(self, stone: list, color: int, *index: (int, int)) -> None:
|
|
for cell in stone:
|
|
x, y = cell
|
|
self.board.board[index[0] + x][index[1] + y] = color
|
|
|
|
def remove_stone(self, stone: list, *index: (int, int)) -> None:
|
|
for cell in stone:
|
|
x, y = cell
|
|
self.board.board[index[0] + x][index[1] + y] = 0
|
|
|
|
def save_solution(self, output_file: str) -> None:
|
|
with open(output_file, "w") as f:
|
|
for p in self.board.board:
|
|
for q in self.board.board[p]:
|
|
f.write("{} {} {}\n".format(p, q, self.board.board[p][q]))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
size: int = int(sys.argv[1])
|
|
gm: GridManager = GridManager(size)
|
|
stones: list = base.loadStones(sys.argv[2])
|
|
output_file: str = sys.argv[3]
|
|
placed_stones: list = []
|
|
tilesAmount: int = 0
|
|
totalSize: int = size**2
|
|
for stone in stones:
|
|
tilesAmount += len(stone)
|
|
if (
|
|
gm.place_stones(stones, placed_stones, output_file) == False
|
|
or tilesAmount != totalSize
|
|
):
|
|
with open(output_file, "w") as f:
|
|
f.write("NOSOLUTION")
|
|
else:
|
|
# gm.board.saveImage("img.png")
|
|
gm.save_solution(output_file)
|