Skip to content

Commit a7a92c9

Browse files
black-sliverFlySniper
authored andcommitted
Fill: fix swap error found in CI (ArchipelagoMW#2397)
* Fill: add test for swap error with item rules https://discord.com/channels/731205301247803413/731214280439103580/1167195750082560121 * Fill: fix swap error found in CI Swap now assumes the unplaced items can be placed before the to-be-swapped item. Unsure if that is safe or unsafe. * Test: clarify docstring and comments in fill swap test * Test: clarify comments in fill swap test more
1 parent adbd9dc commit a7a92c9

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

Fill.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def fill_restrictive(world: MultiWorld, base_state: CollectionState, locations:
112112

113113
location.item = None
114114
placed_item.location = None
115-
swap_state = sweep_from_pool(base_state, [placed_item] if unsafe else [])
115+
swap_state = sweep_from_pool(base_state, [placed_item, *item_pool] if unsafe else item_pool)
116116
# unsafe means swap_state assumes we can somehow collect placed_item before item_to_place
117117
# by continuing to swap, which is not guaranteed. This is unsafe because there is no mechanic
118118
# to clean that up later, so there is a chance generation fails.

test/general/test_fill.py

+41
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,47 @@ def test_swap_to_earlier_location_with_item_rule(self):
442442
self.assertTrue(sphere1_loc.item, "Did not swap required item into Sphere 1")
443443
self.assertEqual(sphere1_loc.item, allowed_item, "Wrong item in Sphere 1")
444444

445+
def test_swap_to_earlier_location_with_item_rule2(self):
446+
"""Test that swap works before all items are placed"""
447+
multi_world = generate_multi_world(1)
448+
player1 = generate_player_data(multi_world, 1, 5, 5)
449+
locations = player1.locations[:] # copy required
450+
items = player1.prog_items[:] # copy required
451+
# Two items provide access to sphere 2.
452+
# One of them is forbidden in sphere 1, the other is first placed in sphere 4 because of placement order,
453+
# requiring a swap.
454+
# There are spheres in between, so for the swap to work, it'll have to assume all other items are collected.
455+
one_to_two1 = items[4].name
456+
one_to_two2 = items[3].name
457+
three_to_four = items[2].name
458+
two_to_three1 = items[1].name
459+
two_to_three2 = items[0].name
460+
# Sphere 4
461+
set_rule(locations[0], lambda state: ((state.has(one_to_two1, player1.id) or state.has(one_to_two2, player1.id))
462+
and state.has(two_to_three1, player1.id)
463+
and state.has(two_to_three2, player1.id)
464+
and state.has(three_to_four, player1.id)))
465+
# Sphere 3
466+
set_rule(locations[1], lambda state: ((state.has(one_to_two1, player1.id) or state.has(one_to_two2, player1.id))
467+
and state.has(two_to_three1, player1.id)
468+
and state.has(two_to_three2, player1.id)))
469+
# Sphere 2
470+
set_rule(locations[2], lambda state: state.has(one_to_two1, player1.id) or state.has(one_to_two2, player1.id))
471+
# Sphere 1
472+
sphere1_loc1 = locations[3]
473+
sphere1_loc2 = locations[4]
474+
# forbid one_to_two2 in sphere 1 to make the swap happen as described above
475+
add_item_rule(sphere1_loc1, lambda item_to_place: item_to_place.name != one_to_two2)
476+
add_item_rule(sphere1_loc2, lambda item_to_place: item_to_place.name != one_to_two2)
477+
478+
# Now fill should place one_to_two1 in sphere1_loc1 or sphere1_loc2 via swap,
479+
# which it will attempt before two_to_three and three_to_four are placed, testing the behavior.
480+
fill_restrictive(multi_world, multi_world.state, player1.locations, player1.prog_items)
481+
# assert swap happened
482+
self.assertTrue(sphere1_loc1.item and sphere1_loc2.item, "Did not swap required item into Sphere 1")
483+
self.assertTrue(sphere1_loc1.item.name == one_to_two1 or
484+
sphere1_loc2.item.name == one_to_two1, "Wrong item in Sphere 1")
485+
445486
def test_double_sweep(self):
446487
"""Test that sweep doesn't duplicate Event items when sweeping"""
447488
# test for PR1114

0 commit comments

Comments
 (0)