# coding: utf-8 import typing from synergine2.config import Config from synergine2.simulation import SimulationBehaviour from synergine2.simulation import SubjectBehaviour from synergine2.simulation import SubjectMechanism from synergine2.simulation import Intention from synergine2.simulation import Simulation from synergine2.simulation import Event from synergine2_xyz.simulation import XYZSimulation class MoveToIntention(Intention): def __init__(self, move_to: typing.Tuple[int, int]) -> None: self.move_to = move_to self.path = [] # type: typing.List[typing.Tuple[int, int]] self.path_progression = -1 # type: int class RequestMoveBehaviour(SimulationBehaviour): move_intention_class = MoveToIntention @classmethod def merge_data(cls, new_data, start_data=None): # TODO: behaviour/Thing dedicated to Gui -> Simulation ? pass # This behaviour is designed to be launch by terminal def __init__( self, config: Config, simulation: Simulation, ): super().__init__(config, simulation) self.simulation = typing.cast(XYZSimulation, self.simulation) def run(self, data): # TODO: behaviour/Thing dedicated to Gui -> Simulation ? pass # This behaviour is designed to be launch by terminal def action(self, data) -> typing.List[Event]: subject_id = data['subject_id'] move_to = data['move_to'] try: subject = self.simulation.subjects.index[subject_id] subject.intentions.set(self.move_intention_class(move_to)) except KeyError: # TODO: log error here pass return [] class MoveToMechanism(SubjectMechanism): def run(self): # TODO: Si move to: Si nouveau: a*, si bloque, a*, sinon rien # TODO: pourquoi un mechanism plutot que dans run du behaviour ? faire en sorte que lorsque on calcule, # si un subject est déjà passé par là et qu'il va au même endroit, ne pas recalculer. try: # TODO: MoveToIntention doit être configurable move = self.subject.intentions.get(MoveToIntention) move = typing.cast(MoveToIntention, move) new_path = None if not move.path: move.path = self.simulation.physics.found_path( start=self.subject.position, end=move.move_to, subject=self.subject, ) # Note: We are in process, move change will be lost new_path = move.path # move.path = [] # new_path = move.path # for i in range(20): # move.path.append(( # self.subject.position[0], # self.subject.position[1] + i, # )) next_move = move.path[move.path_progression + 1] # TODO: fin de path if not self.simulation.is_possible_position(next_move): # TODO: refaire le path new_path = ['...'] return { 'new_path': new_path, } except IndexError: # TODO: Specialize ? No movement left return None except KeyError: # TODO: Specialize ? No MoveIntention return None class MoveEvent(Event): def __init__( self, subject_id: int, from_position: typing.Tuple[int, int], to_position: typing.Tuple[int, int], *args, **kwargs ): super().__init__(*args, **kwargs) self.subject_id = subject_id self.from_position = from_position self.to_position = to_position def repr_debug(self) -> str: return '{}: subject_id:{}, from_position:{} to_position: {}'.format( type(self).__name__, self.subject_id, self.from_position, self.to_position, ) class MoveToBehaviour(SubjectBehaviour): use = [MoveToMechanism] move_to_mechanism = MoveToMechanism def run(self, data): # TODO: on fait vraiment rien ici ? Note: meme si il n'y a pas de new_path, l'action doit s'effectuer # du moment qu'il y a une intention de move move_to_data = data[self.move_to_mechanism.__name__] if move_to_data: return move_to_data return False def action(self, data) -> [Event]: # TODO: effectuer un move vers une nouvelle position ou faire progresser "l'entre-deux" new_path = data['new_path'] try: # TODO: MoveToIntention doit être configurable move = self.subject.intentions.get(MoveToIntention) move = typing.cast(MoveToIntention, move) if new_path: move.path = new_path move.path_progression = -1 # TODO: progression et lorsque "vraiment avance d'une case" envoyer le Move # pour le moment on move direct # TODO: fin de path move.path_progression += 1 new_position = move.path[move.path_progression] previous_position = self.subject.position self.subject.position = new_position self.subject.intentions.set(move) return [MoveEvent(self.subject.id, previous_position, new_position)] except KeyError: # TODO: log ? Il devrait y avoir un move puisque data du run/mechanism ! pass