def play(
      self,
      premise: str | None = None,
      max_steps: int | None = None,
      raw_log: list[Mapping[str, Any]] | None = None,
  ) -> str:
    """Run the simulation.

    Args:
      premise: A string to use as the initial premise of the simulation.
      max_steps: The maximum number of steps to run the simulation for.
      raw_log: A list to store the raw log of the simulation. This is used to
        generate the HTML log. Data in the supplied raw_log will be appended
        with the log from the simulation. If None, a new list is created.

    Returns:
      html_results_log: browseable log of the simulation in HTML format
    """
    if premise is None:
      premise = self._config.default_premise
    if max_steps is None:
      max_steps = self._config.default_max_steps

    raw_log = raw_log or []
    self._environment.run_loop(
        game_masters=self.game_masters,
        entities=self.entities,
        premise=premise,
        max_steps=max_steps,
        verbose=True,
        log=raw_log,
    )

    player_logs = []
    player_log_names = []

    scores = helper_functions_lib.find_data_in_nested_structure(
        raw_log, "Player Scores"
    )

    for player in self.entities:
      if (
          not isinstance(player, entity_component.EntityWithComponents)
          or player.get_component("__memory__") is None
      ):
        continue

      entity_memory_component = player.get_component("__memory__")
      entity_memories = entity_memory_component.get_all_memories_as_text()
      player_html = html_lib.PythonObjectToHTMLConverter(
          entity_memories
      ).convert()
      player_logs.append(player_html)
      player_log_names.append(f"{player.name}")

    game_master_memories = (
        self.game_master_memory_bank.get_all_memories_as_text()
    )
    game_master_html = html_lib.PythonObjectToHTMLConverter(
        game_master_memories
    ).convert()
    player_logs.append(game_master_html)
    player_log_names.append("Game Master Memories")
    summary = ""
    if scores:
      summary = f"Player Scores: {scores[-1]}"
    results_log = html_lib.PythonObjectToHTMLConverter(
        copy.deepcopy(raw_log)
    ).convert()
    tabbed_html = html_lib.combine_html_pages(
        [results_log, *player_logs],
        ["Game Master log", *player_log_names],
        summary=summary,
        title="Simulation Log",
    )
    html_results_log = html_lib.finalise_html(tabbed_html)
    return html_results_log
Run the simulation.

    Args:
      premise: A string to use as the initial premise of the simulation.
      max_steps: The maximum number of steps to run the simulation for.
      raw_log: A list to store the raw log of the simulation. This is used to
        generate the HTML log. Data in the supplied raw_log will be appended
        with the log from the simulation. If None, a new list is created.

    Returns:
      html_results_log: browseable log of the simulation in HTML format
    
concordia/prefabs/simulation/generic.py