Descriptions benutzen und andere Feldgrössen als 5x5 erlauben
This commit is contained in:
32
src/GUI.py
32
src/GUI.py
@@ -1,12 +1,15 @@
|
||||
import os
|
||||
from typing import override
|
||||
|
||||
import pygame
|
||||
|
||||
from src.net import NetGame
|
||||
|
||||
# pyright: reportUnusedCallResult=false, reportAny=false
|
||||
|
||||
LEFT_TURN = pygame.USEREVENT + 1
|
||||
RIGHT_TURN = pygame.USEREVENT + 2
|
||||
LOCK = pygame.USEREVENT + 3
|
||||
|
||||
|
||||
class PieceSprite(pygame.sprite.Sprite):
|
||||
@@ -28,7 +31,12 @@ class PieceSprite(pygame.sprite.Sprite):
|
||||
def update(self, game: NetGame, events: list[pygame.event.Event]):
|
||||
piece = game.get_piece(self.x, self.y)
|
||||
image = pygame.image.load(os.path.join("assets", f"{piece.type}.bmp")).convert()
|
||||
image = pygame.transform.rotate(image, -90 * piece.direction)
|
||||
image.set_colorkey("#ffffff")
|
||||
image = pygame.transform.rotate(image, -90 * int(piece.direction))
|
||||
if piece.locked:
|
||||
self.image.fill("#a0a0a0")
|
||||
else:
|
||||
self.image.fill("#ffffff")
|
||||
self.image.blit(image, (0, 0))
|
||||
for event in events:
|
||||
if event.type == pygame.MOUSEBUTTONUP:
|
||||
@@ -38,6 +46,10 @@ class PieceSprite(pygame.sprite.Sprite):
|
||||
pygame.event.post(
|
||||
pygame.event.Event(LEFT_TURN, {"x": self.x, "y": self.y})
|
||||
)
|
||||
elif event.button == 2:
|
||||
pygame.event.post(
|
||||
pygame.event.Event(LOCK, {"x": self.x, "y": self.y})
|
||||
)
|
||||
elif event.button == 3:
|
||||
pygame.event.post(
|
||||
pygame.event.Event(RIGHT_TURN, {"x": self.x, "y": self.y})
|
||||
@@ -47,18 +59,18 @@ class PieceSprite(pygame.sprite.Sprite):
|
||||
class NetGUI:
|
||||
game: NetGame
|
||||
window: pygame.Surface
|
||||
pieceSprites: pygame.sprite.Group[PieceSprite]
|
||||
pieceSprites: pygame.sprite.Group[PieceSprite] # pyright: ignore[reportInvalidTypeArguments]
|
||||
|
||||
def __init__(self):
|
||||
self.game = NetGame(5, 5)
|
||||
def __init__(self, width: int, height: int):
|
||||
self.game = NetGame(width, height)
|
||||
pygame.init()
|
||||
self.window = pygame.display.set_mode((5 * 30, 5 * 30))
|
||||
self.window = pygame.display.set_mode((width * 30, height * 30))
|
||||
self.window.fill("#ffffff")
|
||||
pygame.display.set_caption("Net")
|
||||
|
||||
self.pieceSprites = pygame.sprite.Group()
|
||||
for x in range(5):
|
||||
for y in range(5):
|
||||
for x in range(width):
|
||||
for y in range(height):
|
||||
self.pieceSprites.add(PieceSprite(x, y))
|
||||
|
||||
def run_game(self):
|
||||
@@ -71,11 +83,13 @@ class NetGUI:
|
||||
elif event.type == LEFT_TURN:
|
||||
self.game.turn_ccw(event.x, event.y)
|
||||
if self.game.solved():
|
||||
raise SystemExit
|
||||
raise SystemExit # TODO: Richtiger Spiel schluss, nicht einfach schliessen
|
||||
elif event.type == RIGHT_TURN:
|
||||
self.game.turn_cw(event.x, event.y)
|
||||
if self.game.solved():
|
||||
raise SystemExit
|
||||
elif event.type == LOCK:
|
||||
self.game.lock(event.x, event.y)
|
||||
|
||||
self.pieceSprites.update(self.game, events)
|
||||
for sprite in self.pieceSprites:
|
||||
@@ -84,4 +98,4 @@ class NetGUI:
|
||||
pygame.display.flip()
|
||||
|
||||
|
||||
NetGUI().run_game()
|
||||
NetGUI(13, 13).run_game()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from src.types import Piece, Direction, PieceType
|
||||
from src.netTypes import Piece, Direction, PieceType
|
||||
|
||||
|
||||
# Tatham's board description format:
|
||||
|
||||
61
src/net.py
61
src/net.py
@@ -2,47 +2,10 @@
|
||||
Kernlogik des Spiels
|
||||
"""
|
||||
|
||||
from src.types import Piece, Direction
|
||||
from random import choice
|
||||
|
||||
from src.interface import parse_description
|
||||
|
||||
|
||||
# DEMO_FIELD = [
|
||||
# [
|
||||
# Piece(PieceType.NODE),
|
||||
# Piece(PieceType.NODE),
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.NODE),
|
||||
# Piece(PieceType.NODE),
|
||||
# ],
|
||||
# [
|
||||
# Piece(PieceType.STRAIGHT),
|
||||
# Piece(PieceType.NODE),
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.STRAIGHT),
|
||||
# Piece(PieceType.CORNER),
|
||||
# ],
|
||||
# [
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.NODE),
|
||||
# ],
|
||||
# [
|
||||
# Piece(PieceType.STRAIGHT),
|
||||
# Piece(PieceType.NODE),
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.T_JUNCTION),
|
||||
# Piece(PieceType.NODE),
|
||||
# ],
|
||||
# [
|
||||
# Piece(PieceType.NODE),
|
||||
# Piece(PieceType.NODE),
|
||||
# Piece(PieceType.CORNER),
|
||||
# Piece(PieceType.CORNER),
|
||||
# Piece(PieceType.CORNER),
|
||||
# ],
|
||||
# ]
|
||||
from src.netTypes import Piece, Direction, Coordinate
|
||||
|
||||
DEMO_FIELD = parse_description("5x5:c7634887c213e5b8db3e69282")
|
||||
|
||||
@@ -55,9 +18,12 @@ class Grid:
|
||||
def __init__(self, width: int, height: int) -> None:
|
||||
self.height = height
|
||||
self.width = width
|
||||
self.pieces = (
|
||||
DEMO_FIELD # TODO: Field generation or import from Tatham's version
|
||||
)
|
||||
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] = []
|
||||
@@ -82,7 +48,7 @@ class Grid:
|
||||
) -> list[list[bool]]:
|
||||
connected[x][y] = True
|
||||
|
||||
connectedNeighbors: list[Coordinate] = []
|
||||
connected_neighbors: list[Coordinate] = []
|
||||
for nx, ny in self.neighbors(x, y):
|
||||
dx = x - nx
|
||||
dy = y - ny
|
||||
@@ -92,9 +58,9 @@ class Grid:
|
||||
and Direction.from_offset(-dx, -dy)
|
||||
in self.pieces[x][y].connected_directions()
|
||||
):
|
||||
connectedNeighbors.append((nx, ny))
|
||||
connected_neighbors.append((nx, ny))
|
||||
|
||||
for nx, ny in connectedNeighbors:
|
||||
for nx, ny in connected_neighbors:
|
||||
if connected[nx][ny]:
|
||||
continue
|
||||
connected = self._solve_floodfill(nx, ny, connected)
|
||||
@@ -119,6 +85,9 @@ class NetGame:
|
||||
|
||||
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()
|
||||
|
||||
@@ -51,7 +51,11 @@ class Piece:
|
||||
]
|
||||
|
||||
def turn_cw(self) -> None:
|
||||
if self.locked:
|
||||
return
|
||||
self.direction = Direction((self.direction + 1) % 4)
|
||||
|
||||
def turn_ccw(self) -> None:
|
||||
if self.locked:
|
||||
return
|
||||
self.direction = Direction((self.direction - 1) % 4)
|
||||
Reference in New Issue
Block a user