Skip to content

Commit eb195e8

Browse files
black-sliverFlySniper
authored andcommitted
Stardew Valley: simplify in-place (ArchipelagoMW#2393)
this allows skipping multiple simplifications of the same object, e.g. item_rules also update the logic simplification tests to be a proper unittest.TestCase
1 parent d03d0be commit eb195e8

File tree

2 files changed

+67
-54
lines changed

2 files changed

+67
-54
lines changed

worlds/stardew_valley/stardew_rule.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def get_difficulty(self):
8888

8989
class Or(StardewRule):
9090
rules: FrozenSet[StardewRule]
91+
_simplified: bool
9192

9293
def __init__(self, rule: Union[StardewRule, Iterable[StardewRule]], *rules: StardewRule):
9394
rules_list: Set[StardewRule]
@@ -112,6 +113,7 @@ def __init__(self, rule: Union[StardewRule, Iterable[StardewRule]], *rules: Star
112113
rules_list = new_rules
113114

114115
self.rules = frozenset(rules_list)
116+
self._simplified = False
115117

116118
def __call__(self, state: CollectionState) -> bool:
117119
return any(rule(state) for rule in self.rules)
@@ -139,6 +141,8 @@ def get_difficulty(self):
139141
return min(rule.get_difficulty() for rule in self.rules)
140142

141143
def simplify(self) -> StardewRule:
144+
if self._simplified:
145+
return self
142146
if true_ in self.rules:
143147
return true_
144148

@@ -151,11 +155,14 @@ def simplify(self) -> StardewRule:
151155
if len(simplified_rules) == 1:
152156
return simplified_rules[0]
153157

154-
return Or(simplified_rules)
158+
self.rules = frozenset(simplified_rules)
159+
self._simplified = True
160+
return self
155161

156162

157163
class And(StardewRule):
158164
rules: FrozenSet[StardewRule]
165+
_simplified: bool
159166

160167
def __init__(self, rule: Union[StardewRule, Iterable[StardewRule]], *rules: StardewRule):
161168
rules_list: Set[StardewRule]
@@ -180,6 +187,7 @@ def __init__(self, rule: Union[StardewRule, Iterable[StardewRule]], *rules: Star
180187
rules_list = new_rules
181188

182189
self.rules = frozenset(rules_list)
190+
self._simplified = False
183191

184192
def __call__(self, state: CollectionState) -> bool:
185193
return all(rule(state) for rule in self.rules)
@@ -207,6 +215,8 @@ def get_difficulty(self):
207215
return max(rule.get_difficulty() for rule in self.rules)
208216

209217
def simplify(self) -> StardewRule:
218+
if self._simplified:
219+
return self
210220
if false_ in self.rules:
211221
return false_
212222

@@ -219,7 +229,9 @@ def simplify(self) -> StardewRule:
219229
if len(simplified_rules) == 1:
220230
return simplified_rules[0]
221231

222-
return And(simplified_rules)
232+
self.rules = frozenset(simplified_rules)
233+
self._simplified = True
234+
return self
223235

224236

225237
class Count(StardewRule):
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,57 @@
1+
import unittest
12
from .. import True_
23
from ..logic import Received, Has, False_, And, Or
34

45

5-
def test_simplify_true_in_and():
6-
rules = {
7-
"Wood": True_(),
8-
"Rock": True_(),
9-
}
10-
summer = Received("Summer", 0, 1)
11-
assert (Has("Wood", rules) & summer & Has("Rock", rules)).simplify() == summer
12-
13-
14-
def test_simplify_false_in_or():
15-
rules = {
16-
"Wood": False_(),
17-
"Rock": False_(),
18-
}
19-
summer = Received("Summer", 0, 1)
20-
assert (Has("Wood", rules) | summer | Has("Rock", rules)).simplify() == summer
21-
22-
23-
def test_simplify_and_in_and():
24-
rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)),
25-
And(Received('Winter', 0, 1), Received('Spring', 0, 1)))
26-
assert rule.simplify() == And(Received('Summer', 0, 1), Received('Fall', 0, 1), Received('Winter', 0, 1),
27-
Received('Spring', 0, 1))
28-
29-
30-
def test_simplify_duplicated_and():
31-
rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)),
32-
And(Received('Summer', 0, 1), Received('Fall', 0, 1)))
33-
assert rule.simplify() == And(Received('Summer', 0, 1), Received('Fall', 0, 1))
34-
35-
36-
def test_simplify_or_in_or():
37-
rule = Or(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)),
38-
Or(Received('Winter', 0, 1), Received('Spring', 0, 1)))
39-
assert rule.simplify() == Or(Received('Summer', 0, 1), Received('Fall', 0, 1), Received('Winter', 0, 1),
40-
Received('Spring', 0, 1))
41-
42-
43-
def test_simplify_duplicated_or():
44-
rule = And(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)),
45-
Or(Received('Summer', 0, 1), Received('Fall', 0, 1)))
46-
assert rule.simplify() == Or(Received('Summer', 0, 1), Received('Fall', 0, 1))
47-
48-
49-
def test_simplify_true_in_or():
50-
rule = Or(True_(), Received('Summer', 0, 1))
51-
assert rule.simplify() == True_()
52-
53-
54-
def test_simplify_false_in_and():
55-
rule = And(False_(), Received('Summer', 0, 1))
56-
assert rule.simplify() == False_()
6+
class TestSimplification(unittest.TestCase):
7+
def test_simplify_true_in_and(self):
8+
rules = {
9+
"Wood": True_(),
10+
"Rock": True_(),
11+
}
12+
summer = Received("Summer", 0, 1)
13+
self.assertEqual((Has("Wood", rules) & summer & Has("Rock", rules)).simplify(),
14+
summer)
15+
16+
def test_simplify_false_in_or(self):
17+
rules = {
18+
"Wood": False_(),
19+
"Rock": False_(),
20+
}
21+
summer = Received("Summer", 0, 1)
22+
self.assertEqual((Has("Wood", rules) | summer | Has("Rock", rules)).simplify(),
23+
summer)
24+
25+
def test_simplify_and_in_and(self):
26+
rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)),
27+
And(Received('Winter', 0, 1), Received('Spring', 0, 1)))
28+
self.assertEqual(rule.simplify(),
29+
And(Received('Summer', 0, 1), Received('Fall', 0, 1),
30+
Received('Winter', 0, 1), Received('Spring', 0, 1)))
31+
32+
def test_simplify_duplicated_and(self):
33+
rule = And(And(Received('Summer', 0, 1), Received('Fall', 0, 1)),
34+
And(Received('Summer', 0, 1), Received('Fall', 0, 1)))
35+
self.assertEqual(rule.simplify(),
36+
And(Received('Summer', 0, 1), Received('Fall', 0, 1)))
37+
38+
def test_simplify_or_in_or(self):
39+
rule = Or(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)),
40+
Or(Received('Winter', 0, 1), Received('Spring', 0, 1)))
41+
self.assertEqual(rule.simplify(),
42+
Or(Received('Summer', 0, 1), Received('Fall', 0, 1), Received('Winter', 0, 1),
43+
Received('Spring', 0, 1)))
44+
45+
def test_simplify_duplicated_or(self):
46+
rule = And(Or(Received('Summer', 0, 1), Received('Fall', 0, 1)),
47+
Or(Received('Summer', 0, 1), Received('Fall', 0, 1)))
48+
self.assertEqual(rule.simplify(),
49+
Or(Received('Summer', 0, 1), Received('Fall', 0, 1)))
50+
51+
def test_simplify_true_in_or(self):
52+
rule = Or(True_(), Received('Summer', 0, 1))
53+
self.assertEqual(rule.simplify(), True_())
54+
55+
def test_simplify_false_in_and(self):
56+
rule = And(False_(), Received('Summer', 0, 1))
57+
self.assertEqual(rule.simplify(), False_())

0 commit comments

Comments
 (0)