[docs]classTakingTurnsSimulationController(SimulationController):def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)asyncdefsimulate(self):"""Main simulation task This method is usually scheduled as a task at the end of the simulation setup phase. It can be overwritten by descendant classes to excert complete control over the simulation. """agents=list(self._agents.values())# Needed to preserve orderai=0# Index of current agentenv_terminates=Falsewhileself.is_running:# With the index ai, we iterate over agents in the order in which# they were loaded, which, in turn, is given by the order in# which comes from the ExperimentRun object.# The index ai wraps (see the end of the loop).# Python's dict is guaranteed to remember the order in which items# were added to it (since Python version 3.7).agent=agents[ai]try:response=(awaitself.act([agent]))[0]env_updates=awaitself.step([agent],response.actuators)exceptFlowControlChange:self._state=BasicState.STOPPINGbreakai=(ai+1)%len(agents)LOG.debug("The simulation has ended, updating agents one last time.",)# Notify agents of our terminal state. We can potentially parallelize# here, as order is no longer important: Each agent gets the same# final state, no actions are applied anymore.try:_=awaitself.act(agents,done=True)exceptFlowControlChange:pass# Not relevant here anymore.self.flow_control()