106 lines
3.2 KiB
Python
106 lines
3.2 KiB
Python
"""
|
|
Kernlogik des Spiels
|
|
"""
|
|
|
|
from random import choice
|
|
|
|
from src.interface import parse_description
|
|
from src.netTypes import Piece, Direction, Coordinate
|
|
|
|
|
|
class Grid:
|
|
pieces: list[list[Piece]]
|
|
width: int
|
|
height: int
|
|
|
|
def __init__(self, width: int, height: int, specific: int | None = None) -> None:
|
|
self.height = height
|
|
self.width = width
|
|
if width != height or width not in [3, 5, 7, 9, 11, 13]:
|
|
raise ValueError("Feldgrösse nicht erlaubt")
|
|
with open(f"descriptions/{width}x{height}.txt") as f:
|
|
lines = f.readlines()
|
|
if specific is not None:
|
|
selected = lines[specific].strip()
|
|
else:
|
|
selected = choice(lines).strip()
|
|
print(f"Seed: {lines.index(selected + "\n")}")
|
|
self.pieces = parse_description(selected)
|
|
|
|
def neighbors(self, x: int, y: int) -> list[Coordinate]:
|
|
neighbors: list[Coordinate] = []
|
|
for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
|
|
if (
|
|
x + dx < 0
|
|
or x + dx >= self.width
|
|
or y + dy < 0
|
|
or y + dy >= self.height
|
|
):
|
|
continue
|
|
neighbors.append((x + dx, y + dy))
|
|
return neighbors
|
|
|
|
def solved(self) -> bool:
|
|
connected = [([False] * self.height) for _ in range(self.width)]
|
|
connected = self._solve_floodfill(0, 0, connected)
|
|
return all(map(lambda x: all(x), connected))
|
|
|
|
def _solve_floodfill(
|
|
self, x: int, y: int, connected: list[list[bool]]
|
|
) -> list[list[bool]]:
|
|
connected[x][y] = True
|
|
|
|
connected_neighbors: list[Coordinate] = []
|
|
for nx, ny in self.neighbors(x, y):
|
|
dx = x - nx
|
|
dy = y - ny
|
|
if (
|
|
Direction.from_offset(dx, dy)
|
|
in self.pieces[nx][ny].connected_directions()
|
|
and Direction.from_offset(-dx, -dy)
|
|
in self.pieces[x][y].connected_directions()
|
|
):
|
|
connected_neighbors.append((nx, ny))
|
|
|
|
for nx, ny in connected_neighbors:
|
|
if connected[nx][ny]:
|
|
continue
|
|
connected = self._solve_floodfill(nx, ny, connected)
|
|
|
|
return connected
|
|
|
|
|
|
class NetGame:
|
|
_grid: Grid
|
|
width: int
|
|
height: int
|
|
|
|
def __init__(self, width: int, height: int, specific: int | None = None) -> None:
|
|
self._grid = Grid(width, height, specific)
|
|
self.width = width
|
|
self.height = height
|
|
|
|
def get_field(self) -> list[list[Piece]]:
|
|
return self._grid.pieces
|
|
|
|
def get_piece(self, x: int, y: int) -> Piece:
|
|
return self._grid.pieces[x][y]
|
|
|
|
def turn_cw(self, x: int, y: int) -> None:
|
|
self._grid.pieces[x][y].turn_cw()
|
|
|
|
def turn_ccw(self, x: int, y: int) -> None:
|
|
self._grid.pieces[x][y].turn_ccw()
|
|
|
|
def lock(self, x: int, y: int) -> None:
|
|
self._grid.pieces[x][y].locked = not self._grid.pieces[x][y].locked
|
|
|
|
def set_direction(self, x: int, y: int, dir: Direction) -> None:
|
|
self._grid.pieces[x][y].direction = dir
|
|
|
|
def neighbors(self, x: int, y: int) -> list[Coordinate]:
|
|
return self._grid.neighbors(x, y)
|
|
|
|
def solved(self):
|
|
return self._grid.solved()
|