diff --git a/test/general/test_fill.py b/test/general/test_fill.py index 5f44c54c0d8b..489417771d2a 100644 --- a/test/general/test_fill.py +++ b/test/general/test_fill.py @@ -11,30 +11,30 @@ from worlds.generic.Rules import CollectionRule, add_item_rule, locality_rules, set_rule -def generate_multi_world(players: int = 1) -> MultiWorld: - multi_world = MultiWorld(players) - multi_world.player_name = {} - multi_world.state = CollectionState(multi_world) +def generate_multiworld(players: int = 1) -> MultiWorld: + multiworld = MultiWorld(players) + multiworld.player_name = {} + multiworld.state = CollectionState(multiworld) for i in range(players): player_id = i+1 - world = World(multi_world, player_id) - multi_world.game[player_id] = f"Game {player_id}" - multi_world.worlds[player_id] = world - multi_world.player_name[player_id] = "Test Player " + str(player_id) - region = Region("Menu", player_id, multi_world, "Menu Region Hint") - multi_world.regions.append(region) + world = World(multiworld, player_id) + multiworld.game[player_id] = f"Game {player_id}" + multiworld.worlds[player_id] = world + multiworld.player_name[player_id] = "Test Player " + str(player_id) + region = Region("Menu", player_id, multiworld, "Menu Region Hint") + multiworld.regions.append(region) for option_key, option in Options.PerGameCommonOptions.type_hints.items(): - if hasattr(multi_world, option_key): - getattr(multi_world, option_key).setdefault(player_id, option.from_any(getattr(option, "default"))) + if hasattr(multiworld, option_key): + getattr(multiworld, option_key).setdefault(player_id, option.from_any(getattr(option, "default"))) else: - setattr(multi_world, option_key, {player_id: option.from_any(getattr(option, "default"))}) + setattr(multiworld, option_key, {player_id: option.from_any(getattr(option, "default"))}) # TODO - remove this loop once all worlds use options dataclasses - world.options = world.options_dataclass(**{option_key: getattr(multi_world, option_key)[player_id] + world.options = world.options_dataclass(**{option_key: getattr(multiworld, option_key)[player_id] for option_key in world.options_dataclass.type_hints}) - multi_world.set_seed(0) + multiworld.set_seed(0) - return multi_world + return multiworld class PlayerDefinition(object): @@ -46,8 +46,8 @@ class PlayerDefinition(object): basic_items: List[Item] regions: List[Region] - def __init__(self, multi_world: MultiWorld, id: int, menu: Region, locations: List[Location] = [], prog_items: List[Item] = [], basic_items: List[Item] = []): - self.multiworld = multi_world + def __init__(self, multiworld: MultiWorld, id: int, menu: Region, locations: List[Location] = [], prog_items: List[Item] = [], basic_items: List[Item] = []): + self.multiworld = multiworld self.id = id self.menu = menu self.locations = locations @@ -72,7 +72,7 @@ def generate_region(self, parent: Region, size: int, access_rule: CollectionRule return region -def fill_region(multi_world: MultiWorld, region: Region, items: List[Item]) -> List[Item]: +def fill_region(multiworld: MultiWorld, region: Region, items: List[Item]) -> List[Item]: items = items.copy() while len(items) > 0: location = region.locations.pop(0) @@ -80,7 +80,7 @@ def fill_region(multi_world: MultiWorld, region: Region, items: List[Item]) -> L if location.item: return items item = items.pop(0) - multi_world.push_item(location, item, False) + multiworld.push_item(location, item, False) location.event = item.advancement return items @@ -94,15 +94,15 @@ def region_contains(region: Region, item: Item) -> bool: return False -def generate_player_data(multi_world: MultiWorld, player_id: int, location_count: int = 0, prog_item_count: int = 0, basic_item_count: int = 0) -> PlayerDefinition: - menu = multi_world.get_region("Menu", player_id) +def generate_player_data(multiworld: MultiWorld, player_id: int, location_count: int = 0, prog_item_count: int = 0, basic_item_count: int = 0) -> PlayerDefinition: + menu = multiworld.get_region("Menu", player_id) locations = generate_locations(location_count, player_id, None, menu) prog_items = generate_items(prog_item_count, player_id, True) - multi_world.itempool += prog_items + multiworld.itempool += prog_items basic_items = generate_items(basic_item_count, player_id, False) - multi_world.itempool += basic_items + multiworld.itempool += basic_items - return PlayerDefinition(multi_world, player_id, menu, locations, prog_items, basic_items) + return PlayerDefinition(multiworld, player_id, menu, locations, prog_items, basic_items) def generate_locations(count: int, player_id: int, address: int = None, region: Region = None, tag: str = "") -> List[Location]: @@ -134,15 +134,15 @@ def names(objs: list) -> Iterable[str]: class TestFillRestrictive(unittest.TestCase): def test_basic_fill(self): """Tests `fill_restrictive` fills and removes the locations and items from their respective lists""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 2, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 2, 2) item0 = player1.prog_items[0] item1 = player1.prog_items[1] loc0 = player1.locations[0] loc1 = player1.locations[1] - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, player1.locations, player1.prog_items) self.assertEqual(loc0.item, item1) @@ -152,16 +152,16 @@ def test_basic_fill(self): def test_ordered_fill(self): """Tests `fill_restrictive` fulfills set rules""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 2, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 2, 2) items = player1.prog_items locations = player1.locations - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( items[0].name, player1.id) and state.has(items[1].name, player1.id) set_rule(locations[1], lambda state: state.has( items[0].name, player1.id)) - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, player1.locations.copy(), player1.prog_items.copy()) self.assertEqual(locations[0].item, items[0]) @@ -169,8 +169,8 @@ def test_ordered_fill(self): def test_partial_fill(self): """Tests that `fill_restrictive` returns unfilled locations""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 3, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 3, 2) item0 = player1.prog_items[0] item1 = player1.prog_items[1] @@ -178,14 +178,14 @@ def test_partial_fill(self): loc1 = player1.locations[1] loc2 = player1.locations[2] - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( item0.name, player1.id) and state.has(item1.name, player1.id) set_rule(loc1, lambda state: state.has( item0.name, player1.id)) # forces a swap set_rule(loc2, lambda state: state.has( item0.name, player1.id)) - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, player1.locations, player1.prog_items) self.assertEqual(loc0.item, item0) @@ -195,19 +195,19 @@ def test_partial_fill(self): def test_minimal_fill(self): """Test that fill for minimal player can have unreachable items""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 2, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 2, 2) items = player1.prog_items locations = player1.locations - multi_world.worlds[player1.id].options.accessibility = Accessibility.from_any(Accessibility.option_minimal) - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.worlds[player1.id].options.accessibility = Accessibility.from_any(Accessibility.option_minimal) + multiworld.completion_condition[player1.id] = lambda state: state.has( items[1].name, player1.id) set_rule(locations[1], lambda state: state.has( items[0].name, player1.id)) - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, player1.locations.copy(), player1.prog_items.copy()) self.assertEqual(locations[0].item, items[1]) @@ -220,15 +220,15 @@ def test_minimal_mixed_fill(self): the non-minimal player get all items. """ - multi_world = generate_multi_world(2) - player1 = generate_player_data(multi_world, 1, 3, 3) - player2 = generate_player_data(multi_world, 2, 3, 3) + multiworld = generate_multiworld(2) + player1 = generate_player_data(multiworld, 1, 3, 3) + player2 = generate_player_data(multiworld, 2, 3, 3) - multi_world.accessibility[player1.id].value = multi_world.accessibility[player1.id].option_minimal - multi_world.accessibility[player2.id].value = multi_world.accessibility[player2.id].option_locations + multiworld.accessibility[player1.id].value = multiworld.accessibility[player1.id].option_minimal + multiworld.accessibility[player2.id].value = multiworld.accessibility[player2.id].option_locations - multi_world.completion_condition[player1.id] = lambda state: True - multi_world.completion_condition[player2.id] = lambda state: state.has(player2.prog_items[2].name, player2.id) + multiworld.completion_condition[player1.id] = lambda state: True + multiworld.completion_condition[player2.id] = lambda state: state.has(player2.prog_items[2].name, player2.id) set_rule(player1.locations[1], lambda state: state.has(player1.prog_items[0].name, player1.id)) set_rule(player1.locations[2], lambda state: state.has(player1.prog_items[1].name, player1.id)) @@ -241,28 +241,28 @@ def test_minimal_mixed_fill(self): # fill remaining locations with remaining items location_pool = player1.locations[1:] + player2.locations item_pool = player1.prog_items[:-1] + player2.prog_items - fill_restrictive(multi_world, multi_world.state, location_pool, item_pool) - multi_world.state.sweep_for_events() # collect everything + fill_restrictive(multiworld, multiworld.state, location_pool, item_pool) + multiworld.state.sweep_for_events() # collect everything # all of player2's locations and items should be accessible (not all of player1's) for item in player2.prog_items: - self.assertTrue(multi_world.state.has(item.name, player2.id), + self.assertTrue(multiworld.state.has(item.name, player2.id), f'{item} is unreachable in {item.location}') def test_reversed_fill(self): """Test a different set of rules can be satisfied""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 2, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 2, 2) item0 = player1.prog_items[0] item1 = player1.prog_items[1] loc0 = player1.locations[0] loc1 = player1.locations[1] - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( item0.name, player1.id) and state.has(item1.name, player1.id) set_rule(loc1, lambda state: state.has(item1.name, player1.id)) - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, player1.locations, player1.prog_items) self.assertEqual(loc0.item, item1) @@ -270,13 +270,13 @@ def test_reversed_fill(self): def test_multi_step_fill(self): """Test that fill is able to satisfy multiple spheres""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 4, 4) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 4, 4) items = player1.prog_items locations = player1.locations - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( items[2].name, player1.id) and state.has(items[3].name, player1.id) set_rule(locations[1], lambda state: state.has( items[0].name, player1.id)) @@ -285,7 +285,7 @@ def test_multi_step_fill(self): set_rule(locations[3], lambda state: state.has( items[1].name, player1.id)) - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, player1.locations.copy(), player1.prog_items.copy()) self.assertEqual(locations[0].item, items[1]) @@ -295,25 +295,25 @@ def test_multi_step_fill(self): def test_impossible_fill(self): """Test that fill raises an error when it can't place any items""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 2, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 2, 2) items = player1.prog_items locations = player1.locations - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( items[0].name, player1.id) and state.has(items[1].name, player1.id) set_rule(locations[1], lambda state: state.has( items[1].name, player1.id)) set_rule(locations[0], lambda state: state.has( items[0].name, player1.id)) - self.assertRaises(FillError, fill_restrictive, multi_world, multi_world.state, + self.assertRaises(FillError, fill_restrictive, multiworld, multiworld.state, player1.locations.copy(), player1.prog_items.copy()) def test_circular_fill(self): """Test that fill raises an error when it can't place all items""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 3, 3) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 3, 3) item0 = player1.prog_items[0] item1 = player1.prog_items[1] @@ -322,46 +322,46 @@ def test_circular_fill(self): loc1 = player1.locations[1] loc2 = player1.locations[2] - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( item0.name, player1.id) and state.has(item1.name, player1.id) and state.has(item2.name, player1.id) set_rule(loc1, lambda state: state.has(item0.name, player1.id)) set_rule(loc2, lambda state: state.has(item1.name, player1.id)) set_rule(loc0, lambda state: state.has(item2.name, player1.id)) - self.assertRaises(FillError, fill_restrictive, multi_world, multi_world.state, + self.assertRaises(FillError, fill_restrictive, multiworld, multiworld.state, player1.locations.copy(), player1.prog_items.copy()) def test_competing_fill(self): """Test that fill raises an error when it can't place items in a way to satisfy the conditions""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 2, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 2, 2) item0 = player1.prog_items[0] item1 = player1.prog_items[1] loc1 = player1.locations[1] - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( item0.name, player1.id) and state.has(item0.name, player1.id) and state.has(item1.name, player1.id) set_rule(loc1, lambda state: state.has(item0.name, player1.id) and state.has(item1.name, player1.id)) - self.assertRaises(FillError, fill_restrictive, multi_world, multi_world.state, + self.assertRaises(FillError, fill_restrictive, multiworld, multiworld.state, player1.locations.copy(), player1.prog_items.copy()) def test_multiplayer_fill(self): """Test that items can be placed across worlds""" - multi_world = generate_multi_world(2) - player1 = generate_player_data(multi_world, 1, 2, 2) - player2 = generate_player_data(multi_world, 2, 2, 2) + multiworld = generate_multiworld(2) + player1 = generate_player_data(multiworld, 1, 2, 2) + player2 = generate_player_data(multiworld, 2, 2, 2) - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( player1.prog_items[0].name, player1.id) and state.has( player1.prog_items[1].name, player1.id) - multi_world.completion_condition[player2.id] = lambda state: state.has( + multiworld.completion_condition[player2.id] = lambda state: state.has( player2.prog_items[0].name, player2.id) and state.has( player2.prog_items[1].name, player2.id) - fill_restrictive(multi_world, multi_world.state, player1.locations + + fill_restrictive(multiworld, multiworld.state, player1.locations + player2.locations, player1.prog_items + player2.prog_items) self.assertEqual(player1.locations[0].item, player1.prog_items[1]) @@ -371,21 +371,21 @@ def test_multiplayer_fill(self): def test_multiplayer_rules_fill(self): """Test that fill across worlds satisfies the rules""" - multi_world = generate_multi_world(2) - player1 = generate_player_data(multi_world, 1, 2, 2) - player2 = generate_player_data(multi_world, 2, 2, 2) + multiworld = generate_multiworld(2) + player1 = generate_player_data(multiworld, 1, 2, 2) + player2 = generate_player_data(multiworld, 2, 2, 2) - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( player1.prog_items[0].name, player1.id) and state.has( player1.prog_items[1].name, player1.id) - multi_world.completion_condition[player2.id] = lambda state: state.has( + multiworld.completion_condition[player2.id] = lambda state: state.has( player2.prog_items[0].name, player2.id) and state.has( player2.prog_items[1].name, player2.id) set_rule(player2.locations[1], lambda state: state.has( player2.prog_items[0].name, player2.id)) - fill_restrictive(multi_world, multi_world.state, player1.locations + + fill_restrictive(multiworld, multiworld.state, player1.locations + player2.locations, player1.prog_items + player2.prog_items) self.assertEqual(player1.locations[0].item, player2.prog_items[0]) @@ -395,10 +395,10 @@ def test_multiplayer_rules_fill(self): def test_restrictive_progress(self): """Test that various spheres with different requirements can be filled""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, prog_item_count=25) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, prog_item_count=25) items = player1.prog_items.copy() - multi_world.completion_condition[player1.id] = lambda state: state.has_all( + multiworld.completion_condition[player1.id] = lambda state: state.has_all( names(player1.prog_items), player1.id) player1.generate_region(player1.menu, 5) @@ -411,16 +411,16 @@ def test_restrictive_progress(self): player1.generate_region(player1.menu, 5, lambda state: state.has_all( names(items[17:22]), player1.id)) - locations = multi_world.get_unfilled_locations() + locations = multiworld.get_unfilled_locations() - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, locations, player1.prog_items) def test_swap_to_earlier_location_with_item_rule(self): """Test that item swap happens and works as intended""" # test for PR#1109 - multi_world = generate_multi_world(1) - player1 = generate_player_data(multi_world, 1, 4, 4) + multiworld = generate_multiworld(1) + player1 = generate_player_data(multiworld, 1, 4, 4) locations = player1.locations[:] # copy required items = player1.prog_items[:] # copy required # for the test to work, item and location order is relevant: Sphere 1 last, allowed_item not last @@ -437,15 +437,15 @@ def test_swap_to_earlier_location_with_item_rule(self): self.assertTrue(sphere1_loc.can_fill(None, allowed_item, False), "Test is flawed") self.assertFalse(sphere1_loc.can_fill(None, items[2], False), "Test is flawed") # fill has to place items[1] in locations[0] which will result in a swap because of placement order - fill_restrictive(multi_world, multi_world.state, player1.locations, player1.prog_items) + fill_restrictive(multiworld, multiworld.state, player1.locations, player1.prog_items) # assert swap happened self.assertTrue(sphere1_loc.item, "Did not swap required item into Sphere 1") self.assertEqual(sphere1_loc.item, allowed_item, "Wrong item in Sphere 1") def test_swap_to_earlier_location_with_item_rule2(self): """Test that swap works before all items are placed""" - multi_world = generate_multi_world(1) - player1 = generate_player_data(multi_world, 1, 5, 5) + multiworld = generate_multiworld(1) + player1 = generate_player_data(multiworld, 1, 5, 5) locations = player1.locations[:] # copy required items = player1.prog_items[:] # copy required # Two items provide access to sphere 2. @@ -477,7 +477,7 @@ def test_swap_to_earlier_location_with_item_rule2(self): # Now fill should place one_to_two1 in sphere1_loc1 or sphere1_loc2 via swap, # which it will attempt before two_to_three and three_to_four are placed, testing the behavior. - fill_restrictive(multi_world, multi_world.state, player1.locations, player1.prog_items) + fill_restrictive(multiworld, multiworld.state, player1.locations, player1.prog_items) # assert swap happened self.assertTrue(sphere1_loc1.item and sphere1_loc2.item, "Did not swap required item into Sphere 1") self.assertTrue(sphere1_loc1.item.name == one_to_two1 or @@ -486,29 +486,29 @@ def test_swap_to_earlier_location_with_item_rule2(self): def test_double_sweep(self): """Test that sweep doesn't duplicate Event items when sweeping""" # test for PR1114 - multi_world = generate_multi_world(1) - player1 = generate_player_data(multi_world, 1, 1, 1) + multiworld = generate_multiworld(1) + player1 = generate_player_data(multiworld, 1, 1, 1) location = player1.locations[0] location.address = None location.event = True item = player1.prog_items[0] item.code = None location.place_locked_item(item) - multi_world.state.sweep_for_events() - multi_world.state.sweep_for_events() - self.assertTrue(multi_world.state.prog_items[item.player][item.name], "Sweep did not collect - Test flawed") - self.assertEqual(multi_world.state.prog_items[item.player][item.name], 1, "Sweep collected multiple times") + multiworld.state.sweep_for_events() + multiworld.state.sweep_for_events() + self.assertTrue(multiworld.state.prog_items[item.player][item.name], "Sweep did not collect - Test flawed") + self.assertEqual(multiworld.state.prog_items[item.player][item.name], 1, "Sweep collected multiple times") def test_correct_item_instance_removed_from_pool(self): """Test that a placed item gets removed from the submitted pool""" - multi_world = generate_multi_world() - player1 = generate_player_data(multi_world, 1, 2, 2) + multiworld = generate_multiworld() + player1 = generate_player_data(multiworld, 1, 2, 2) player1.prog_items[0].name = "Different_item_instance_but_same_item_name" player1.prog_items[1].name = "Different_item_instance_but_same_item_name" loc0 = player1.locations[0] - fill_restrictive(multi_world, multi_world.state, + fill_restrictive(multiworld, multiworld.state, [loc0], player1.prog_items) self.assertEqual(1, len(player1.prog_items)) @@ -518,14 +518,14 @@ def test_correct_item_instance_removed_from_pool(self): class TestDistributeItemsRestrictive(unittest.TestCase): def test_basic_distribute(self): """Test that distribute_items_restrictive is deterministic""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) locations = player1.locations prog_items = player1.prog_items basic_items = player1.basic_items - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertEqual(locations[0].item, basic_items[1]) self.assertFalse(locations[0].event) @@ -538,52 +538,52 @@ def test_basic_distribute(self): def test_excluded_distribute(self): """Test that distribute_items_restrictive doesn't put advancement items on excluded locations""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) locations = player1.locations locations[1].progress_type = LocationProgressType.EXCLUDED locations[2].progress_type = LocationProgressType.EXCLUDED - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertFalse(locations[1].item.advancement) self.assertFalse(locations[2].item.advancement) def test_non_excluded_item_distribute(self): """Test that useful items aren't placed on excluded locations""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) locations = player1.locations basic_items = player1.basic_items locations[1].progress_type = LocationProgressType.EXCLUDED basic_items[1].classification = ItemClassification.useful - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertEqual(locations[1].item, basic_items[0]) def test_too_many_excluded_distribute(self): """Test that fill fails if it can't place all progression items due to too many excluded locations""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) locations = player1.locations locations[0].progress_type = LocationProgressType.EXCLUDED locations[1].progress_type = LocationProgressType.EXCLUDED locations[2].progress_type = LocationProgressType.EXCLUDED - self.assertRaises(FillError, distribute_items_restrictive, multi_world) + self.assertRaises(FillError, distribute_items_restrictive, multiworld) def test_non_excluded_item_must_distribute(self): """Test that fill fails if it can't place useful items due to too many excluded locations""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) locations = player1.locations basic_items = player1.basic_items @@ -592,47 +592,47 @@ def test_non_excluded_item_must_distribute(self): basic_items[0].classification = ItemClassification.useful basic_items[1].classification = ItemClassification.useful - self.assertRaises(FillError, distribute_items_restrictive, multi_world) + self.assertRaises(FillError, distribute_items_restrictive, multiworld) def test_priority_distribute(self): """Test that priority locations receive advancement items""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) locations = player1.locations locations[0].progress_type = LocationProgressType.PRIORITY locations[3].progress_type = LocationProgressType.PRIORITY - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertTrue(locations[0].item.advancement) self.assertTrue(locations[3].item.advancement) def test_excess_priority_distribute(self): """Test that if there's more priority locations than advancement items, they can still fill""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) locations = player1.locations locations[0].progress_type = LocationProgressType.PRIORITY locations[1].progress_type = LocationProgressType.PRIORITY locations[2].progress_type = LocationProgressType.PRIORITY - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertFalse(locations[3].item.advancement) def test_multiple_world_priority_distribute(self): """Test that priority fill can be satisfied for multiple worlds""" - multi_world = generate_multi_world(3) + multiworld = generate_multiworld(3) player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) player2 = generate_player_data( - multi_world, 2, 4, prog_item_count=1, basic_item_count=3) + multiworld, 2, 4, prog_item_count=1, basic_item_count=3) player3 = generate_player_data( - multi_world, 3, 6, prog_item_count=4, basic_item_count=2) + multiworld, 3, 6, prog_item_count=4, basic_item_count=2) player1.locations[2].progress_type = LocationProgressType.PRIORITY player1.locations[3].progress_type = LocationProgressType.PRIORITY @@ -644,7 +644,7 @@ def test_multiple_world_priority_distribute(self): player3.locations[2].progress_type = LocationProgressType.PRIORITY player3.locations[3].progress_type = LocationProgressType.PRIORITY - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertTrue(player1.locations[2].item.advancement) self.assertTrue(player1.locations[3].item.advancement) @@ -656,9 +656,9 @@ def test_multiple_world_priority_distribute(self): def test_can_remove_locations_in_fill_hook(self): """Test that distribute_items_restrictive calls the fill hook and allows for item and location removal""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, 4, prog_item_count=2, basic_item_count=2) + multiworld, 1, 4, prog_item_count=2, basic_item_count=2) removed_item: list[Item] = [] removed_location: list[Location] = [] @@ -667,21 +667,21 @@ def fill_hook(progitempool, usefulitempool, filleritempool, fill_locations): removed_item.append(filleritempool.pop(0)) removed_location.append(fill_locations.pop(0)) - multi_world.worlds[player1.id].fill_hook = fill_hook + multiworld.worlds[player1.id].fill_hook = fill_hook - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertIsNone(removed_item[0].location) self.assertIsNone(removed_location[0].item) def test_seed_robust_to_item_order(self): """Test deterministic fill""" - mw1 = generate_multi_world() + mw1 = generate_multiworld() gen1 = generate_player_data( mw1, 1, 4, prog_item_count=2, basic_item_count=2) distribute_items_restrictive(mw1) - mw2 = generate_multi_world() + mw2 = generate_multiworld() gen2 = generate_player_data( mw2, 1, 4, prog_item_count=2, basic_item_count=2) mw2.itempool.append(mw2.itempool.pop(0)) @@ -694,12 +694,12 @@ def test_seed_robust_to_item_order(self): def test_seed_robust_to_location_order(self): """Test deterministic fill even if locations in a region are reordered""" - mw1 = generate_multi_world() + mw1 = generate_multiworld() gen1 = generate_player_data( mw1, 1, 4, prog_item_count=2, basic_item_count=2) distribute_items_restrictive(mw1) - mw2 = generate_multi_world() + mw2 = generate_multiworld() gen2 = generate_player_data( mw2, 1, 4, prog_item_count=2, basic_item_count=2) reg = mw2.get_region("Menu", gen2.id) @@ -713,45 +713,45 @@ def test_seed_robust_to_location_order(self): def test_can_reserve_advancement_items_for_general_fill(self): """Test that priority locations fill still satisfies item rules""" - multi_world = generate_multi_world() + multiworld = generate_multiworld() player1 = generate_player_data( - multi_world, 1, location_count=5, prog_item_count=5) + multiworld, 1, location_count=5, prog_item_count=5) items = player1.prog_items - multi_world.completion_condition[player1.id] = lambda state: state.has_all( + multiworld.completion_condition[player1.id] = lambda state: state.has_all( names(items), player1.id) location = player1.locations[0] location.progress_type = LocationProgressType.PRIORITY location.item_rule = lambda item: item not in items[:4] - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) self.assertEqual(location.item, items[4]) def test_non_excluded_local_items(self): """Test that local items get placed locally in a multiworld""" - multi_world = generate_multi_world(2) + multiworld = generate_multiworld(2) player1 = generate_player_data( - multi_world, 1, location_count=5, basic_item_count=5) + multiworld, 1, location_count=5, basic_item_count=5) player2 = generate_player_data( - multi_world, 2, location_count=5, basic_item_count=5) + multiworld, 2, location_count=5, basic_item_count=5) - for item in multi_world.get_items(): + for item in multiworld.get_items(): item.classification = ItemClassification.useful - multi_world.local_items[player1.id].value = set(names(player1.basic_items)) - multi_world.local_items[player2.id].value = set(names(player2.basic_items)) - locality_rules(multi_world) + multiworld.local_items[player1.id].value = set(names(player1.basic_items)) + multiworld.local_items[player2.id].value = set(names(player2.basic_items)) + locality_rules(multiworld) - distribute_items_restrictive(multi_world) + distribute_items_restrictive(multiworld) - for item in multi_world.get_items(): + for item in multiworld.get_items(): self.assertEqual(item.player, item.location.player) self.assertFalse(item.location.event, False) def test_early_items(self) -> None: """Test that the early items API successfully places items early""" - mw = generate_multi_world(2) + mw = generate_multiworld(2) player1 = generate_player_data(mw, 1, location_count=5, basic_item_count=5) player2 = generate_player_data(mw, 2, location_count=5, basic_item_count=5) mw.early_items[1][player1.basic_items[0].name] = 1 @@ -810,19 +810,19 @@ def assertRegionContains(self, region: Region, item: Item) -> bool: "\n Contains" + str(list(map(lambda location: location.item, region.locations)))) def setUp(self) -> None: - multi_world = generate_multi_world(2) - self.multi_world = multi_world + multiworld = generate_multiworld(2) + self.multiworld = multiworld player1 = generate_player_data( - multi_world, 1, prog_item_count=2, basic_item_count=40) + multiworld, 1, prog_item_count=2, basic_item_count=40) self.player1 = player1 player2 = generate_player_data( - multi_world, 2, prog_item_count=2, basic_item_count=40) + multiworld, 2, prog_item_count=2, basic_item_count=40) self.player2 = player2 - multi_world.completion_condition[player1.id] = lambda state: state.has( + multiworld.completion_condition[player1.id] = lambda state: state.has( player1.prog_items[0].name, player1.id) and state.has( player1.prog_items[1].name, player1.id) - multi_world.completion_condition[player2.id] = lambda state: state.has( + multiworld.completion_condition[player2.id] = lambda state: state.has( player2.prog_items[0].name, player2.id) and state.has( player2.prog_items[1].name, player2.id) @@ -830,42 +830,42 @@ def setUp(self) -> None: # Sphere 1 region = player1.generate_region(player1.menu, 20) - items = fill_region(multi_world, region, [ + items = fill_region(multiworld, region, [ player1.prog_items[0]] + items) # Sphere 2 region = player1.generate_region( player1.regions[1], 20, lambda state: state.has(player1.prog_items[0].name, player1.id)) items = fill_region( - multi_world, region, [player1.prog_items[1], player2.prog_items[0]] + items) + multiworld, region, [player1.prog_items[1], player2.prog_items[0]] + items) # Sphere 3 region = player2.generate_region( player2.menu, 20, lambda state: state.has(player2.prog_items[0].name, player2.id)) - fill_region(multi_world, region, [player2.prog_items[1]] + items) + fill_region(multiworld, region, [player2.prog_items[1]] + items) def test_balances_progression(self) -> None: """Tests that progression balancing moves progression items earlier""" - self.multi_world.progression_balancing[self.player1.id].value = 50 - self.multi_world.progression_balancing[self.player2.id].value = 50 + self.multiworld.progression_balancing[self.player1.id].value = 50 + self.multiworld.progression_balancing[self.player2.id].value = 50 self.assertRegionContains( self.player1.regions[2], self.player2.prog_items[0]) - balance_multiworld_progression(self.multi_world) + balance_multiworld_progression(self.multiworld) self.assertRegionContains( self.player1.regions[1], self.player2.prog_items[0]) def test_balances_progression_light(self) -> None: """Test that progression balancing still moves items earlier on minimum value""" - self.multi_world.progression_balancing[self.player1.id].value = 1 - self.multi_world.progression_balancing[self.player2.id].value = 1 + self.multiworld.progression_balancing[self.player1.id].value = 1 + self.multiworld.progression_balancing[self.player2.id].value = 1 self.assertRegionContains( self.player1.regions[2], self.player2.prog_items[0]) - balance_multiworld_progression(self.multi_world) + balance_multiworld_progression(self.multiworld) # TODO: arrange for a result that's different from the default self.assertRegionContains( @@ -873,13 +873,13 @@ def test_balances_progression_light(self) -> None: def test_balances_progression_heavy(self) -> None: """Test that progression balancing moves items earlier on maximum value""" - self.multi_world.progression_balancing[self.player1.id].value = 99 - self.multi_world.progression_balancing[self.player2.id].value = 99 + self.multiworld.progression_balancing[self.player1.id].value = 99 + self.multiworld.progression_balancing[self.player2.id].value = 99 self.assertRegionContains( self.player1.regions[2], self.player2.prog_items[0]) - balance_multiworld_progression(self.multi_world) + balance_multiworld_progression(self.multiworld) # TODO: arrange for a result that's different from the default self.assertRegionContains( @@ -887,25 +887,25 @@ def test_balances_progression_heavy(self) -> None: def test_skips_balancing_progression(self) -> None: """Test that progression balancing is skipped when players have it disabled""" - self.multi_world.progression_balancing[self.player1.id].value = 0 - self.multi_world.progression_balancing[self.player2.id].value = 0 + self.multiworld.progression_balancing[self.player1.id].value = 0 + self.multiworld.progression_balancing[self.player2.id].value = 0 self.assertRegionContains( self.player1.regions[2], self.player2.prog_items[0]) - balance_multiworld_progression(self.multi_world) + balance_multiworld_progression(self.multiworld) self.assertRegionContains( self.player1.regions[2], self.player2.prog_items[0]) def test_ignores_priority_locations(self) -> None: """Test that progression items on priority locations don't get moved by balancing""" - self.multi_world.progression_balancing[self.player1.id].value = 50 - self.multi_world.progression_balancing[self.player2.id].value = 50 + self.multiworld.progression_balancing[self.player1.id].value = 50 + self.multiworld.progression_balancing[self.player2.id].value = 50 self.player2.prog_items[0].location.progress_type = LocationProgressType.PRIORITY - balance_multiworld_progression(self.multi_world) + balance_multiworld_progression(self.multiworld) self.assertRegionContains( self.player1.regions[2], self.player2.prog_items[0])