import os from time import sleep from typing import override import pygame from src.algorithms.wfc import WFCSolver from src.algorithms.bruteforce import BruteForceSolver 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): image: pygame.Surface rect: pygame.Rect x: int y: int def __init__(self, x: int, y: int) -> None: super().__init__() self.image = pygame.Surface((28, 28)) self.rect = self.image.get_rect() self.rect.x = 30 * x + 1 self.rect.y = 30 * y + 1 self.x = x self.y = y @override 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_alpha() 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: if not self.rect.collidepoint(*event.pos): continue if event.button == 1: 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}) ) class NetGUI: game: NetGame window: pygame.Surface pieceSprites: pygame.sprite.Group[ PieceSprite # pyright: ignore[reportInvalidTypeArguments] ] def __init__(self, width: int, height: int): self.game = NetGame(width, height) pygame.init() 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(width): for y in range(height): self.pieceSprites.add(PieceSprite(x, y)) def update_display(self, events: list[pygame.event.Event]): self.pieceSprites.update(self.game, events) for sprite in self.pieceSprites: self.window.blit(sprite.image, sprite.rect) pygame.display.flip() def run_game(self): current_solver = None display_solver = False step_solver = False while not self.game.solved(): events = pygame.event.get() for event in events: if event.type == pygame.QUIT: raise SystemExit elif event.type == LEFT_TURN: self.game.turn_ccw(event.x, event.y) elif event.type == RIGHT_TURN: self.game.turn_cw(event.x, event.y) elif event.type == LOCK: self.game.lock(event.x, event.y) elif event.type == pygame.KEYDOWN: if event.key == pygame.K_b: current_solver = BruteForceSolver(self.game).solve() elif event.key == pygame.K_d: display_solver = not display_solver elif event.key == pygame.K_s: step_solver = not step_solver elif event.key == pygame.K_w: current_solver = WFCSolver(self.game).solve() if current_solver: try: _ = next(current_solver) except StopIteration: current_solver = None if step_solver: _ = input() if (not current_solver) or display_solver: self.update_display(events) sleep(2) NetGUI(5, 5).run_game()