123 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
def flatten(l):
 | 
						|
    if type(l) is list:
 | 
						|
        return [ y for x in l for y in flatten(x) ]
 | 
						|
    else:
 | 
						|
        return [ l ]
 | 
						|
 | 
						|
# super metroid boolean
 | 
						|
class SMBool:
 | 
						|
    __slots__ = ('bool', 'difficulty', '_knows', '_items')
 | 
						|
    def __init__(self, boolean, difficulty=0, knows=[], items=[]):
 | 
						|
        self.bool = boolean
 | 
						|
        self.difficulty = difficulty
 | 
						|
        self._knows = knows
 | 
						|
        self._items = items
 | 
						|
 | 
						|
    @property
 | 
						|
    def knows(self):
 | 
						|
        self._knows = list(set(flatten(self._knows)))
 | 
						|
        return self._knows
 | 
						|
 | 
						|
    @knows.setter
 | 
						|
    def knows(self, knows):
 | 
						|
        self._knows = knows
 | 
						|
 | 
						|
    @property
 | 
						|
    def items(self):
 | 
						|
        self._items = list(set(flatten(self._items)))
 | 
						|
        return self._items
 | 
						|
 | 
						|
    @items.setter
 | 
						|
    def items(self, items):
 | 
						|
        self._items = items
 | 
						|
 | 
						|
    def __repr__(self):
 | 
						|
        # to display the smbool as a string
 | 
						|
        return 'SMBool({}, {}, {}, {})'.format(self.bool, self.difficulty, sorted(self.knows), sorted(self.items))
 | 
						|
 | 
						|
    def __getitem__(self, index):
 | 
						|
        # to acces the smbool as [0] for the bool and [1] for the difficulty.
 | 
						|
        # required when we load a json preset where the smbool is stored as a list,
 | 
						|
        # and we add missing smbools to it, so we have a mix of lists and smbools.
 | 
						|
        if index == 0:
 | 
						|
            return self.bool
 | 
						|
        elif index == 1:
 | 
						|
            return self.difficulty
 | 
						|
 | 
						|
    def __bool__(self):
 | 
						|
        # when used in boolean expressions (with and/or/not) (python3)
 | 
						|
        return self.bool
 | 
						|
 | 
						|
    def __eq__(self, other):
 | 
						|
        # for ==
 | 
						|
        return self.bool == other
 | 
						|
 | 
						|
    def __ne__(self, other):
 | 
						|
        # for !=
 | 
						|
        return self.bool != other
 | 
						|
 | 
						|
    def __lt__(self, other):
 | 
						|
        # for <
 | 
						|
        if self.bool and other.bool:
 | 
						|
            return self.difficulty < other.difficulty
 | 
						|
        else:
 | 
						|
            return self.bool
 | 
						|
 | 
						|
    def __copy__(self):
 | 
						|
        return SMBool(self.bool, self.difficulty, self._knows, self._items)
 | 
						|
 | 
						|
    def json(self):
 | 
						|
        # as we have slots instead of dict
 | 
						|
        return {'bool': self.bool, 'difficulty': self.difficulty, 'knows': self.knows, 'items': self.items}
 | 
						|
 | 
						|
    def wand(*args):
 | 
						|
        # looping here is faster than using "if ... in" construct
 | 
						|
        for smb in args:
 | 
						|
            if not smb.bool:
 | 
						|
                return smboolFalse
 | 
						|
 | 
						|
        difficulty = 0
 | 
						|
 | 
						|
        for smb in args:
 | 
						|
            difficulty += smb.difficulty
 | 
						|
 | 
						|
        return SMBool(True,
 | 
						|
                      difficulty,
 | 
						|
                      [ smb._knows for smb in args ],
 | 
						|
                      [ smb._items for smb in args ])
 | 
						|
 | 
						|
    def wandmax(*args):
 | 
						|
        # looping here is faster than using "if ... in" construct
 | 
						|
        for smb in args:
 | 
						|
            if not smb.bool:
 | 
						|
                return smboolFalse
 | 
						|
 | 
						|
        difficulty = 0
 | 
						|
 | 
						|
        for smb in args:
 | 
						|
            if smb.difficulty > difficulty:
 | 
						|
                difficulty = smb.difficulty
 | 
						|
 | 
						|
        return SMBool(True,
 | 
						|
                      difficulty,
 | 
						|
                      [ smb._knows for smb in args ],
 | 
						|
                      [ smb._items for smb in args ])
 | 
						|
 | 
						|
    def wor(*args):
 | 
						|
        # looping here is faster than using "if ... in" construct
 | 
						|
        for smb in args:
 | 
						|
            if smb.bool:
 | 
						|
                return min(args)
 | 
						|
 | 
						|
        return smboolFalse
 | 
						|
 | 
						|
    # negates boolean part of the SMBool
 | 
						|
    def wnot(a):
 | 
						|
        return smboolFalse if a.bool else SMBool(True, a.difficulty)
 | 
						|
 | 
						|
    __and__ = wand
 | 
						|
    __or__ = wor
 | 
						|
    __not__ = wnot
 | 
						|
 | 
						|
smboolFalse = SMBool(False)
 |