From 04a3f78605fa55e9f8fd3177d0229d48b8d7890d Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 27 Jul 2025 23:29:21 +0200 Subject: [PATCH] Core: Support inequality operators ("less than") for Choice option string comparisons (#3769) * add some unit tests to it * fix * Update Options.py Co-authored-by: qwint * Update Options.py --------- Co-authored-by: qwint --- Options.py | 24 ++++++++++++++++++++++++ test/options/test_option_classes.py | 9 +++++++++ worlds/witness/__init__.py | 2 +- worlds/witness/hints.py | 2 +- worlds/witness/player_logic.py | 4 ++-- 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Options.py b/Options.py index c948e7e9..3e67d685 100644 --- a/Options.py +++ b/Options.py @@ -494,6 +494,30 @@ class Choice(NumericOption): else: raise TypeError(f"Can't compare {self.__class__.__name__} with {other.__class__.__name__}") + def __lt__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} < {other}" + other = self.options[other] + return super(Choice, self).__lt__(other) + + def __gt__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} > {other}" + other = self.options[other] + return super(Choice, self).__gt__(other) + + def __le__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} <= {other}" + other = self.options[other] + return super(Choice, self).__le__(other) + + def __ge__(self, other: typing.Union[Choice, int, str]): + if isinstance(other, str): + assert other in self.options, f"compared against an unknown string. {self} >= {other}" + other = self.options[other] + return super(Choice, self).__ge__(other) + __hash__ = Option.__hash__ # see https://docs.python.org/3/reference/datamodel.html#object.__hash__ diff --git a/test/options/test_option_classes.py b/test/options/test_option_classes.py index 8e2c4702..ca90db88 100644 --- a/test/options/test_option_classes.py +++ b/test/options/test_option_classes.py @@ -33,6 +33,15 @@ class TestNumericOptions(unittest.TestCase): self.assertEqual(choice_option_alias, TestChoice.alias_three) self.assertEqual(choice_option_attr, TestChoice.non_option_attr) + self.assertLess(choice_option_string, "two") + self.assertGreater(choice_option_string, "zero") + self.assertLessEqual(choice_option_string, "one") + self.assertLessEqual(choice_option_string, "two") + self.assertGreaterEqual(choice_option_string, "one") + self.assertGreaterEqual(choice_option_string, "zero") + + self.assertGreaterEqual(choice_option_alias, "three") + self.assertRaises(KeyError, TestChoice.from_any, "four") self.assertIn(choice_option_int, [1, 2, 3]) diff --git a/worlds/witness/__init__.py b/worlds/witness/__init__.py index 0f96ee94..bce9bb51 100644 --- a/worlds/witness/__init__.py +++ b/worlds/witness/__init__.py @@ -257,7 +257,7 @@ class WitnessWorld(World): needed_size = 2 needed_size += self.options.puzzle_randomization == "sigma_expert" needed_size += self.options.shuffle_symbols - needed_size += self.options.shuffle_doors > 0 + needed_size += self.options.shuffle_doors != "off" # Then, add checks in order until the required amount of sphere 1 checks is met. diff --git a/worlds/witness/hints.py b/worlds/witness/hints.py index c82024cc..ac557225 100644 --- a/worlds/witness/hints.py +++ b/worlds/witness/hints.py @@ -129,7 +129,7 @@ def get_priority_hint_items(world: "WitnessWorld") -> List[str]: "Shadows Laser", ] - if world.options.shuffle_doors >= 2: + if world.options.shuffle_doors >= "doors": priority.add("Desert Laser") priority.update(world.random.sample(lasers, 5)) diff --git a/worlds/witness/player_logic.py b/worlds/witness/player_logic.py index 52bddde1..aed6d3da 100644 --- a/worlds/witness/player_logic.py +++ b/worlds/witness/player_logic.py @@ -435,7 +435,7 @@ class WitnessPlayerLogic: postgame_adjustments = [] # Make some quick references to some options - remote_doors = world.options.shuffle_doors >= 2 # "Panels" mode has no region accessibility implications. + remote_doors = world.options.shuffle_doors >= "doors" # "Panels" mode has no region accessibility implications. early_caves = world.options.early_caves victory = world.options.victory_condition mnt_lasers = world.options.mountain_lasers @@ -592,7 +592,7 @@ class WitnessPlayerLogic: # Make condensed references to some options - remote_doors = world.options.shuffle_doors >= 2 # "Panels" mode has no overarching region access implications. + remote_doors = world.options.shuffle_doors >= "doors" # "Panels" mode has no region access implications. lasers = world.options.shuffle_lasers victory = world.options.victory_condition mnt_lasers = world.options.mountain_lasers