Beispiel #1
0
def test_edit_layout_quantity(option: Options,
                              initial_layout_configuration_params: dict):
    # Setup
    option._layout_configuration = LayoutConfiguration.from_params(**initial_layout_configuration_params)
    option._nested_autosave_level = 1
    pickup = next(option._layout_configuration.pickup_quantities.pickups())

    # Run
    initial_layout_configuration_params["pickup_quantities"] = {pickup.name: 12}
    option.set_quantity_for_pickup(pickup, 12)

    # Assert
    assert option.layout_configuration == LayoutConfiguration.from_params(**initial_layout_configuration_params)
Beispiel #2
0
def test_edit_layout_trick_level(option: Options,
                                 initial_layout_configuration_params: dict,
                                 new_trick_level: LayoutTrickLevel):
    # Setup
    option._layout_configuration = LayoutConfiguration.from_params(**initial_layout_configuration_params)
    option._nested_autosave_level = 1

    # Run
    initial_layout_configuration_params["trick_level"] = new_trick_level
    setattr(option, "layout_configuration_trick_level", new_trick_level)

    # Assert
    assert option.layout_configuration == LayoutConfiguration.from_params(**initial_layout_configuration_params)
def test_round_trip_generated_patches(echoes_game_data):
    # Setup
    configuration = LayoutConfiguration.from_params(
        trick_level_configuration=TrickLevelConfiguration(
            global_level=LayoutTrickLevel.MINIMAL_RESTRICTIONS,
            specific_levels={},
        ))

    patches = generator._create_randomized_patches(
        permalink=Permalink(
            seed_number=1000,
            spoiler=True,
            patcher_configuration=PatcherConfiguration.default(),
            layout_configuration=configuration,
        ),
        game=data_reader.decode_data(echoes_game_data),
        status_update=lambda x: None,
    )

    # Run
    encoded = game_patches_serializer.serialize(patches, echoes_game_data)
    decoded = game_patches_serializer.decode(encoded, configuration)

    # Assert
    assert patches == decoded
Beispiel #4
0
def test_distribute_command_logic(mock_generate_list: MagicMock, ):
    # Setup
    args = MagicMock()
    args.trick_level = LayoutTrickLevel.HARD.value
    args.major_items_mode = False
    args.sky_temple_keys = LayoutSkyTempleKeyMode.ALL_BOSSES.value
    args.skip_item_loss = True
    args.seed = 15000
    args.output_file = "asdfasdf/qwerqwerqwer/zxcvzxcv.json"

    # Run
    echoes.distribute_command_logic(args)

    # Assert
    mock_generate_list.assert_called_once_with(permalink=Permalink(
        seed_number=args.seed,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level=LayoutTrickLevel.HARD,
            sky_temple_keys=LayoutSkyTempleKeyMode.ALL_BOSSES,
            elevators=LayoutRandomizedFlag.VANILLA,
            pickup_quantities={},
            starting_location=StartingLocation.default(),
            starting_resources=StartingResources.from_non_custom_configuration(
                StartingResourcesConfiguration.VANILLA_ITEM_LOSS_DISABLED),
        ),
    ),
                                               status_update=ANY)

    save_file_mock: MagicMock = mock_generate_list.return_value.save_to_file
    save_file_mock.assert_called_once_with(Path(args.output_file))
def _layout_config_with_data(request):
    trick_config = DummyValue()
    starting_location = DummyValue()
    randomization_mode = DummyValue()
    major_items = DummyValue()
    ammo_config = DummyValue()
    translator_config = DummyValue()
    hints = DummyValue()

    with patch.multiple(TrickLevelConfiguration, bit_pack_unpack=MagicMock(return_value=trick_config)), \
         patch.multiple(StartingLocation, bit_pack_unpack=MagicMock(return_value=starting_location)), \
         patch.multiple(RandomizationMode, bit_pack_unpack=MagicMock(return_value=randomization_mode)), \
         patch.multiple(MajorItemsConfiguration, bit_pack_unpack=MagicMock(return_value=major_items)), \
         patch.multiple(AmmoConfiguration, bit_pack_unpack=MagicMock(return_value=ammo_config)), \
         patch.multiple(TranslatorConfiguration, bit_pack_unpack=MagicMock(return_value=translator_config)), \
         patch.multiple(HintConfiguration, bit_pack_unpack=MagicMock(return_value=hints)):
        yield request.param["encoded"], LayoutConfiguration.from_params(
            trick_level_configuration=trick_config,
            sky_temple_keys=request.param["sky_temple"],
            elevators=request.param["elevators"],
            starting_location=starting_location,
            randomization_mode=randomization_mode,
            major_items_configuration=major_items,
            ammo_configuration=ammo_config,
            translator_configuration=translator_config,
            hints=hints,
        )
def test_decode(mock_dictionary_byte_hash: MagicMock):
    mock_dictionary_byte_hash.return_value = 120
    # We're mocking the database hash to avoid breaking tests every single time we change the database

    # This test should break whenever we change how permalinks are created
    # When this happens, we must bump the permalink version and change the tests
    encoded = "gAAAfReLCAAC4wAAAOaANg=="

    expected = Permalink(
        seed_number=1000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration(
            menu_mod=True,
            warp_to_start=False,
        ),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level_configuration=TrickLevelConfiguration(
                LayoutTrickLevel.HARD),
            elevators=LayoutElevators.RANDOMIZED,
        ),
    )

    # Uncomment this line to quickly get the new encoded permalink
    # assert expected.as_str == ""
    # print(expected.as_str)

    # Run
    link = Permalink.from_str(encoded)

    # Assert
    assert link == expected
def test_create_permalink_logic(mock_print: MagicMock, ):
    # Setup
    args = MagicMock()
    args.trick_level = LayoutTrickLevel.HARD.value
    args.major_items_mode = False
    args.sky_temple_keys = LayoutSkyTempleKeyMode.ALL_BOSSES.value
    args.skip_item_loss = True
    args.seed = 15000
    args.menu_mod = False
    args.warp_to_start = False

    # Run
    randovania.cli.commands.create_permalink.create_permalink_logic(args)

    # Assert
    permalink = Permalink(
        seed_number=args.seed,
        spoiler=True,
        patcher_configuration=PatcherConfiguration(
            menu_mod=args.menu_mod,
            warp_to_start=args.warp_to_start,
        ),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level_configuration=TrickLevelConfiguration(
                LayoutTrickLevel.HARD),
            sky_temple_keys=LayoutSkyTempleKeyMode.ALL_BOSSES,
            elevators=LayoutElevators.VANILLA,
            starting_location=StartingLocation.default(),
        ),
    )

    # Assert
    mock_print.assert_called_once_with(permalink)
def test_edit_layout_trick_level(option: Options,
                                 initial_layout_configuration_params: dict,
                                 new_trick_level: LayoutTrickLevel):
    # Setup
    option._layout_configuration = LayoutConfiguration.from_params(
        **initial_layout_configuration_params)
    option._nested_autosave_level = 1

    # Run
    initial_layout_configuration_params[
        "trick_level_configuration"] = TrickLevelConfiguration(new_trick_level)
    option.set_layout_configuration_field(
        "trick_level_configuration", TrickLevelConfiguration(new_trick_level))

    # Assert
    assert option.layout_configuration == LayoutConfiguration.from_params(
        **initial_layout_configuration_params)
Beispiel #9
0
def get_layout_configuration_from_args(args) -> LayoutConfiguration:
    return LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel(args.trick_level),
        sky_temple_keys=LayoutSkyTempleKeyMode(args.sky_temple_keys),
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.from_item_loss(
            not args.skip_item_loss),
    )
Beispiel #10
0
def test_create_patches(
    mock_random: MagicMock,
    mock_calculate_item_pool: MagicMock,
    mock_create_base_patches: MagicMock,
    mock_retcon_playthrough_filler: MagicMock,
    mock_indices_for_unassigned_pickups: MagicMock,
):
    # Setup
    seed_number: int = 91319
    game = default_prime2_game_description()
    status_update: Union[MagicMock, Callable[[str], None]] = MagicMock()
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.from_item_loss(False),
    )
    permalink = Permalink(
        seed_number=seed_number,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    mock_calculate_item_pool.return_value = list(
        sorted(game.pickup_database.original_pickup_mapping.values()))
    mock_create_base_patches.return_value.starting_location = game.starting_location
    mock_create_base_patches.return_value.custom_initial_items = None

    filler_patches = mock_retcon_playthrough_filler.return_value

    # Run
    result = generator._create_patches(permalink, game, status_update)

    # Assert
    mock_random.assert_called_once_with(permalink.as_str)
    mock_calculate_item_pool.assert_called_once_with(permalink, game)

    mock_create_base_patches.assert_called_once_with(mock_random.return_value,
                                                     game, permalink, ANY)

    mock_retcon_playthrough_filler.assert_called_once_with(
        ANY, ANY, ANY, mock_random.return_value, status_update)

    mock_indices_for_unassigned_pickups.assert_called_once_with(
        mock_random.return_value, game, filler_patches.pickup_assignment, ANY)
    filler_patches.assign_new_pickups.assert_called_once_with(
        mock_indices_for_unassigned_pickups.return_value)

    assert result == filler_patches.assign_new_pickups.return_value
Beispiel #11
0
def get_layout_configuration_from_args(args) -> LayoutConfiguration:
    try:
        sky_temple_keys = int(args.sky_temple_keys)
    except ValueError:
        sky_temple_keys = args.sky_temple_keys

    # TODO: support for item loss
    return LayoutConfiguration.from_params(
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel(args.trick_level)),
        sky_temple_keys=LayoutSkyTempleKeyMode(sky_temple_keys),
        elevators=LayoutElevators.VANILLA,
        starting_location=StartingLocation.default(),
    )
def test_create_pickup_all_from_pool(echoes_resource_database,
                                     disable_hud_popup: bool
                                     ):
    layout_configuration = LayoutConfiguration.from_params()
    item_pool = pool_creator.calculate_pool_results(layout_configuration, echoes_resource_database)[0]
    index = PickupIndex(0)
    if disable_hud_popup:
        memo_data = None
    else:
        memo_data = default_prime2_memo_data()

    for item in item_pool:
        try:
            patcher_file._create_pickup(index, item, item, PickupModelStyle.ALL_VISIBLE, memo_data)
        except Exception as e:
            assert str(e) == item.name
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data)
    configuration = LayoutConfiguration.from_params()
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    patches = GamePatches.with_game(game)
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, game.resource_database, Random(15000)))
    game, state = logic_bootstrap(configuration, game, patches)

    return game, state, permalink
def test_calculate_reach_with_all_pickups(test_data):
    game, state, _ = test_data

    item_pool = calculate_item_pool(LayoutConfiguration.from_params(),
                                    game.resource_database, state.patches)
    add_resources_into_another(state.resources, item_pool[0].starting_items)
    for pickup in item_pool[1]:
        add_pickup_to_state(state, pickup)

    first_reach, second_reach = _create_reaches_and_compare(game, state)
    first_actions, second_actions = _compare_actions(first_reach, second_reach)

    found_pickups = set(
        filter_pickup_nodes(filter_reachable(second_reach.nodes, first_reach)))
    all_pickups = set(filter_pickup_nodes(game.world_list.all_nodes))

    # assert (len(list(first_reach.nodes)), len(first_actions)) == (898, 9)
    # assert (len(list(second_reach.nodes)), len(second_actions)) == (898, 9)
    pprint.pprint(first_actions)
    assert all_pickups == found_pickups
def test_reach_size_from_start(echoes_game_description):
    # Setup
    configuration = LayoutConfiguration.from_params(
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel.HYPERMODE), )
    patches = GamePatches.with_game(echoes_game_description)
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, echoes_game_description.resource_database,
            Random(15000)))

    game, state = logic_bootstrap(configuration, echoes_game_description,
                                  patches)

    # Run
    reach = GeneratorReach.reach_from_state(game, state)

    # Assert
    assert len(list(reach.nodes)) == 26
    assert len(list(reach.safe_nodes)) == 4
Beispiel #16
0
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data, False)
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    logic, state = logic_bootstrap(configuration, game,
                                   GamePatches.with_game(game))

    return logic, state, permalink
Beispiel #17
0
def test_generate_seed_with_invalid_quantity_configuration():
    # Setup
    status_update = MagicMock()

    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={"Light Suit": 5},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )

    permalink = Permalink(
        seed_number=50,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )

    # Run
    with pytest.raises(randovania.resolver.exceptions.GenerationFailure):
        generator.generate_list(permalink, status_update=status_update)
Beispiel #18
0
def test_decode_v1(mock_dictionary_byte_hash: MagicMock):
    mock_dictionary_byte_hash.return_value = 120
    # We're mocking the database hash to avoid breaking tests every single time we change the database

    # This test should break whenever we change how permalinks are created
    # When this happens, we must bump the permalink version and change the tests
    encoded = "IAAAfReNPArRHMClxLYgIID3"

    expected = Permalink(
        seed_number=1000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration(
            disable_hud_popup=True,
            menu_mod=True,
            speed_up_credits=False,
        ),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level=LayoutTrickLevel.HARD,
            sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
            elevators=LayoutRandomizedFlag.RANDOMIZED,
            pickup_quantities={
                "Missile Expansion": 10,
                "Light Suit": 9,
            },
            starting_location=StartingLocation.default(),
            starting_resources=StartingResources.default(),
        ),
    )

    # Uncomment this line to quickly get the new encoded permalink
    # assert expected.as_str == ""

    # Run
    link = Permalink.from_str(encoded)

    # Assert
    assert link == expected
        Permalink.from_str(invalid)


@pytest.mark.parametrize("spoiler", [False, True])
@pytest.mark.parametrize("patcher", [
    PatcherConfiguration.default(),
    PatcherConfiguration(
        menu_mod=True,
        warp_to_start=False,
    ),
])
@pytest.mark.parametrize("layout", [
    LayoutConfiguration.default(),
    LayoutConfiguration.from_params(
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel.HARD),
        sky_temple_keys=LayoutSkyTempleKeyMode.ALL_GUARDIANS,
        elevators=LayoutElevators.RANDOMIZED,
    ),
])
def test_round_trip(spoiler: bool, patcher: PatcherConfiguration,
                    layout: LayoutConfiguration):
    # Setup
    link = Permalink(
        seed_number=1000,
        spoiler=spoiler,
        patcher_configuration=patcher,
        layout_configuration=layout,
    )

    # Run
    after = Permalink.from_str(link.as_str)
Beispiel #20
0
@pytest.mark.parametrize("spoiler", [False, True])
@pytest.mark.parametrize("patcher", [
    PatcherConfiguration.default(),
    PatcherConfiguration(
        menu_mod=True,
        warp_to_start=False,
    ),
])
@pytest.mark.parametrize("layout", [
    LayoutConfiguration.default(),
    LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.HARD,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.RANDOMIZED,
        pickup_quantities={
            "Missile Expansion": 10,
            "Light Suit": 9,
        },
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    ),
])
def test_round_trip(spoiler: bool, patcher: PatcherConfiguration,
                    layout: LayoutConfiguration):
    # Setup
    link = Permalink(
        seed_number=1000,
        spoiler=spoiler,
        patcher_configuration=patcher,
        layout_configuration=layout,
    )
Beispiel #21
0
        patches=GamePatches.with_game(game).assign_new_pickups([
            (PickupIndex(i), pickup_database.original_pickup_mapping[PickupIndex(new_index)])
            for i, new_index in enumerate(pickup_mapping)
        ]),
        solver_path=())


# TODO: this permalink is impossible for solver: B6gWMhxALWmCI50gIQBs


_unused_test_descriptions = [
    _create_test_layout_description(
        configuration=LayoutConfiguration.from_params(trick_level=LayoutTrickLevel.NO_TRICKS,
                                                      sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
                                                      elevators=LayoutRandomizedFlag.VANILLA,
                                                      pickup_quantities={},
                                                      starting_location=StartingLocation.default(),
                                                      starting_resources=StartingResources.default(),
                                                      ),
        pickup_mapping=[2, 88, 4, 7, 4, 38, 23, 76, 2, 2, 2, 46, 57, 82, 24, 2, 106, 83, 2, 39, 37, 8, 69, 2, 15, 2, 52,
                        109, 1, 19, 2, 2, 91, 8, 2, 75, 8, 86, 2, 2, 79, 4, 43, 4, 2, 13, 0, 2, 2, 2, 4, 2, 4, 2, 4, 2,
                        74, 2, 2, 116, 2, 2, 2, 2, 2, 2, 2, 2, 68, 50, 2, 4, 21, 2, 2, 2, 112, 4, 45, 4, 8, 4, 17, 4, 2,
                        100, 2, 115, 8, 2, 24, 2, 4, 44, 17, 2, 2, 2, 102, 118, 11, 8, 2, 4, 2, 17, 92, 53, 2, 2, 59,
                        114, 2, 2, 8, 17, 8, 2, 117],
    ),
    _create_test_layout_description(
        configuration=LayoutConfiguration.from_params(trick_level=LayoutTrickLevel.NO_TRICKS,
                                                      sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
                                                      elevators=LayoutRandomizedFlag.VANILLA,
                                                      pickup_quantities={
                                                          "Missile Expansion": 0
def test_apply_layout(mock_run_with_args: MagicMock,
                      mock_base_args: MagicMock,
                      mock_ensure_no_menu_mod: MagicMock,
                      mock_create_pak_backups: MagicMock,
                      mock_calculate_indices: MagicMock,
                      mock_add_menu_mod_to_files: MagicMock,
                      mock_create_progress_update_from_successive_messages: MagicMock,
                      mock_save_to_file: MagicMock,
                      seed_number: int,
                      item_loss: bool,
                      elevators: bool,
                      warp_to_start: bool,
                      include_menu_mod: bool,
                      speed_up_credits: bool,
                      ):
    # Setup
    hud_memo_popup_removal: bool = MagicMock()
    cosmetic_patches = CosmeticPatches(disable_hud_popup=hud_memo_popup_removal,
                                       speed_up_credits=speed_up_credits,
                                       )
    description = LayoutDescription(
        version=randovania.VERSION,
        permalink=Permalink(
            seed_number=seed_number,
            spoiler=False,
            patcher_configuration=PatcherConfiguration(
                menu_mod=include_menu_mod,
                warp_to_start=warp_to_start,
            ),
            layout_configuration=LayoutConfiguration.from_params(
                trick_level=MagicMock(),
                sky_temple_keys=MagicMock(),
                elevators=LayoutRandomizedFlag.RANDOMIZED if elevators else LayoutRandomizedFlag.VANILLA,
                pickup_quantities={},
                starting_location=StartingLocation.default(),
                starting_resources=StartingResources.from_item_loss(item_loss),
            )
        ),
        patches=None,
        solver_path=(),
    )

    game_root = MagicMock(spec=Path())
    backup_files_path = MagicMock()
    progress_update = MagicMock()
    status_update = mock_create_progress_update_from_successive_messages.return_value

    mock_calculate_indices.return_value = [10, 25, 1, 2, 5, 1]
    mock_base_args.return_value = []
    expected_args = [
        "-s", str(seed_number),
        "-p", "10,25,1,2,5,1"
    ]
    if not item_loss:
        expected_args.append("-i")
    if elevators:
        expected_args.append("-v")
    if speed_up_credits:
        expected_args.append("-c")
    if warp_to_start:
        expected_args.append("-t")

    # Run
    claris_randomizer.apply_layout(description, cosmetic_patches, backup_files_path, progress_update, game_root)

    # Assert
    mock_base_args.assert_called_once_with(game_root, hud_memo_popup_removal=hud_memo_popup_removal)
    mock_create_progress_update_from_successive_messages.assert_called_once_with(
        progress_update,
        400 if include_menu_mod else 100
    )
    mock_ensure_no_menu_mod.assert_called_once_with(game_root, backup_files_path, status_update)
    mock_create_pak_backups.assert_called_once_with(game_root, backup_files_path, status_update)
    mock_calculate_indices.assert_called_once_with(description)
    game_root.joinpath.assert_called_once_with("files", "randovania.json")
    mock_save_to_file.assert_called_once_with(description, game_root.joinpath.return_value)
    mock_run_with_args.assert_called_once_with(expected_args, "Randomized!", status_update)
    if include_menu_mod:
        mock_add_menu_mod_to_files.assert_called_once_with(game_root, status_update)
    else:
        mock_add_menu_mod_to_files.assert_not_called()
Beispiel #23
0
_test_descriptions = [
    _create_test_layout_description(
        configuration=LayoutConfiguration.default(),
        pickup_mapping=[
            37, 2, 2, 68, 100, 38, 102, 109, 8, 17, 4, 69, 88, 13, 44, 2, 4, 2,
            74, 2, 27, 23, 2, 46, 43, 15, 2, 2, 50, 4, 24, 2, 2, 2, 2, 57, 2,
            2, 2, 4, 4, 115, 2, 53, 7, 2, 2, 59, 75, 8, 2, 52, 8, 2, 19, 112,
            2, 8, 17, 92, 2, 2, 79, 106, 2, 4, 2, 17, 4, 2, 2, 2, 2, 117, 2, 2,
            2, 17, 2, 8, 82, 8, 2, 4, 114, 118, 2, 91, 8, 4, 4, 11, 2, 2, 4, 1,
            2, 0, 4, 8, 2, 116, 2, 4, 2, 2, 86, 2, 2, 39, 2, 21, 2, 2, 45, 2,
            4, 76, 83
        ],
    ),
    _create_test_layout_description(
        configuration=LayoutConfiguration.from_params(
            trick_level_configuration=TrickLevelConfiguration(
                LayoutTrickLevel.HYPERMODE), ),
        pickup_mapping=[
            91, 45, 17, 24, 4, 2, 23, 59, 2, 0, 2, 68, 8, 38, 2, 2, 2, 7, 4,
            115, 37, 2, 86, 2, 76, 2, 4, 2, 117, 112, 17, 2, 2, 2, 13, 39, 88,
            82, 102, 50, 57, 2, 52, 116, 2, 4, 2, 8, 118, 2, 2, 2, 1, 2, 2, 53,
            74, 2, 2, 114, 4, 2, 4, 8, 2, 8, 2, 2, 19, 2, 43, 2, 2, 2, 2, 2, 2,
            8, 4, 2, 2, 2, 4, 109, 2, 4, 2, 4, 11, 8, 69, 92, 2, 4, 106, 17,
            17, 21, 75, 79, 2, 2, 2, 100, 2, 15, 83, 8, 4, 2, 2, 46, 24, 2, 4,
            44, 8, 4, 2
        ],
    ),
    _create_test_layout_description(
        configuration=LayoutConfiguration.from_params(
            trick_level_configuration=TrickLevelConfiguration(
                LayoutTrickLevel.MINIMAL_RESTRICTIONS),