""" Kernlogik des Spiels """ from random import choice from src.interface import parse_description from src.netTypes import Piece, Direction, Coordinate DEMO_FIELD = parse_description("5x5:c7634887c213e5b8db3e69282") class Grid: pieces: list[list[Piece]] width: int height: int def __init__(self, width: int, height: int) -> None: self.height = height self.width = width if width != height or width not in [5, 7, 9, 11, 13]: raise ValueError("Feldgrösse nicht erlaubt") with open(f"descriptions/{width}x{height}.txt") as f: lines = f.readlines() selected = choice(lines).strip() 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 def __init__(self, width: int, height: int) -> None: self._grid = Grid(width, 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 solved(self): return self._grid.solved()