def __init__(
      self,
      *,
      model: language_model.LanguageModel,
      memory: associative_memory.AssociativeMemory,
      clock: game_clock.GameClock,
      players: Sequence[agent_lib.GenerativeAgent],
      name: str = 'Game Master',
      update_thought_chain: Sequence[
          Callable[[interactive_document.InteractiveDocument, str, str], str]
      ] = DEFAULT_THOUGHTS,
      components: Sequence[component.Component] = (),
      action_spec: agent_lib.ActionSpec | Mapping[str, agent_lib.ActionSpec] = (
          agent_lib.DEFAULT_ACTION_SPEC
      ),
      randomise_initiative: bool = False,
      player_observes_event: bool = True,
      players_act_simultaneously: bool = True,
      verbose: bool = False,
      concurrent_externalities: bool = True,
      use_default_instructions: bool = True,
      log_color: str = 'red',
      seed: int | None = None,
  ):
    """Game master constructor.

    Args:
      model: a language model
      memory: an associative memory
      clock: a clock
      players: a sequence of generative agent simulacra which is assumed to
        contain only information that players also can access.
      name: name of the game master.
      update_thought_chain: chain of thoughts for update from player
      components: components to condition on
      action_spec: action_specs to pass to agents
      randomise_initiative: whether to randomise initiative (who goes first )
        order
      player_observes_event: send outcome of the players action back as
        observation. Helpful to turn off if using direct_effect externality to
        avoid duplicate memories.
      players_act_simultaneously: advance time after all players have acted, if
        false then advance time after each player acts.
      verbose: whether to print debugging information or not.
      concurrent_externalities: if true, runs externalities in separate threads
      use_default_instructions: set to False if you want to skip the standard
        instructions used for the game master, e.g. do this if you plan to pass
        custom instructions as a constant component instead.
      log_color: color in which to print logs
      seed: random seed for the game master
    """
    self._name = name
    self._model = model
    self._memory = memory
    self._clock = clock
    self._log_color = log_color
    self._randomise_initiative = randomise_initiative
    self._player_observes_event = player_observes_event
    self._players_act_simultaneously = players_act_simultaneously
    self._seed = seed if seed is not None else random.getrandbits(63)
    self._rng = random.Random(seed)

    if isinstance(action_spec, agent_lib.ActionSpec):
      self._action_spec = {player.name: action_spec for player in players}
    else:
      self._action_spec = dict(action_spec)

    components = list(components)
    if use_default_instructions:
      instructions_component = generic_components.constant.ConstantComponent(
          state=DEFAULT_GAME_MASTER_INSTRUCTIONS, name='Instructions'
      )
      components.insert(0, instructions_component)

    self._components: dict[str, component.Component] = {}
    for comp in components:
      if comp.name() in self._components:
        raise ValueError(f'Duplicate component name: {comp.name()}')
      else:
        self._components[comp.name()] = comp

    self._verbose = verbose

    self._update_from_player_thoughts = update_thought_chain

    self._players_by_name = {player.name: player for player in players}
    if len(self._players_by_name) != len(players):
      raise ValueError('Duplicate player names')

    self._concurrent_externalities = concurrent_externalities
    self._log = []
Game master constructor.

    Args:
      model: a language model
      memory: an associative memory
      clock: a clock
      players: a sequence of generative agent simulacra which is assumed to
        contain only information that players also can access.
      name: name of the game master.
      update_thought_chain: chain of thoughts for update from player
      components: components to condition on
      action_spec: action_specs to pass to agents
      randomise_initiative: whether to randomise initiative (who goes first )
        order
      player_observes_event: send outcome of the players action back as
        observation. Helpful to turn off if using direct_effect externality to
        avoid duplicate memories.
      players_act_simultaneously: advance time after all players have acted, if
        false then advance time after each player acts.
      verbose: whether to print debugging information or not.
      concurrent_externalities: if true, runs externalities in separate threads
      use_default_instructions: set to False if you want to skip the standard
        instructions used for the game master, e.g. do this if you plan to pass
        custom instructions as a constant component instead.
      log_color: color in which to print logs
      seed: random seed for the game master
    
concordia/environment/deprecated/game_master.py