some speed improvments
This commit is contained in:
parent
1d75d5b70e
commit
27b6dd8bd7
|
@ -8,6 +8,7 @@ from collections import OrderedDict
|
||||||
from collections_extended import bag
|
from collections_extended import bag
|
||||||
from EntranceShuffle import door_addresses
|
from EntranceShuffle import door_addresses
|
||||||
from Utils import int16_as_bytes
|
from Utils import int16_as_bytes
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
class World(object):
|
class World(object):
|
||||||
player_names: list
|
player_names: list
|
||||||
|
@ -294,7 +295,7 @@ class World(object):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def has_beaten_game(self, state, player=None):
|
def has_beaten_game(self, state, player: Union[None, int] = None):
|
||||||
if player:
|
if player:
|
||||||
return state.has('Triforce', player)
|
return state.has('Triforce', player)
|
||||||
else:
|
else:
|
||||||
|
@ -302,14 +303,15 @@ class World(object):
|
||||||
|
|
||||||
def can_beat_game(self, starting_state=None):
|
def can_beat_game(self, starting_state=None):
|
||||||
if starting_state:
|
if starting_state:
|
||||||
|
if self.has_beaten_game(starting_state):
|
||||||
|
return True
|
||||||
state = starting_state.copy()
|
state = starting_state.copy()
|
||||||
else:
|
else:
|
||||||
state = CollectionState(self)
|
if self.has_beaten_game(self.state):
|
||||||
|
|
||||||
if self.has_beaten_game(state):
|
|
||||||
return True
|
return True
|
||||||
|
state = CollectionState(self)
|
||||||
prog_locations = [location for location in self.get_locations() if location.item is not None and (location.item.advancement or location.event) and location not in state.locations_checked]
|
prog_locations = {location for location in self.get_locations() if location.item is not None and (
|
||||||
|
location.item.advancement or location.event) and location not in state.locations_checked}
|
||||||
|
|
||||||
while prog_locations:
|
while prog_locations:
|
||||||
sphere = []
|
sphere = []
|
||||||
|
@ -343,6 +345,7 @@ class CollectionState(object):
|
||||||
self.stale = {player: True for player in range(1, parent.players + 1)}
|
self.stale = {player: True for player in range(1, parent.players + 1)}
|
||||||
for item in parent.precollected_items:
|
for item in parent.precollected_items:
|
||||||
self.collect(item, True)
|
self.collect(item, True)
|
||||||
|
self._reachable_cache = set()
|
||||||
|
|
||||||
def update_reachable_regions(self, player: int):
|
def update_reachable_regions(self, player: int):
|
||||||
player_regions = self.world.get_regions(player)
|
player_regions = self.world.get_regions(player)
|
||||||
|
@ -369,9 +372,10 @@ class CollectionState(object):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def can_reach(self, spot, resolution_hint=None, player=None):
|
def can_reach(self, spot, resolution_hint=None, player=None):
|
||||||
try:
|
if (player, getattr(spot, "name", spot)) in self._reachable_cache:
|
||||||
spot_type = spot.spot_type
|
return True
|
||||||
except AttributeError:
|
else:
|
||||||
|
if not hasattr(spot, "spot_type"):
|
||||||
# try to resolve a name
|
# try to resolve a name
|
||||||
if resolution_hint == 'Location':
|
if resolution_hint == 'Location':
|
||||||
spot = self.world.get_location(spot, player)
|
spot = self.world.get_location(spot, player)
|
||||||
|
@ -380,7 +384,9 @@ class CollectionState(object):
|
||||||
else:
|
else:
|
||||||
# default to Region
|
# default to Region
|
||||||
spot = self.world.get_region(spot, player)
|
spot = self.world.get_region(spot, player)
|
||||||
|
res = spot.can_reach(self)
|
||||||
|
if res:
|
||||||
|
self._reachable_cache.add((player, spot.name))
|
||||||
return spot.can_reach(self)
|
return spot.can_reach(self)
|
||||||
|
|
||||||
def sweep_for_events(self, key_only=False, locations=None):
|
def sweep_for_events(self, key_only=False, locations=None):
|
||||||
|
@ -707,7 +713,7 @@ class Region(object):
|
||||||
state.update_reachable_regions(self.player)
|
state.update_reachable_regions(self.player)
|
||||||
return self in state.reachable_regions[self.player]
|
return self in state.reachable_regions[self.player]
|
||||||
|
|
||||||
def can_reach_private(self, state):
|
def can_reach_private(self, state: CollectionState):
|
||||||
for entrance in self.entrances:
|
for entrance in self.entrances:
|
||||||
if entrance.can_reach(state):
|
if entrance.can_reach(state):
|
||||||
if not self in state.path:
|
if not self in state.path:
|
||||||
|
@ -715,7 +721,7 @@ class Region(object):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def can_fill(self, item):
|
def can_fill(self, item: Item):
|
||||||
inside_dungeon_item = ((item.smallkey and not self.world.keyshuffle[item.player])
|
inside_dungeon_item = ((item.smallkey and not self.world.keyshuffle[item.player])
|
||||||
or (item.bigkey and not self.world.bigkeyshuffle[item.player])
|
or (item.bigkey and not self.world.bigkeyshuffle[item.player])
|
||||||
or (item.map and not self.world.mapshuffle[item.player])
|
or (item.map and not self.world.mapshuffle[item.player])
|
||||||
|
|
Loading…
Reference in New Issue