Skip to content

Commit

Permalink
The Witness: Fix Tunnels Theater Flower EP Access Logic + Add Unit Te…
Browse files Browse the repository at this point in the history
…st for it (and Expert PP2) (ArchipelagoMW#3807)

* Tunnels Theater Flowers fix + Flowers&PP2 Unit Tests

* copypaste

* Can just do it like this

* This is even better probably

* Also do some cleanup :3

* God damnit
  • Loading branch information
NewSoupVi authored Aug 19, 2024
1 parent 9277cb3 commit 182f7e2
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 32 deletions.
50 changes: 18 additions & 32 deletions worlds/witness/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ def _can_do_expert_pp2(state: CollectionState, world: "WitnessWorld") -> bool:
"""

player = world.player
player_regions = world.player_regions
two_way_entrance_register = world.player_regions.two_way_entrance_register

front_access = (
any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 2nd Pressure Plate", "Keep"])
any(e.can_reach(state) for e in two_way_entrance_register["Keep 2nd Pressure Plate", "Keep"])
and state.can_reach_region("Keep", player)
)

Expand All @@ -88,7 +88,7 @@ def _can_do_expert_pp2(state: CollectionState, world: "WitnessWorld") -> bool:
# Front access works. Now, we need to check for the many ways to access PP2 from the back.
# All of those ways lead through the PP3 exit door from PP4. So we check this first.

fourth_to_third = any(e.can_reach(state) for e in player_regions.two_way_entrance_register[
fourth_to_third = any(e.can_reach(state) for e in two_way_entrance_register[
"Keep 3rd Pressure Plate", "Keep 4th Pressure Plate"
])

Expand All @@ -100,17 +100,15 @@ def _can_do_expert_pp2(state: CollectionState, world: "WitnessWorld") -> bool:
# The shadows shortcut is the simplest way.

shadows_shortcut = (
any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 4th Pressure Plate", "Shadows"])
any(e.can_reach(state) for e in two_way_entrance_register["Keep 4th Pressure Plate", "Shadows"])
)

if shadows_shortcut:
return True

# We don't have the Shadows shortcut. This means we need to come in through the PP4 exit door instead.

tower_to_pp4 = any(
e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 4th Pressure Plate", "Keep Tower"]
)
tower_to_pp4 = any(e.can_reach(state) for e in two_way_entrance_register["Keep 4th Pressure Plate", "Keep Tower"])

# If we don't have the PP4 exit door, we've run out of options.
if not tower_to_pp4:
Expand All @@ -119,7 +117,7 @@ def _can_do_expert_pp2(state: CollectionState, world: "WitnessWorld") -> bool:
# We have the PP4 exit door. If we can get to Keep Tower from behind, we can do PP2.
# The simplest way would be the Tower Shortcut.

tower_shortcut = any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep", "Keep Tower"])
tower_shortcut = any(e.can_reach(state) for e in two_way_entrance_register["Keep", "Keep Tower"])

if tower_shortcut:
return True
Expand All @@ -128,56 +126,44 @@ def _can_do_expert_pp2(state: CollectionState, world: "WitnessWorld") -> bool:
# Getting to Keep Tower through the hedge mazes. This can be done in a multitude of ways.
# No matter what, though, we would need Hedge Maze 4 Exit to Keep Tower.

tower_access_from_hedges = any(
e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 4th Maze", "Keep Tower"]
)
tower_access_from_hedges = any(e.can_reach(state) for e in two_way_entrance_register["Keep 4th Maze", "Keep Tower"])

if not tower_access_from_hedges:
return False

# We can reach Keep Tower from Hedge Maze 4. If we now have the Hedge 4 Shortcut, we are immediately good.

hedge_4_shortcut = any(
e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 4th Maze", "Keep"]
)
hedge_4_shortcut = any(e.can_reach(state) for e in two_way_entrance_register["Keep 4th Maze", "Keep"])

# If we have the hedge 4 shortcut, that works.
if hedge_4_shortcut:
return True

# We don't have the hedge 4 shortcut. This means we would now need to come through Hedge Maze 3.

hedge_3_to_4 = any(
e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 4th Maze", "Keep 3rd Maze"]
)
hedge_3_to_4 = any(e.can_reach(state) for e in two_way_entrance_register["Keep 4th Maze", "Keep 3rd Maze"])

if not hedge_3_to_4:
return False

# We can get to Hedge 4 from Hedge 3. If we have the Hedge 3 Shortcut, we're good.

hedge_3_shortcut = any(
e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 3rd Maze", "Keep"]
)
hedge_3_shortcut = any(e.can_reach(state) for e in two_way_entrance_register["Keep 3rd Maze", "Keep"])

if hedge_3_shortcut:
return True

# We don't have Hedge 3 Shortcut. This means we would now need to come through Hedge Maze 2.

hedge_2_to_3 = any(
e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 3rd Maze", "Keep 2nd Maze"]
)
hedge_2_to_3 = any(e.can_reach(state) for e in two_way_entrance_register["Keep 3rd Maze", "Keep 2nd Maze"])

if not hedge_2_to_3:
return False

# We can get to Hedge 3 from Hedge 2. If we can get from Keep to Hedge 2, we're good.
# This covers both Hedge 1 Exit and Hedge 2 Shortcut, because Hedge 1 is just part of the Keep region.

return any(
e.can_reach(state) for e in player_regions.two_way_entrance_register["Keep 2nd Maze", "Keep"]
)
return any(e.can_reach(state) for e in two_way_entrance_register["Keep 2nd Maze", "Keep"])


def _can_do_theater_to_tunnels(state: CollectionState, world: "WitnessWorld") -> bool:
Expand All @@ -189,11 +175,11 @@ def _can_do_theater_to_tunnels(state: CollectionState, world: "WitnessWorld") ->
# Checking for access to Theater is not necessary, as solvability of Tutorial Video is checked in the other half
# of the Theater Flowers EP condition.

player_regions = world.player_regions
two_way_entrance_register = world.player_regions.two_way_entrance_register

direct_access = (
any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Tunnels", "Windmill Interior"])
and any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Theater", "Windmill Interior"])
any(e.can_reach(state) for e in two_way_entrance_register["Tunnels", "Windmill Interior"])
and any(e.can_reach(state) for e in two_way_entrance_register["Theater", "Windmill Interior"])
)

if direct_access:
Expand All @@ -210,9 +196,9 @@ def _can_do_theater_to_tunnels(state: CollectionState, world: "WitnessWorld") ->
# We also need a way from Town to Tunnels.

return (
any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Tunnels", "Windmill Interior"])
and any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Town", "Windmill Interior"])
or any(e.can_reach(state) for e in player_regions.two_way_entrance_register["Tunnels", "Town"])
any(e.can_reach(state) for e in two_way_entrance_register["Tunnels", "Windmill Interior"])
and any(e.can_reach(state) for e in two_way_entrance_register["Outside Windmill", "Windmill Interior"])
or any(e.can_reach(state) for e in two_way_entrance_register["Tunnels", "Town"])
)


Expand Down
66 changes: 66 additions & 0 deletions worlds/witness/test/test_weird_traversals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from ..test import WitnessTestBase


class TestWeirdTraversalRequirements(WitnessTestBase):
options = {
"shuffle_vault_boxes": True,
"shuffle_symbols": False,
"shuffle_EPs": "individual",
"EP_difficulty": "tedious",
"shuffle_doors": "doors",
"door_groupings": "off",
"puzzle_randomization": "sigma_expert",
}

def test_weird_traversal_requirements(self) -> None:
"""
Test that Tunnels Theater Flowers EP and Expert PP2 consider all valid paths logically.
"""

with self.subTest("Tunnels Theater Flowers EP"):
self.assertAccessDependency(
["Tunnels Theater Flowers EP"],
[
["Theater Exit Left (Door)", "Windmill Entry (Door)", "Tunnels Theater Shortcut (Door)"],
["Theater Exit Right (Door)", "Windmill Entry (Door)", "Tunnels Theater Shortcut (Door)"],
["Theater Exit Left (Door)", "Tunnels Town Shortcut (Door)"],
["Theater Exit Right (Door)", "Tunnels Town Shortcut (Door)"],
["Theater Entry (Door)", "Tunnels Theater Shortcut (Door)"],
["Theater Entry (Door)", "Windmill Entry (Door)", "Tunnels Town Shortcut (Door)"],
],
only_check_listed=True,
)

with self.subTest("Expert Keep Pressure Plates 2"):
# Always necessary
self.assertAccessDependency(
["Keep Pressure Plates 2"],
[["Keep Pressure Plates 1 Exit (Door)"]],
only_check_listed=True,
)

# Always necessary
self.assertAccessDependency(
["Keep Pressure Plates 2"],
[["Keep Pressure Plates 3 Exit (Door)"]],
only_check_listed=True,
)

# All the possible "Exit methods" from PP3
self.assertAccessDependency(
["Keep Pressure Plates 2"],
[
["Keep Shadows Shortcut (Door)"],
["Keep Pressure Plates 4 Exit (Door)", "Keep Tower Shortcut (Door)"],
["Keep Pressure Plates 4 Exit (Door)", "Keep Hedge Maze 4 Exit (Door)",
"Keep Hedge Maze 4 Shortcut (Door)"],
["Keep Pressure Plates 4 Exit (Door)", "Keep Hedge Maze 4 Exit (Door)",
"Keep Hedge Maze 3 Exit (Door)", "Keep Hedge Maze 3 Shortcut (Door)"],
["Keep Pressure Plates 4 Exit (Door)", "Keep Hedge Maze 4 Exit (Door)",
"Keep Hedge Maze 3 Exit (Door)", "Keep Hedge Maze 2 Exit (Door)",
"Keep Hedge Maze 2 Shortcut (Door)"],
["Keep Pressure Plates 4 Exit (Door)", "Keep Hedge Maze 4 Exit (Door)",
"Keep Hedge Maze 3 Exit (Door)", "Keep Hedge Maze 2 Exit (Door)", "Keep Hedge Maze 1 Exit (Door)"],
],
only_check_listed=True,
)

0 comments on commit 182f7e2

Please sign in to comment.