def run(self, num_times, board, agents, bombs, items, flames, is_partially_observable, agent_view_size, action_space, training_agent=None, is_communicative=False):
    'Run the forward model.\n\n        Args:\n          num_times: The number of times to run it for. This is a maximum and\n            it will stop early if we reach a done.\n          board: The board state to run it from.\n          agents: The agents to use to run it.\n          bombs: The starting bombs.\n          items: The starting items.\n          flames: The starting flames.\n          is_partially_observable: Whether the board is partially observable or\n            not. Only applies to TeamRadio.\n          agent_view_size: If it\'s partially observable, then the size of the\n            square that the agent can view.\n          action_space: The actions that each agent can take.\n          training_agent: The training agent to pass to done.\n          is_communicative: Whether the action depends on communication\n            observations as well.\n\n        Returns:\n          steps: The list of step results, which are each a dict of "obs",\n            "next_obs", "reward", "action".\n          board: Updated board.\n          agents: Updated agents, same models though.\n          bombs: Updated bombs.\n          items: Updated items.\n          flames: Updated flames.\n          done: Whether we completed the game in these steps.\n          info: The result of the game if it\'s completed.\n        '
    steps = []
    for _ in num_times:
        obs = self.get_observations(board, agents, bombs, is_partially_observable, agent_view_size)
        actions = self.act(agents, obs, action_space, is_communicative=is_communicative)
        (board, agents, bombs, items, flames) = self.step(actions, board, agents, bombs, items, flames)
        next_obs = self.get_observations(board, agents, bombs, is_partially_observable, agent_view_size)
        reward = self.get_rewards(agents, game_type, step_count, max_steps)
        done = self.get_done(agents, game_type, step_count, max_steps, training_agent)
        info = self.get_info(done, rewards, game_type, agents)
        steps.append({'obs': obs, 'next_obs': next_obs, 'reward': reward, 'actions': actions})
        if done:
            for agent in agents:
                agent.episode_end(reward[agent.agent_id])
            break
    return (steps, board, agents, bombs, items, flames, done, info)
Run the forward model.

Args:
  num_times: The number of times to run it for. This is a maximum and
    it will stop early if we reach a done.
  board: The board state to run it from.
  agents: The agents to use to run it.
  bombs: The starting bombs.
  items: The starting items.
  flames: The starting flames.
  is_partially_observable: Whether the board is partially observable or
    not. Only applies to TeamRadio.
  agent_view_size: If it's partially observable, then the size of the
    square that the agent can view.
  action_space: The actions that each agent can take.
  training_agent: The training agent to pass to done.
  is_communicative: Whether the action depends on communication
    observations as well.

Returns:
  steps: The list of step results, which are each a dict of "obs",
    "next_obs", "reward", "action".
  board: Updated board.
  agents: Updated agents, same models though.
  bombs: Updated bombs.
  items: Updated items.
  flames: Updated flames.
  done: Whether we completed the game in these steps.
  info: The result of the game if it's completed.
def run(self, num_times, board, agents, bombs, items, flames, is_partially_observable, agent_view_size, action_space, training_agent=None, is_communicative=False):
    'Run the forward model.\n\n        Args:\n          num_times: The number of times to run it for. This is a maximum and\n            it will stop early if we reach a done.\n          board: The board state to run it from.\n          agents: The agents to use to run it.\n          bombs: The starting bombs.\n          items: The starting items.\n          flames: The starting flames.\n          is_partially_observable: Whether the board is partially observable or\n            not. Only applies to TeamRadio.\n          agent_view_size: If it\'s partially observable, then the size of the\n            square that the agent can view.\n          action_space: The actions that each agent can take.\n          training_agent: The training agent to pass to done.\n          is_communicative: Whether the action depends on communication\n            observations as well.\n\n        Returns:\n          steps: The list of step results, which are each a dict of "obs",\n            "next_obs", "reward", "action".\n          board: Updated board.\n          agents: Updated agents, same models though.\n          bombs: Updated bombs.\n          items: Updated items.\n          flames: Updated flames.\n          done: Whether we completed the game in these steps.\n          info: The result of the game if it\'s completed.\n        '
    steps = []
    for _ in num_times:
        obs = self.get_observations(board, agents, bombs, is_partially_observable, agent_view_size)
        actions = self.act(agents, obs, action_space, is_communicative=is_communicative)
        (board, agents, bombs, items, flames) = self.step(actions, board, agents, bombs, items, flames)
        next_obs = self.get_observations(board, agents, bombs, is_partially_observable, agent_view_size)
        reward = self.get_rewards(agents, game_type, step_count, max_steps)
        done = self.get_done(agents, game_type, step_count, max_steps, training_agent)
        info = self.get_info(done, rewards, game_type, agents)
        steps.append({'obs': obs, 'next_obs': next_obs, 'reward': reward, 'actions': actions})
        if done:
            for agent in agents:
                agent.episode_end(reward[agent.agent_id])
            break
    return (steps, board, agents, bombs, items, flames, done, info)