@@ -181,7 +181,7 @@ def _connect_one_way(self, source_exit: Entrance, target_entrance: Entrance) ->
181
181
self .pairings .append ((source_exit .name , target_entrance .name ))
182
182
183
183
def test_speculative_connection (self , source_exit : Entrance , target_entrance : Entrance ,
184
- usable_exits : list [Entrance ]) -> bool :
184
+ usable_exits : set [Entrance ]) -> bool :
185
185
copied_state = self .collection_state .copy ()
186
186
# simulated connection. A real connection is unsafe because the region graph is shallow-copied and would
187
187
# propagate back to the real multiworld.
@@ -329,6 +329,24 @@ def randomize_entrances(
329
329
# similar to fill, skip validity checks on entrances if the game is beatable on minimal accessibility
330
330
perform_validity_check = True
331
331
332
+ if not er_targets :
333
+ er_targets = sorted ([entrance for region in world .multiworld .get_regions (world .player )
334
+ for entrance in region .entrances if not entrance .parent_region ], key = lambda x : x .name )
335
+ if not exits :
336
+ exits = sorted ([ex for region in world .multiworld .get_regions (world .player )
337
+ for ex in region .exits if not ex .connected_region ], key = lambda x : x .name )
338
+ if len (er_targets ) != len (exits ):
339
+ raise EntranceRandomizationError (f"Unable to randomize entrances due to a mismatched count of "
340
+ f"entrances ({ len (er_targets )} ) and exits ({ len (exits )} ." )
341
+
342
+ # used when membership checks are needed on the exit list, e.g. speculative sweep
343
+ exits_set = set (exits )
344
+ for entrance in er_targets :
345
+ entrance_lookup .add (entrance )
346
+
347
+ # place the menu region and connected start region(s)
348
+ er_state .collection_state .update_reachable_regions (world .player )
349
+
332
350
def do_placement (source_exit : Entrance , target_entrance : Entrance ) -> None :
333
351
placed_exits , removed_entrances = er_state .connect (source_exit , target_entrance )
334
352
# remove the placed targets from consideration
@@ -358,7 +376,7 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool:
358
376
and len (placeable_exits ) == 1 )
359
377
if exit_requirement_satisfied and source_exit .can_connect_to (target_entrance , dead_end , er_state ):
360
378
if (needs_speculative_sweep
361
- and not er_state .test_speculative_connection (source_exit , target_entrance , exits )):
379
+ and not er_state .test_speculative_connection (source_exit , target_entrance , exits_set )):
362
380
continue
363
381
do_placement (source_exit , target_entrance )
364
382
return True
@@ -410,21 +428,6 @@ def find_pairing(dead_end: bool, require_new_exits: bool) -> bool:
410
428
f"All unplaced entrances: { unplaced_entrances } \n "
411
429
f"All unplaced exits: { unplaced_exits } " )
412
430
413
- if not er_targets :
414
- er_targets = sorted ([entrance for region in world .multiworld .get_regions (world .player )
415
- for entrance in region .entrances if not entrance .parent_region ], key = lambda x : x .name )
416
- if not exits :
417
- exits = sorted ([ex for region in world .multiworld .get_regions (world .player )
418
- for ex in region .exits if not ex .connected_region ], key = lambda x : x .name )
419
- if len (er_targets ) != len (exits ):
420
- raise EntranceRandomizationError (f"Unable to randomize entrances due to a mismatched count of "
421
- f"entrances ({ len (er_targets )} ) and exits ({ len (exits )} ." )
422
- for entrance in er_targets :
423
- entrance_lookup .add (entrance )
424
-
425
- # place the menu region and connected start region(s)
426
- er_state .collection_state .update_reachable_regions (world .player )
427
-
428
431
# stage 1 - try to place all the non-dead-end entrances
429
432
while entrance_lookup .others :
430
433
if not find_pairing (dead_end = False , require_new_exits = True ):
0 commit comments