diff --git a/worlds/stardew_valley/stardew_rule.py b/worlds/stardew_valley/stardew_rule.py index 5455a40e..9c96de00 100644 --- a/worlds/stardew_valley/stardew_rule.py +++ b/worlds/stardew_valley/stardew_rule.py @@ -88,6 +88,7 @@ assert true_ is True_() class Or(StardewRule): rules: FrozenSet[StardewRule] + _simplified: bool def __init__(self, rule: Union[StardewRule, Iterable[StardewRule]], *rules: StardewRule): rules_list: Set[StardewRule] @@ -112,6 +113,7 @@ class Or(StardewRule): rules_list = new_rules self.rules = frozenset(rules_list) + self._simplified = False def __call__(self, state: CollectionState) -> bool: return any(rule(state) for rule in self.rules) @@ -139,6 +141,8 @@ class Or(StardewRule): return min(rule.get_difficulty() for rule in self.rules) def simplify(self) -> StardewRule: + if self._simplified: + return self if true_ in self.rules: return true_ @@ -151,11 +155,14 @@ class Or(StardewRule): if len(simplified_rules) == 1: return simplified_rules[0] - return Or(simplified_rules) + self.rules = frozenset(simplified_rules) + self._simplified = True + return self class And(StardewRule): rules: FrozenSet[StardewRule] + _simplified: bool def __init__(self, rule: Union[StardewRule, Iterable[StardewRule]], *rules: StardewRule): rules_list: Set[StardewRule] @@ -180,6 +187,7 @@ class And(StardewRule): rules_list = new_rules self.rules = frozenset(rules_list) + self._simplified = False def __call__(self, state: CollectionState) -> bool: return all(rule(state) for rule in self.rules) @@ -207,6 +215,8 @@ class And(StardewRule): return max(rule.get_difficulty() for rule in self.rules) def simplify(self) -> StardewRule: + if self._simplified: + return self if false_ in self.rules: return false_ @@ -219,7 +229,9 @@ class And(StardewRule): if len(simplified_rules) == 1: return simplified_rules[0] - return And(simplified_rules) + self.rules = frozenset(simplified_rules) + self._simplified = True + return self class Count(StardewRule): diff --git a/worlds/stardew_valley/test/TestLogicSimplification.py b/worlds/stardew_valley/test/TestLogicSimplification.py index 33b24280..3f02643b 100644 --- a/worlds/stardew_valley/test/TestLogicSimplification.py +++ b/worlds/stardew_valley/test/TestLogicSimplification.py @@ -1,56 +1,57 @@ +import unittest from .. import True_ from ..logic import Received, Has, False_, And, Or -def test_simplify_true_in_and(): - rules = { - "Wood": True_(), - "Rock": True_(), - } - summer = Received("Summer", 0, 1) - assert (Has("Wood", rules) & summer & Has("Rock", rules)).simplify() == summer +class TestSimplification(unittest.TestCase): + def test_simplify_true_in_and(self): + rules = { + "Wood": True_(), + "Rock": True_(), + } + summer = Received("Summer", 0, 1) + self.assertEqual((Has("Wood", rules) & summer & Has("Rock", rules)).simplify(), + summer) + def test_simplify_false_in_or(self): + rules = { + "Wood": False_(), + "Rock": False_(), + } + summer = Received("Summer", 0, 1) + self.assertEqual((Has("Wood", rules) | summer | Has("Rock", rules)).simplify(), + summer) -def test_simplify_false_in_or(): - rules = { - "Wood": False_(), - "Rock": False_(), - } - summer = Received("Summer", 0, 1) - assert (Has("Wood", rules) | summer | Has("Rock", rules)).simplify() == summer + def test_simplify_and_in_and(self): + rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)), + And(Received('Winter', 0, 1), Received('Spring', 0, 1))) + self.assertEqual(rule.simplify(), + And(Received('Summer', 0, 1), Received('Fall', 0, 1), + Received('Winter', 0, 1), Received('Spring', 0, 1))) + def test_simplify_duplicated_and(self): + rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)), + And(Received('Summer', 0, 1), Received('Fall', 0, 1))) + self.assertEqual(rule.simplify(), + And(Received('Summer', 0, 1), Received('Fall', 0, 1))) -def test_simplify_and_in_and(): - rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)), - And(Received('Winter', 0, 1), Received('Spring', 0, 1))) - assert rule.simplify() == And(Received('Summer', 0, 1), Received('Fall', 0, 1), Received('Winter', 0, 1), - Received('Spring', 0, 1)) + def test_simplify_or_in_or(self): + rule = Or(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)), + Or(Received('Winter', 0, 1), Received('Spring', 0, 1))) + self.assertEqual(rule.simplify(), + Or(Received('Summer', 0, 1), Received('Fall', 0, 1), Received('Winter', 0, 1), + Received('Spring', 0, 1))) + def test_simplify_duplicated_or(self): + rule = And(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)), + Or(Received('Summer', 0, 1), Received('Fall', 0, 1))) + self.assertEqual(rule.simplify(), + Or(Received('Summer', 0, 1), Received('Fall', 0, 1))) -def test_simplify_duplicated_and(): - rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)), - And(Received('Summer', 0, 1), Received('Fall', 0, 1))) - assert rule.simplify() == And(Received('Summer', 0, 1), Received('Fall', 0, 1)) + def test_simplify_true_in_or(self): + rule = Or(True_(), Received('Summer', 0, 1)) + self.assertEqual(rule.simplify(), True_()) - -def test_simplify_or_in_or(): - rule = Or(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)), - Or(Received('Winter', 0, 1), Received('Spring', 0, 1))) - assert rule.simplify() == Or(Received('Summer', 0, 1), Received('Fall', 0, 1), Received('Winter', 0, 1), - Received('Spring', 0, 1)) - - -def test_simplify_duplicated_or(): - rule = And(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)), - Or(Received('Summer', 0, 1), Received('Fall', 0, 1))) - assert rule.simplify() == Or(Received('Summer', 0, 1), Received('Fall', 0, 1)) - - -def test_simplify_true_in_or(): - rule = Or(True_(), Received('Summer', 0, 1)) - assert rule.simplify() == True_() - - -def test_simplify_false_in_and(): - rule = And(False_(), Received('Summer', 0, 1)) - assert rule.simplify() == False_() + def test_simplify_false_in_and(self): + rule = And(False_(), Received('Summer', 0, 1)) + self.assertEqual(rule.simplify(), False_())