remove collections_extended dependency and replace with much faster stdlib Counter

This commit is contained in:
Fabian Dill 2020-03-07 23:35:55 +01:00
parent 27b6dd8bd7
commit f583db3ee9
2 changed files with 35 additions and 37 deletions

View File

@ -4,8 +4,7 @@ import copy
from enum import Enum, unique from enum import Enum, unique
import logging import logging
import json import json
from collections import OrderedDict from collections import OrderedDict, Counter
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 from typing import Union
@ -165,42 +164,42 @@ class World(object):
pass pass
elif ret.has('Tempered Sword', item.player) and self.difficulty_requirements[ elif ret.has('Tempered Sword', item.player) and self.difficulty_requirements[
item.player].progressive_sword_limit >= 4: item.player].progressive_sword_limit >= 4:
ret.prog_items.add(('Golden Sword', item.player)) ret.prog_items['Golden Sword', item.player] += 1
elif ret.has('Master Sword', item.player) and self.difficulty_requirements[ elif ret.has('Master Sword', item.player) and self.difficulty_requirements[
item.player].progressive_sword_limit >= 3: item.player].progressive_sword_limit >= 3:
ret.prog_items.add(('Tempered Sword', item.player)) ret.prog_items['Tempered Sword', item.player] += 1
elif ret.has('Fighter Sword', item.player) and self.difficulty_requirements[item.player].progressive_sword_limit >= 2: elif ret.has('Fighter Sword', item.player) and self.difficulty_requirements[item.player].progressive_sword_limit >= 2:
ret.prog_items.add(('Master Sword', item.player)) ret.prog_items['Master Sword', item.player] += 1
elif self.difficulty_requirements[item.player].progressive_sword_limit >= 1: elif self.difficulty_requirements[item.player].progressive_sword_limit >= 1:
ret.prog_items.add(('Fighter Sword', item.player)) ret.prog_items['Fighter Sword', item.player] += 1
elif 'Glove' in item.name: elif 'Glove' in item.name:
if ret.has('Titans Mitts', item.player): if ret.has('Titans Mitts', item.player):
pass pass
elif ret.has('Power Glove', item.player): elif ret.has('Power Glove', item.player):
ret.prog_items.add(('Titans Mitts', item.player)) ret.prog_items['Titans Mitts', item.player] += 1
else: else:
ret.prog_items.add(('Power Glove', item.player)) ret.prog_items['Power Glove', item.player] += 1
elif 'Shield' in item.name: elif 'Shield' in item.name:
if ret.has('Mirror Shield', item.player): if ret.has('Mirror Shield', item.player):
pass pass
elif ret.has('Red Shield', item.player) and self.difficulty_requirements[item.player].progressive_shield_limit >= 3: elif ret.has('Red Shield', item.player) and self.difficulty_requirements[item.player].progressive_shield_limit >= 3:
ret.prog_items.add(('Mirror Shield', item.player)) ret.prog_items['Mirror Shield', item.player] += 1
elif ret.has('Blue Shield', item.player) and self.difficulty_requirements[item.player].progressive_shield_limit >= 2: elif ret.has('Blue Shield', item.player) and self.difficulty_requirements[item.player].progressive_shield_limit >= 2:
ret.prog_items.add(('Red Shield', item.player)) ret.prog_items['Red Shield', item.player] += 1
elif self.difficulty_requirements[item.player].progressive_shield_limit >= 1: elif self.difficulty_requirements[item.player].progressive_shield_limit >= 1:
ret.prog_items.add(('Blue Shield', item.player)) ret.prog_items['Blue Shield', item.player] += 1
elif 'Bow' in item.name: elif 'Bow' in item.name:
if ret.has('Silver Arrows', item.player): if ret.has('Silver Arrows', item.player):
pass pass
elif ret.has('Bow', item.player) and self.difficulty_requirements[item.player].progressive_bow_limit >= 2: elif ret.has('Bow', item.player) and self.difficulty_requirements[item.player].progressive_bow_limit >= 2:
ret.prog_items.add(('Silver Arrows', item.player)) ret.prog_items['Silver Arrows', item.player] += 1
elif self.difficulty_requirements[item.player].progressive_bow_limit >= 1: elif self.difficulty_requirements[item.player].progressive_bow_limit >= 1:
ret.prog_items.add(('Bow', item.player)) ret.prog_items['Bow', item.player] += 1
elif item.name.startswith('Bottle'): elif item.name.startswith('Bottle'):
if ret.bottle_count(item.player) < self.difficulty_requirements[item.player].progressive_bottle_limit: if ret.bottle_count(item.player) < self.difficulty_requirements[item.player].progressive_bottle_limit:
ret.prog_items.add((item.name, item.player)) ret.prog_items[item.name, item.player] += 1
elif item.advancement or item.smallkey or item.bigkey: elif item.advancement or item.smallkey or item.bigkey:
ret.prog_items.add((item.name, item.player)) ret.prog_items[item.name, item.player] += 1
for item in self.itempool: for item in self.itempool:
soft_collect(item) soft_collect(item)
@ -336,7 +335,7 @@ class World(object):
class CollectionState(object): class CollectionState(object):
def __init__(self, parent: World): def __init__(self, parent: World):
self.prog_items = bag() self.prog_items = Counter()
self.world = parent self.world = parent
self.reachable_regions = {player: set() for player in range(1, parent.players + 1)} self.reachable_regions = {player: set() for player in range(1, parent.players + 1)}
self.events = [] self.events = []
@ -409,14 +408,14 @@ class CollectionState(object):
def has(self, item, player, count=1): def has(self, item, player, count=1):
if count == 1: if count == 1:
return (item, player) in self.prog_items return (item, player) in self.prog_items
return self.prog_items.count((item, player)) >= count return self.prog_items[item, player] >= count
def has_key(self, item, player, count=1): def has_key(self, item, player, count=1):
if self.world.retro[player]: if self.world.retro[player]:
return self.can_buy_unlimited('Small Key (Universal)', player) return self.can_buy_unlimited('Small Key (Universal)', player)
if count == 1: if count == 1:
return (item, player) in self.prog_items return (item, player) in self.prog_items
return self.prog_items.count((item, player)) >= count return self.prog_items[item, player] >= count
def can_buy_unlimited(self, item: str, player: int) -> bool: def can_buy_unlimited(self, item: str, player: int) -> bool:
for shop in self.world.shops: for shop in self.world.shops:
@ -425,7 +424,7 @@ class CollectionState(object):
return False return False
def item_count(self, item, player: int) -> int: def item_count(self, item, player: int) -> int:
return self.prog_items.count((item, player)) return self.prog_items[item, player]
def has_crystals(self, count: int, player: int) -> bool: def has_crystals(self, count: int, player: int) -> bool:
crystals = ['Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7'] crystals = ['Crystal 1', 'Crystal 2', 'Crystal 3', 'Crystal 4', 'Crystal 5', 'Crystal 6', 'Crystal 7']
@ -563,53 +562,53 @@ class CollectionState(object):
pass pass
elif self.has('Tempered Sword', item.player) and self.world.difficulty_requirements[ elif self.has('Tempered Sword', item.player) and self.world.difficulty_requirements[
item.player].progressive_sword_limit >= 4: item.player].progressive_sword_limit >= 4:
self.prog_items.add(('Golden Sword', item.player)) self.prog_items['Golden Sword', item.player] += 1
changed = True changed = True
elif self.has('Master Sword', item.player) and self.world.difficulty_requirements[item.player].progressive_sword_limit >= 3: elif self.has('Master Sword', item.player) and self.world.difficulty_requirements[item.player].progressive_sword_limit >= 3:
self.prog_items.add(('Tempered Sword', item.player)) self.prog_items['Tempered Sword', item.player] += 1
changed = True changed = True
elif self.has('Fighter Sword', item.player) and self.world.difficulty_requirements[item.player].progressive_sword_limit >= 2: elif self.has('Fighter Sword', item.player) and self.world.difficulty_requirements[item.player].progressive_sword_limit >= 2:
self.prog_items.add(('Master Sword', item.player)) self.prog_items['Master Sword', item.player] += 1
changed = True changed = True
elif self.world.difficulty_requirements[item.player].progressive_sword_limit >= 1: elif self.world.difficulty_requirements[item.player].progressive_sword_limit >= 1:
self.prog_items.add(('Fighter Sword', item.player)) self.prog_items['Fighter Sword', item.player] += 1
changed = True changed = True
elif 'Glove' in item.name: elif 'Glove' in item.name:
if self.has('Titans Mitts', item.player): if self.has('Titans Mitts', item.player):
pass pass
elif self.has('Power Glove', item.player): elif self.has('Power Glove', item.player):
self.prog_items.add(('Titans Mitts', item.player)) self.prog_items['Titans Mitts', item.player] += 1
changed = True changed = True
else: else:
self.prog_items.add(('Power Glove', item.player)) self.prog_items['Power Glove', item.player] += 1
changed = True changed = True
elif 'Shield' in item.name: elif 'Shield' in item.name:
if self.has('Mirror Shield', item.player): if self.has('Mirror Shield', item.player):
pass pass
elif self.has('Red Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 3: elif self.has('Red Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 3:
self.prog_items.add(('Mirror Shield', item.player)) self.prog_items['Mirror Shield', item.player] += 1
changed = True changed = True
elif self.has('Blue Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 2: elif self.has('Blue Shield', item.player) and self.world.difficulty_requirements[item.player].progressive_shield_limit >= 2:
self.prog_items.add(('Red Shield', item.player)) self.prog_items['Red Shield', item.player] += 1
changed = True changed = True
elif self.world.difficulty_requirements[item.player].progressive_shield_limit >= 1: elif self.world.difficulty_requirements[item.player].progressive_shield_limit >= 1:
self.prog_items.add(('Blue Shield', item.player)) self.prog_items['Blue Shield', item.player] += 1
changed = True changed = True
elif 'Bow' in item.name: elif 'Bow' in item.name:
if self.has('Silver Arrows', item.player): if self.has('Silver Arrows', item.player):
pass pass
elif self.has('Bow', item.player): elif self.has('Bow', item.player):
self.prog_items.add(('Silver Arrows', item.player)) self.prog_items['Silver Arrows', item.player] += 1
changed = True changed = True
else: else:
self.prog_items.add(('Bow', item.player)) self.prog_items['Bow', item.player] += 1
changed = True changed = True
elif item.name.startswith('Bottle'): elif item.name.startswith('Bottle'):
if self.bottle_count(item.player) < self.world.difficulty_requirements[item.player].progressive_bottle_limit: if self.bottle_count(item.player) < self.world.difficulty_requirements[item.player].progressive_bottle_limit:
self.prog_items.add((item.name, item.player)) self.prog_items[item.name, item.player] += 1
changed = True changed = True
elif event or item.advancement: elif event or item.advancement:
self.prog_items.add((item.name, item.player)) self.prog_items[item.name, item.player] += 1
changed = True changed = True
self.stale[item.player] = True self.stale[item.player] = True
@ -658,12 +657,12 @@ class CollectionState(object):
to_remove = None to_remove = None
if to_remove is not None: if to_remove is not None:
try:
self.prog_items.remove((to_remove, item.player))
except ValueError:
return
self.prog_items[to_remove, item.player] -= 1
if self.prog_items[to_remove, item.player] < 1:
del (self.prog_items[to_remove, item.player])
# invalidate caches, nothing can be trusted anymore now # invalidate caches, nothing can be trusted anymore now
self._reachable_cache = set()
self.reachable_regions[item.player] = set() self.reachable_regions[item.player] = set()
self.stale[item.player] = True self.stale[item.player] = True

View File

@ -2,7 +2,6 @@ aioconsole>=0.1.15
colorama>=0.4.3 colorama>=0.4.3
websockets>=8.1 websockets>=8.1
PyYAML>=5.3 PyYAML>=5.3
collections_extended>=1.0.3
fuzzywuzzy>=0.18.0 fuzzywuzzy>=0.18.0
bsdiff4>=1.1.9 bsdiff4>=1.1.9
upnpy>=1.1.5 upnpy>=1.1.5