127 lines
4.2 KiB
Python
127 lines
4.2 KiB
Python
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()
|