64 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
 | |
| import utils.log, random
 | |
| 
 | |
| from logic.smboolmanager import SMBoolManager
 | |
| from utils.parameters import infinity
 | |
| 
 | |
| class MiniSolver(object):
 | |
|     def __init__(self, startAP, areaGraph, restrictions):
 | |
|         self.startAP = startAP
 | |
|         self.areaGraph = areaGraph
 | |
|         self.restrictions = restrictions
 | |
|         self.settings = restrictions.settings
 | |
|         self.smbm = SMBoolManager()
 | |
|         self.log = utils.log.get('MiniSolver')
 | |
| 
 | |
|     # if True, does not mean it is actually beatable, unless you're sure of it from another source of information
 | |
|     # if False, it is certain it is not beatable
 | |
|     def isBeatable(self, itemLocations, maxDiff=None):
 | |
|         if maxDiff is None:
 | |
|             maxDiff = self.settings.maxDiff
 | |
|         minDiff = self.settings.minDiff
 | |
|         locations = []
 | |
|         for il in itemLocations:
 | |
|             loc = il.Location
 | |
|             if loc.restricted:
 | |
|                 continue
 | |
|             loc.itemName = il.Item.Type
 | |
|             loc.difficulty = None
 | |
|             locations.append(loc)
 | |
|         self.smbm.resetItems()
 | |
|         ap = self.startAP
 | |
|         onlyBossesLeft = -1
 | |
|         hasOneLocAboveMinDiff = False
 | |
|         while True:
 | |
|             if not locations:
 | |
|                 return hasOneLocAboveMinDiff
 | |
|             # only two loops to collect all remaining locations in only bosses left mode
 | |
|             if onlyBossesLeft >= 0:
 | |
|                 onlyBossesLeft += 1
 | |
|                 if onlyBossesLeft > 2:
 | |
|                     return False
 | |
|             self.areaGraph.getAvailableLocations(locations, self.smbm, maxDiff, ap)
 | |
|             post = [loc for loc in locations if loc.PostAvailable and loc.difficulty.bool == True]
 | |
|             for loc in post:
 | |
|                 self.smbm.addItem(loc.itemName)
 | |
|                 postAvailable = loc.PostAvailable(self.smbm)
 | |
|                 self.smbm.removeItem(loc.itemName)
 | |
|                 loc.difficulty = self.smbm.wand(loc.difficulty, postAvailable)
 | |
|             toCollect = [loc for loc in locations if loc.difficulty.bool == True and loc.difficulty.difficulty <= maxDiff]
 | |
|             if not toCollect:
 | |
|                 # mini onlyBossesLeft
 | |
|                 if maxDiff < infinity:
 | |
|                     maxDiff = infinity
 | |
|                     onlyBossesLeft = 0
 | |
|                     continue
 | |
|                 return False
 | |
|             if not hasOneLocAboveMinDiff:
 | |
|                 hasOneLocAboveMinDiff = any(loc.difficulty.difficulty >= minDiff for loc in locations)
 | |
|             self.smbm.addItems([loc.itemName for loc in toCollect])
 | |
|             for loc in toCollect:
 | |
|                 locations.remove(loc)
 | |
|             # if len(locations) > 0:
 | |
|             #     ap = random.choice([loc.accessPoint for loc in locations])
 | 
