Hive/tile_hard.py
2023-12-29 16:08:55 +01:00

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)