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