TheBird

models.py

8.1 kB · python · 205 lines

1from mrlypy.two import Cell2d2from dataclasses import dataclass, field3from mrlypy.life.enums import Boundary, Fate4from mrlypy.life.models import Life5from mrlypy.music import WaveType6from mrlypy.music.enums import Scale7from mrlypy.music.models import Voice8from mrlypy.paint.enums import Ink9from mrlypy.tile import Tile10from typing import Any, Dict, List11from enums import Path, Sequence, Way1213@dataclass14class Task:1516    key: str = None17    id: str = None18    seed: int = None1920    boundary: Boundary = None21    primary: Ink = None22    secondary: Ink = None23    canvas_size: int = None24    canvas_unit_width: int = None25    canvas_unit_height: int = None2627    tile: Tile = None28    mask: Tile = None2930    way: Way = None31    path: Path = None3233    reflect: bool = None34    birth_sequence: Sequence = None35    survive_sequence: Sequence = None36    include_zeros: bool = None37    include_ones: bool = None38    birth_counts: List[int] = field(default_factory=list)39    survive_counts: List[int] = field(default_factory=list)4041    music: "MusicParams" = None4243    result: Life = None44    count: int = None4546    def is_simple(self) -> bool:47        return self.path == Path.SIMPLE4849    def max_canvas_unit_size(self) -> int:50        return max(self.canvas_unit_width, self.canvas_unit_height)5152    @staticmethod53    def is_custom(sequence: Sequence) -> bool:54        return sequence in [Sequence.CUSTOM, Sequence.RANDOM]5556    def to_dict(self) -> Dict[str, Any]:57        data = {}58        data["key"] = self.key59        data["id"] = self.id60        data["seed"] = self.seed61        data["count"] = self.count62        data["time"] = self.result.time if self.result else None63        data["fate"] = self.result.fate.value if self.result else None64        data["boundary"] = self.boundary.value if self.boundary else None65        data["primary"] = self.primary.value if self.primary else None66        data["secondary"] = self.secondary.value if self.secondary else None67        data["canvas_size"] = self.canvas_size68        data["canvas_unit_width"] = self.canvas_unit_width69        data["canvas_unit_height"] = self.canvas_unit_height70        data["tile"] = self.tile.to_dict() if self.tile else None71        data["mask"] = self.mask.to_dict() if self.mask else None72        data["way"] = self.way.value if self.way else None73        data["path"] = self.path.value if self.path else None74        data["reflect"] = self.reflect75        data["birth_sequence"] = self.birth_sequence.value if self.birth_sequence else None76        data["survive_sequence"] = self.survive_sequence.value if self.survive_sequence else None77        data["include_zeros"] = self.include_zeros78        data["include_ones"] = self.include_ones79        data["birth_counts"] = self.birth_counts if self.is_custom(self.birth_sequence) else None80        data["survive_counts"] = self.survive_counts if self.is_custom(self.survive_sequence) else None81        data["music"] = self.music.to_dict() if self.music else None82        data["grids"] = [grid.to_strings() for grid in self.result.grids] if self.result else None83        return data8485    @classmethod86    def from_dict(cls, data: Dict[str, Any]) -> "Task":87        task = cls()88        task.key = data.get("key")89        task.id = data.get("id")90        task.seed = data.get("seed")91        task.boundary = Boundary(data.get("boundary")) if data.get("boundary") else None92        task.primary = Ink(data.get("primary")) if data.get("primary") else None93        task.secondary = Ink(data.get("secondary")) if data.get("secondary") else None94        task.canvas_size = data.get("canvas_size")95        task.canvas_unit_width = data.get("canvas_unit_width")96        task.canvas_unit_height = data.get("canvas_unit_height")97        tile_data = data.get("tile")98        task.tile = Tile.from_dict(tile_data) if tile_data else None99        mask_data = data.get("mask")100        task.mask = Tile.from_dict(mask_data) if mask_data else None101        task.way = Way(data.get("way")) if data.get("way") else None102        task.path = Path(data.get("path")) if data.get("path") else None103        task.reflect = data.get("reflect")104        task.birth_sequence = Sequence(data.get("birth_sequence")) if data.get("birth_sequence") else None105        task.survive_sequence = Sequence(data.get("survive_sequence")) if data.get("survive_sequence") else None106        task.include_zeros = data.get("include_zeros")107        task.include_ones = data.get("include_ones")108        task.birth_counts = data.get("birth_counts", [])109        task.survive_counts = data.get("survive_counts", [])110        music_data = data.get("music")111        task.music = MusicParams.from_dict(music_data) if music_data else None112        grids_data = data.get("grids")113        grids = [Cell2d.from_strings(grid) for grid in grids_data] if grids_data else []114        fate = Fate(data.get("fate")) if data.get("fate") else None115        count = data.get("count")116        time = data.get("time")117        task.count = count118        if grids:119            task.result = Life(grids=grids, fate=fate, count=count, time=time)120        return task121122@dataclass123class MusicParams:124125    scale: Scale = None126    progression: str = None127    voices: List[Voice] = None128    wave_type: WaveType = None129    num_harmonics: int = None130131    def to_dict(self) -> Dict[str, Any]:132        data = {}133        data["scale"] = self.scale.value if self.scale else None134        data["progression"] = self.progression135        data["wave_type"] = self.wave_type.value if self.wave_type else None136        data["num_harmonics"] = self.num_harmonics137        return data138139    @classmethod140    def from_dict(cls, data: Dict[str, Any]) -> "MusicParams":141        params = cls()142        params.scale = Scale(data.get("scale")) if data.get("scale") else None143        params.progression = data.get("progression")144        params.wave_type = WaveType(data.get("wave_type")) if data.get("wave_type") else None145        params.num_harmonics = data.get("num_harmonics")146        return params147148@dataclass149class Saga:150151    key: str = None152    seed: int = None153154    boundary: Boundary = None155    primary: Ink = None156    canvas_size: int = None157    canvas_unit_width: int = None158    canvas_unit_height: int = None159160    segments: List[Task] = field(default_factory=list)161162    grids: List[Cell2d] = field(default_factory=list)163    segment_lengths: List[int] = field(default_factory=list)164    fate: Fate = None165    count: int = 0166    time: float = 0.0167    attempts: int = 0168169    def to_dict(self) -> Dict[str, Any]:170        data = {}171        data["key"] = self.key172        data["seed"] = self.seed173        data["attempts"] = self.attempts174        data["boundary"] = self.boundary.value if self.boundary else None175        data["primary"] = self.primary.value if self.primary else None176        data["canvas_size"] = self.canvas_size177        data["canvas_unit_width"] = self.canvas_unit_width178        data["canvas_unit_height"] = self.canvas_unit_height179        data["fate"] = self.fate.value if self.fate else None180        data["count"] = self.count181        data["time"] = self.time182        data["segment_lengths"] = self.segment_lengths183        data["segments"] = [s.to_dict() for s in self.segments]184        data["grids"] = [g.to_strings() for g in self.grids] if self.grids else None185        return data186187    @classmethod188    def from_dict(cls, data: Dict[str, Any]) -> "Saga":189        saga = cls()190        saga.key = data.get("key")191        saga.seed = data.get("seed")192        saga.boundary = Boundary(data.get("boundary")) if data.get("boundary") else None193        saga.primary = Ink(data.get("primary")) if data.get("primary") else None194        saga.canvas_size = data.get("canvas_size")195        saga.canvas_unit_width = data.get("canvas_unit_width")196        saga.canvas_unit_height = data.get("canvas_unit_height")197        saga.fate = Fate(data.get("fate")) if data.get("fate") else None198        saga.count = data.get("count", 0)199        saga.attempts = data.get("attempts", 0)200        saga.time = data.get("time", 0.0)201        saga.segment_lengths = data.get("segment_lengths", [])202        saga.segments = [Task.from_dict(s) for s in data.get("segments", [])]203        grids_data = data.get("grids")204        saga.grids = [Cell2d.from_strings(g) for g in grids_data] if grids_data else []205        return saga