from diceplayer.config.player_config import PlayerConfig, RoutineType from diceplayer.logger import logger from diceplayer.state.state_handler import StateHandler from diceplayer.state.state_model import StateModel from typing_extensions import TypedDict, Unpack class PlayerFlags(TypedDict): continuation: bool force: bool class Player: def __init__(self, config: PlayerConfig): self.config = config self._state_handler = StateHandler(config.simulation_dir) def play(self, **flags: Unpack[PlayerFlags]): if not flags["continuation"]: logger.info( "Continuation flag is not set. Starting a new simulation and deleting any existing state." ) self._state_handler.delete() state = self._state_handler.get(self.config, force=flags["force"]) if state is None: state = StateModel.from_config(self.config) else: logger.info("Resuming from existing state.") while state.current_cycle < self.config.max_cyc: logger.info( f"Starting cycle {state.current_cycle + 1} of {self.config.max_cyc}." ) step_directory = self.config.simulation_dir / f"{state.current_cycle::02d}" if not step_directory.exists(): step_directory.mkdir(parents=True) current_routine = self._fetch_current_routine(state.current_cycle) if current_routine == RoutineType.CHARGE: self._charge_opt_routine(state) elif current_routine == RoutineType.GEOMETRY: self._geometry_opt_routine(state) else: logger.error(f"Invalid routine type: {current_routine}") return state.current_cycle += 1 self._state_handler.save(state) logger.info("Reached maximum number of cycles. Simulation complete.") def _fetch_current_routine(self, current_cycle: int) -> RoutineType: if self.config.type != RoutineType.BOTH: return self.config.type if current_cycle < self.config.switch_cyc: return RoutineType.CHARGE return RoutineType.GEOMETRY def _charge_opt_routine(self, state: StateModel) -> None: pass def _geometry_opt_routine(self, state: StateModel) -> None: pass