| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  | import unittest | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from BaseClasses import CollectionState | 
					
						
							|  |  |  | from worlds.AutoWorld import AutoWorldRegister | 
					
						
							| 
									
										
										
										
											2025-01-20 16:07:15 +01:00
										 |  |  | from . import setup_solo_multiworld, gen_steps | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 03:32:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  | class TestBase(unittest.TestCase): | 
					
						
							| 
									
										
										
										
											2025-01-20 16:07:15 +01:00
										 |  |  |     gen_steps = gen_steps | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-19 23:09:54 +01:00
										 |  |  |     default_settings_unreachable_regions = { | 
					
						
							|  |  |  |         "A Link to the Past": { | 
					
						
							|  |  |  |             "Chris Houlihan Room",  # glitch room by definition | 
					
						
							|  |  |  |             "Desert Northern Cliffs",  # on top of mountain, only reachable via OWG | 
					
						
							|  |  |  |             "Dark Death Mountain Bunny Descent Area"  # OWG Mountain descent | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2024-08-20 17:18:28 -06:00
										 |  |  |         # These Blasphemous regions are not reachable with default options | 
					
						
							|  |  |  |         "Blasphemous": { | 
					
						
							|  |  |  |             "D01Z04S13[SE]", # difficulty must be hard | 
					
						
							|  |  |  |             "D01Z05S25[E]", # difficulty must be hard | 
					
						
							|  |  |  |             "D02Z02S05[W]", # difficulty must be hard and purified_hand must be true | 
					
						
							|  |  |  |             "D04Z01S06[E]", # purified_hand must be true | 
					
						
							|  |  |  |             "D04Z02S02[NE]", # difficulty must be hard and purified_hand must be true | 
					
						
							|  |  |  |             "D05Z01S11[SW]", # difficulty must be hard | 
					
						
							|  |  |  |             "D06Z01S08[N]", # difficulty must be hard and purified_hand must be true | 
					
						
							|  |  |  |             "D20Z02S11[NW]", # difficulty must be hard | 
					
						
							|  |  |  |             "D20Z02S11[E]", # difficulty must be hard | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2023-02-19 23:09:54 +01:00
										 |  |  |         "Ocarina of Time": { | 
					
						
							|  |  |  |             "Prelude of Light Warp",  # Prelude is not progression by default | 
					
						
							|  |  |  |             "Serenade of Water Warp",  # Serenade is not progression by default | 
					
						
							|  |  |  |             "Lost Woods Mushroom Timeout",  # trade quest starts after this item | 
					
						
							|  |  |  |             "ZD Eyeball Frog Timeout",  # trade quest starts after this item | 
					
						
							|  |  |  |             "ZR Top of Waterfall",  # dummy region used for entrance shuffle | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2023-05-31 04:16:39 +02:00
										 |  |  |         # The following SM regions are only used when the corresponding StartLocation option is selected (so not with | 
					
						
							|  |  |  |         # default settings). Also, those don't have any entrances as they serve as starting Region (that's why they | 
					
						
							|  |  |  |         # have to be excluded for testAllStateCanReachEverything). | 
					
						
							| 
									
										
										
										
											2023-02-19 23:09:54 +01:00
										 |  |  |         "Super Metroid": { | 
					
						
							|  |  |  |             "Ceres", | 
					
						
							|  |  |  |             "Gauntlet Top", | 
					
						
							|  |  |  |             "Mama Turtle" | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-22 06:00:27 -05:00
										 |  |  |     def test_default_all_state_can_reach_everything(self): | 
					
						
							|  |  |  |         """Ensure all state can reach everything and complete the game with the defined options""" | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  |         for game_name, world_type in AutoWorldRegister.world_types.items(): | 
					
						
							| 
									
										
										
										
											2023-06-29 13:36:48 -05:00
										 |  |  |             unreachable_regions = self.default_settings_unreachable_regions.get(game_name, set()) | 
					
						
							|  |  |  |             with self.subTest("Game", game=game_name): | 
					
						
							| 
									
										
										
										
											2024-02-04 18:38:00 -05:00
										 |  |  |                 multiworld = setup_solo_multiworld(world_type) | 
					
						
							|  |  |  |                 state = multiworld.get_all_state(False) | 
					
						
							|  |  |  |                 for location in multiworld.get_locations(): | 
					
						
							| 
									
										
										
										
											2024-08-16 14:49:37 -04:00
										 |  |  |                     with self.subTest("Location should be reached", location=location.name): | 
					
						
							|  |  |  |                         self.assertTrue(location.can_reach(state), f"{location.name} unreachable") | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-04 18:38:00 -05:00
										 |  |  |                 for region in multiworld.get_regions(): | 
					
						
							| 
									
										
										
										
											2023-07-18 04:18:26 +02:00
										 |  |  |                     if region.name in unreachable_regions: | 
					
						
							| 
									
										
										
										
											2024-07-01 13:47:40 -05:00
										 |  |  |                         with self.subTest("Region should be unreachable", region=region.name): | 
					
						
							| 
									
										
										
										
											2023-07-18 04:18:26 +02:00
										 |  |  |                             self.assertFalse(region.can_reach(state)) | 
					
						
							|  |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2024-07-01 13:47:40 -05:00
										 |  |  |                         with self.subTest("Region should be reached", region=region.name): | 
					
						
							| 
									
										
										
										
											2023-06-29 13:36:48 -05:00
										 |  |  |                             self.assertTrue(region.can_reach(state)) | 
					
						
							| 
									
										
										
										
											2023-02-19 23:09:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-29 13:36:48 -05:00
										 |  |  |                 with self.subTest("Completion Condition"): | 
					
						
							| 
									
										
										
										
											2024-02-04 18:38:00 -05:00
										 |  |  |                     self.assertTrue(multiworld.can_beat_game(state)) | 
					
						
							| 
									
										
										
										
											2022-05-10 19:48:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-22 06:00:27 -05:00
										 |  |  |     def test_default_empty_state_can_reach_something(self): | 
					
						
							|  |  |  |         """Ensure empty state can reach at least one location with the defined options""" | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  |         for game_name, world_type in AutoWorldRegister.world_types.items(): | 
					
						
							| 
									
										
										
										
											2023-05-31 04:16:39 +02:00
										 |  |  |             with self.subTest("Game", game=game_name): | 
					
						
							| 
									
										
										
										
											2024-02-04 18:38:00 -05:00
										 |  |  |                 multiworld = setup_solo_multiworld(world_type) | 
					
						
							|  |  |  |                 state = CollectionState(multiworld) | 
					
						
							|  |  |  |                 all_locations = multiworld.get_locations() | 
					
						
							| 
									
										
										
										
											2023-05-31 04:16:39 +02:00
										 |  |  |                 if all_locations: | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  |                     locations = set() | 
					
						
							| 
									
										
										
										
											2023-05-31 04:16:39 +02:00
										 |  |  |                     for location in all_locations: | 
					
						
							| 
									
										
										
										
											2021-10-21 20:23:13 +02:00
										 |  |  |                         if location.can_reach(state): | 
					
						
							|  |  |  |                             locations.add(location) | 
					
						
							|  |  |  |                     self.assertGreater(len(locations), 0, | 
					
						
							| 
									
										
										
										
											2022-02-20 14:19:20 -07:00
										 |  |  |                                        msg="Need to be able to reach at least one location to get started.") |