Stardew Valley: Make sure number of month in time logic is a int to improve performance by ~20% (#3665)
* make sure number of month is actually a int * improve rule explain like in pr * remove redundant if in can_complete_bundle * assert number is int so cache is not bloated
This commit is contained in:
parent
e33a9991ef
commit
34e7748f23
|
@ -27,8 +27,8 @@ class BundleLogicMixin(BaseLogicMixin):
|
|||
self.bundle = BundleLogic(*args, **kwargs)
|
||||
|
||||
|
||||
class BundleLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, TimeLogicMixin, RegionLogicMixin, MoneyLogicMixin, QualityLogicMixin, FishingLogicMixin, SkillLogicMixin,
|
||||
QuestLogicMixin]]):
|
||||
class BundleLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, TimeLogicMixin, RegionLogicMixin, MoneyLogicMixin, QualityLogicMixin, FishingLogicMixin,
|
||||
SkillLogicMixin, QuestLogicMixin]]):
|
||||
# Should be cached
|
||||
def can_complete_bundle(self, bundle: Bundle) -> StardewRule:
|
||||
item_rules = []
|
||||
|
@ -45,7 +45,7 @@ QuestLogicMixin]]):
|
|||
qualities.append(bundle_item.quality)
|
||||
quality_rules = self.get_quality_rules(qualities)
|
||||
item_rules = self.logic.has_n(*item_rules, count=bundle.number_required)
|
||||
time_rule = True_() if time_to_grind <= 0 else self.logic.time.has_lived_months(time_to_grind)
|
||||
time_rule = self.logic.time.has_lived_months(time_to_grind)
|
||||
return can_speak_junimo & item_rules & quality_rules & time_rule
|
||||
|
||||
def get_quality_rules(self, qualities: List[str]) -> StardewRule:
|
||||
|
|
|
@ -41,7 +41,7 @@ class MuseumLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, TimeLogicMi
|
|||
else:
|
||||
geodes_rule = False_()
|
||||
# monster_rule = self.can_farm_monster(item.monsters)
|
||||
time_needed_to_grind = (20 - item.difficulty) / 2
|
||||
time_needed_to_grind = int((20 - item.difficulty) // 2)
|
||||
time_rule = self.logic.time.has_lived_months(time_needed_to_grind)
|
||||
pan_rule = False_()
|
||||
if item.item_name == Mineral.earth_crystal or item.item_name == Mineral.fire_quartz or item.item_name == Mineral.frozen_tear:
|
||||
|
|
|
@ -26,8 +26,10 @@ class TimeLogic(BaseLogic[Union[TimeLogicMixin, HasLogicMixin]]):
|
|||
|
||||
@cache_self1
|
||||
def has_lived_months(self, number: int) -> StardewRule:
|
||||
assert isinstance(number, int), "Can't have lived a fraction of a month. Use // instead of / when dividing."
|
||||
if number <= 0:
|
||||
return self.logic.true_
|
||||
|
||||
number = min(number, MAX_MONTHS)
|
||||
return HasProgressionPercent(self.player, number * MONTH_COEFFICIENT)
|
||||
|
||||
|
|
|
@ -431,7 +431,7 @@ class Count(BaseStardewRule):
|
|||
return len(self.rules)
|
||||
|
||||
def __repr__(self):
|
||||
return f"Received {self.count} {repr(self.rules)}"
|
||||
return f"Received {self.count} [{', '.join(f'{value}x {repr(rule)}' for rule, value in self.counter.items())}]"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
|
|
@ -34,7 +34,7 @@ class RuleExplanation:
|
|||
if not self.sub_rules:
|
||||
return self.summary(depth)
|
||||
|
||||
return self.summary(depth) + "\n" + "\n".join(RuleExplanation.__str__(i, depth + 1)
|
||||
return self.summary(depth) + "\n" + "\n".join(i.__str__(depth + 1)
|
||||
if i.result is not self.expected else i.summary(depth + 1)
|
||||
for i in sorted(self.explained_sub_rules, key=lambda x: x.result))
|
||||
|
||||
|
@ -42,7 +42,7 @@ class RuleExplanation:
|
|||
if not self.sub_rules:
|
||||
return self.summary(depth)
|
||||
|
||||
return self.summary(depth) + "\n" + "\n".join(RuleExplanation.__repr__(i, depth + 1)
|
||||
return self.summary(depth) + "\n" + "\n".join(i.__repr__(depth + 1)
|
||||
for i in sorted(self.explained_sub_rules, key=lambda x: x.result))
|
||||
|
||||
@cached_property
|
||||
|
@ -61,6 +61,33 @@ class RuleExplanation:
|
|||
return [_explain(i, self.state, self.expected, self.explored_rules_key) for i in self.sub_rules]
|
||||
|
||||
|
||||
@dataclass
|
||||
class CountSubRuleExplanation(RuleExplanation):
|
||||
count: int = 1
|
||||
|
||||
@staticmethod
|
||||
def from_explanation(expl: RuleExplanation, count: int) -> CountSubRuleExplanation:
|
||||
return CountSubRuleExplanation(expl.rule, expl.state, expl.expected, expl.sub_rules, expl.explored_rules_key, expl.current_rule_explored, count)
|
||||
|
||||
def summary(self, depth=0) -> str:
|
||||
summary = " " * depth + f"{self.count}x {str(self.rule)} -> {self.result}"
|
||||
if self.current_rule_explored:
|
||||
summary += " [Already explained]"
|
||||
return summary
|
||||
|
||||
|
||||
@dataclass
|
||||
class CountExplanation(RuleExplanation):
|
||||
rule: Count
|
||||
|
||||
@cached_property
|
||||
def explained_sub_rules(self) -> List[RuleExplanation]:
|
||||
return [
|
||||
CountSubRuleExplanation.from_explanation(_explain(rule, self.state, self.expected, self.explored_rules_key), count)
|
||||
for rule, count in self.rule.counter.items()
|
||||
]
|
||||
|
||||
|
||||
def explain(rule: CollectionRule, state: CollectionState, expected: bool = True) -> RuleExplanation:
|
||||
if isinstance(rule, StardewRule):
|
||||
return _explain(rule, state, expected, explored_spots=set())
|
||||
|
@ -80,7 +107,7 @@ def _(rule: AggregatingStardewRule, state: CollectionState, expected: bool, expl
|
|||
|
||||
@_explain.register
|
||||
def _(rule: Count, state: CollectionState, expected: bool, explored_spots: Set[Tuple[str, str]]) -> RuleExplanation:
|
||||
return RuleExplanation(rule, state, expected, rule.rules, explored_rules_key=explored_spots)
|
||||
return CountExplanation(rule, state, expected, rule.rules, explored_rules_key=explored_spots)
|
||||
|
||||
|
||||
@_explain.register
|
||||
|
|
|
@ -122,4 +122,4 @@ class HasProgressionPercent(CombinableStardewRule):
|
|||
return self, self(state)
|
||||
|
||||
def __repr__(self):
|
||||
return f"Received {self.percent}% progression items."
|
||||
return f"Received {self.percent}% progression items"
|
||||
|
|
Loading…
Reference in New Issue