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