112 lines
2.9 KiB
Python
112 lines
2.9 KiB
Python
import random
|
|
from copy import copy
|
|
from dataclasses import dataclass, field
|
|
from typing import Optional
|
|
|
|
from hopper.enums import ObjectType
|
|
from hopper.models.player import Player, Position
|
|
|
|
BOARD_DUMP_CHARS: dict[ObjectType, str] = {
|
|
ObjectType.NONE: "·",
|
|
ObjectType.OBSTACLE: "✘",
|
|
ObjectType.PLAYER: "⯧",
|
|
ObjectType.DESTINATION: "⬤",
|
|
}
|
|
|
|
|
|
def create_random_position(board_width: int, board_height: int) -> Position:
|
|
return Position(
|
|
x=random.randint(0, board_width - 1),
|
|
y=random.randint(0, board_height - 1),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class LayerObject:
|
|
type_: ObjectType
|
|
position: Position
|
|
|
|
|
|
@dataclass
|
|
class Layer:
|
|
name: Optional[str] = None
|
|
objects: list[LayerObject] = field(default_factory=list)
|
|
|
|
def get_object_at_position(self, position: Position) -> Optional[LayerObject]:
|
|
for obj in self.objects:
|
|
if obj.position == position:
|
|
return obj
|
|
return None
|
|
|
|
|
|
@dataclass
|
|
class Destination:
|
|
position: Position
|
|
|
|
|
|
@dataclass
|
|
class GameBoard:
|
|
width: int
|
|
height: int
|
|
destination: Destination
|
|
layers: list[Layer] = field(default_factory=list)
|
|
|
|
def dump(self) -> list[list[str]]:
|
|
board = [
|
|
[BOARD_DUMP_CHARS[ObjectType.NONE] for _ in range(self.width)]
|
|
for _ in range(self.height)
|
|
]
|
|
|
|
for layer in self.layers:
|
|
for obj in layer.objects:
|
|
board[obj.position.y][obj.position.x] = BOARD_DUMP_CHARS[
|
|
ObjectType.OBSTACLE
|
|
]
|
|
|
|
board[self.destination.position.y][
|
|
self.destination.position.x
|
|
] = BOARD_DUMP_CHARS[ObjectType.DESTINATION]
|
|
|
|
return board
|
|
|
|
def get_object_at_position(self, position: Position) -> Optional[LayerObject]:
|
|
for layer in self.layers:
|
|
obj = layer.get_object_at_position(position)
|
|
if obj is not None:
|
|
return obj
|
|
return None
|
|
|
|
|
|
class BoardLayout:
|
|
def __init__(self, board: GameBoard, players: list[Player]) -> None:
|
|
self.board = board
|
|
self.players = players
|
|
self.layers = self.__create_layers()
|
|
|
|
def __create_layers(self) -> list[Layer]:
|
|
layers = copy(self.board.layers)
|
|
layers.append(
|
|
Layer(
|
|
name="destination",
|
|
objects=[
|
|
LayerObject(
|
|
type_=ObjectType.DESTINATION,
|
|
position=self.board.destination.position,
|
|
),
|
|
],
|
|
)
|
|
)
|
|
layers.append(
|
|
Layer(
|
|
name="players",
|
|
objects=[
|
|
LayerObject(
|
|
type_=ObjectType.PLAYER,
|
|
position=player.position,
|
|
)
|
|
for player in self.players
|
|
],
|
|
)
|
|
)
|
|
return layers
|