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) |