# Path: meltingpot/python/utils/substrates/game_object_utils.py
# class Position(NamedTuple):
# class Orientation(enum.Enum):
# class Transform(NamedTuple):
#   NORTH = "N"
#   EAST = "E"
#   SOUTH = "S"
#   WEST = "W"
# TYPE_ALL = "all"
# TYPE_CHOICE = "choice"
# def get_named_components(
#     game_object_config: PrefabConfig,
#     name: str):
# def get_first_named_component(
#     game_object_config: PrefabConfig,
#     name: str):
# def build_game_objects(
#     num_players: int,
#     ascii_map: str,
#     prefabs: Optional[Mapping[str, PrefabConfig]] = None,
#     char_prefab_map: Optional[PrefabConfig] = None,
#     player_palettes: Optional[Sequence[shapes.Color]] = None,
#     use_badges: bool = False,
#     badge_palettes: Optional[Sequence[shapes.Color]] = None,
# ) -> Tuple[List[PrefabConfig], List[PrefabConfig]]:
# def build_avatar_objects(
#     num_players: int,
#     prefabs: Optional[Mapping[str, PrefabConfig]] = None,
#     player_palettes: Optional[Sequence[shapes.Color]] = None,
# ) -> List[PrefabConfig]:
# def build_avatar_badges(
#     num_players: int,
#     prefabs: Optional[Mapping[str, PrefabConfig]] = None,
#     badge_palettes: Optional[Sequence[shapes.Color]] = None,
# ) -> List[PrefabConfig]:
# def get_game_object_positions_from_map(
#     ascii_map: str, char: str, orientation_mode: str = "always_north"
#     ) -> Sequence[Transform]:
# def _create_game_object(
#     prefab: PrefabConfig, transform: Transform) -> PrefabConfig:
# def get_game_objects_from_map(
#     ascii_map: str,
#     char_prefab_map: Mapping[str, str],
#     prefabs: Mapping[str, PrefabConfig],
#     random: np.random.RandomState = np.random.RandomState()
# ) -> List[PrefabConfig]:
# 
# Path: meltingpot/python/utils/substrates/wrappers/reset_wrapper.py
# class ResetWrapper(base.Wrapper):
#   def __init__(self, build_environment: Callable[[], dmlab2d.Environment]):
#   def reset(self) -> dm_env.TimeStep:


import copy
import itertools
import os
import pathlib  # pylint: disable=unused-import
import random
import tree
import dmlab2d
from typing import Any, Dict, Optional, Union
from absl import logging
from ml_collections import config_dict
from dmlab2d import runfiles_helper
from dmlab2d import settings_helper
from meltingpot.python.utils.substrates import game_object_utils
from meltingpot.python.utils.substrates.wrappers import reset_wrapper

  assert "simulation" in lab2d_settings

  # Copy config, so as not to modify it.
  lab2d_settings = config_dict.ConfigDict(
      copy.deepcopy(lab2d_settings)).unlock()

  apply_prefab_overrides(lab2d_settings, prefab_overrides)
  maybe_build_and_add_avatar_objects(lab2d_settings)
  locate_and_overwrite_level_directory(lab2d_settings)

  # Convert settings from python to Lua format.
  lab2d_settings_dict = parse_python_settings_for_dmlab2d(lab2d_settings)

  if env_seed is None:
    # Select a long seed different than zero.
    env_seed = random.randint(1, _MAX_SEED)
  env_seeds = (seed % (_MAX_SEED + 1) for seed in itertools.count(env_seed))

  def build_environment():
    seed = next(env_seeds)
    lab2d_settings_dict["env_seed"] = str(seed)  # Sets the Lua seed.
    env_raw = dmlab2d.Lab2d(_DMLAB2D_ROOT, lab2d_settings_dict)
    observation_names = env_raw.observation_names()
    return dmlab2d.Environment(
        env=env_raw,
        observation_names=observation_names,
        seed=seed)

  # Add a wrapper that rebuilds the environment when reset is called.

# Path: meltingpot/python/utils/substrates/game_object_utils.py
# class Position(NamedTuple):
# class Orientation(enum.Enum):
# class Transform(NamedTuple):
#   NORTH = "N"
#   EAST = "E"
#   SOUTH = "S"
#   WEST = "W"
# TYPE_ALL = "all"
# TYPE_CHOICE = "choice"
# def get_named_components(
#     game_object_config: PrefabConfig,
#     name: str):
# def get_first_named_component(
#     game_object_config: PrefabConfig,
#     name: str):
# def build_game_objects(
#     num_players: int,
#     ascii_map: str,
#     prefabs: Optional[Mapping[str, PrefabConfig]] = None,
#     char_prefab_map: Optional[PrefabConfig] = None,
#     player_palettes: Optional[Sequence[shapes.Color]] = None,
#     use_badges: bool = False,
#     badge_palettes: Optional[Sequence[shapes.Color]] = None,
# ) -> Tuple[List[PrefabConfig], List[PrefabConfig]]:
# def build_avatar_objects(
#     num_players: int,
#     prefabs: Optional[Mapping[str, PrefabConfig]] = None,
#     player_palettes: Optional[Sequence[shapes.Color]] = None,
# ) -> List[PrefabConfig]:
# def build_avatar_badges(
#     num_players: int,
#     prefabs: Optional[Mapping[str, PrefabConfig]] = None,
#     badge_palettes: Optional[Sequence[shapes.Color]] = None,
# ) -> List[PrefabConfig]:
# def get_game_object_positions_from_map(
#     ascii_map: str, char: str, orientation_mode: str = "always_north"
#     ) -> Sequence[Transform]:
# def _create_game_object(
#     prefab: PrefabConfig, transform: Transform) -> PrefabConfig:
# def get_game_objects_from_map(
#     ascii_map: str,
#     char_prefab_map: Mapping[str, str],
#     prefabs: Mapping[str, PrefabConfig],
#     random: np.random.RandomState = np.random.RandomState()
# ) -> List[PrefabConfig]:
# 
# Path: meltingpot/python/utils/substrates/wrappers/reset_wrapper.py
# class ResetWrapper(base.Wrapper):
#   def __init__(self, build_environment: Callable[[], dmlab2d.Environment]):
#   def reset(self) -> dm_env.TimeStep:


# Path: meltingpot/python/utils/substrates/builder.py
import copy
import itertools
import os
import pathlib  # pylint: disable=unused-import
import random
import tree
import dmlab2d
from typing import Any, Dict, Optional, Union
from absl import logging
from ml_collections import config_dict
from dmlab2d import runfiles_helper
from dmlab2d import settings_helper
from meltingpot.python.utils.substrates import game_object_utils
from meltingpot.python.utils.substrates.wrappers import reset_wrapper


  assert "simulation" in lab2d_settings

  # Copy config, so as not to modify it.
  lab2d_settings = config_dict.ConfigDict(
      copy.deepcopy(lab2d_settings)).unlock()

  apply_prefab_overrides(lab2d_settings, prefab_overrides)
  maybe_build_and_add_avatar_objects(lab2d_settings)
  locate_and_overwrite_level_directory(lab2d_settings)

  # Convert settings from python to Lua format.
  lab2d_settings_dict = parse_python_settings_for_dmlab2d(lab2d_settings)

  if env_seed is None:
    # Select a long seed different than zero.
    env_seed = random.randint(1, _MAX_SEED)
  env_seeds = (seed % (_MAX_SEED + 1) for seed in itertools.count(env_seed))

  def build_environment():
    seed = next(env_seeds)
    lab2d_settings_dict["env_seed"] = str(seed)  # Sets the Lua seed.
    env_raw = dmlab2d.Lab2d(_DMLAB2D_ROOT, lab2d_settings_dict)
    observation_names = env_raw.observation_names()
    return dmlab2d.Environment(
        env=env_raw,
        observation_names=observation_names,
        seed=seed)

  # Add a wrapper that rebuilds the environment when reset is called.

  env = reset_wrapper.ResetWrapper(build_environment)