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