def createHelpingBaseLists(self): self.helpContainer = ContainerSoftBackup(self.container)
class FillerRandom(Filler): def __init__(self, startAP, graph, restrictions, container, endDate, diffSteps=0): super(FillerRandom, self).__init__(startAP, graph, restrictions, container, endDate) self.miniSolver = MiniSolver(startAP, graph, restrictions) self.diffSteps = diffSteps self.beatableBackup = None self.nFrontFillSteps = 0 self.stepIncr = 1 def initFiller(self): super(FillerRandom, self).initFiller() self.log.debug("initFiller. maxDiff=" + str(self.settings.maxDiff)) self.createBaseLists() def createBaseLists(self): self.baseContainer = ContainerSoftBackup(self.container) self.helpContainer = ContainerSoftBackup(self.container) def createHelpingBaseLists(self): self.helpContainer = ContainerSoftBackup(self.container) def resetContainer(self): self.baseContainer.restore(self.container, resetSM=True) def resetHelpingContainer(self): self.helpContainer.restore(self.container, resetSM=False) def isBeatable(self, maxDiff=None): return self.miniSolver.isBeatable(self.container.itemLocations, maxDiff=maxDiff) def getLocations(self, item): return [ loc for loc in self.container.unusedLocations if self.restrictions.canPlaceAtLocation(item, loc, self.container) ] # implemented in the speedrun version def getHelp(self): pass def step(self): # here a step is not an item collection but a whole fill attempt date = time.process_time() while not self.container.isPoolEmpty() and date <= self.endDate: item = random.choice(self.container.itemPool) locs = self.getLocations(item) if not locs: self.log.debug( "FillerRandom: constraint collision during step {} for item {}" .format(self.nSteps, item.Type)) self.resetHelpingContainer() date = time.process_time() continue loc = random.choice(locs) itemLoc = ItemLocation(item, loc) self.container.collect(itemLoc, pickup=False) date = time.process_time() if date > self.endDate: return False # pool is exhausted, use mini solver to see if it is beatable if self.isBeatable(): sys.stdout.write('o') sys.stdout.flush() else: if self.diffSteps > 0 and self.settings.maxDiff < infinity: if self.nSteps < self.diffSteps: couldBeBeatable = self.isBeatable(maxDiff=infinity) if couldBeBeatable: difficulty = max([ il.Location.difficulty.difficulty for il in self.container.itemLocations ]) if self.beatableBackup is None or difficulty < self.beatableBackup[ 1]: self.beatableBackup = ( self.container.itemLocations, difficulty) elif self.beatableBackup is not None: self.container.itemLocations = self.beatableBackup[0] difficulty = self.beatableBackup[1] self.errorMsg += "Could not find a solution compatible with max difficulty. Estimated seed difficulty: " + diffValue2txt( difficulty) sys.stdout.write('O') sys.stdout.flush() return True else: return False # reset container to force a retry self.resetHelpingContainer() if (self.nSteps + 1) % 100 == 0: sys.stdout.write('x') sys.stdout.flush() # help speedrun filler self.getHelp() return True
def createBaseLists(self): self.baseContainer = ContainerSoftBackup(self.container) self.helpContainer = ContainerSoftBackup(self.container)
def getStartupProgItemsPairs(self, ap, container): self.log.debug("getStartupProgItemsPairs: kickstart") (itemLocDict, isProg) = self.getPossiblePlacements(ap, container, ComebackCheckType.NoCheck) # save container saveEmptyContainer = ContainerSoftBackup(container) # key is (item1, item2) pairItemLocDict = {} # keep only unique items in itemLocDict uniqItemLocDict = {} for item, locs in itemLocDict.items(): if item.Type in ['NoEnergy', 'Nothing']: continue if item.Type not in [it.Type for it in uniqItemLocDict.keys()]: uniqItemLocDict[item] = locs if not uniqItemLocDict: return None if self.cache: self.cache.reset() curLocsBefore = self.currentLocations(ap, container) if not curLocsBefore: return None self.log.debug("search for progression with a second item") for item1, locs1 in uniqItemLocDict.items(): # collect first item in first available location matching restrictions if self.cache: self.cache.reset() firstItemPlaced = False for loc in curLocsBefore: if self.restrictions.canPlaceAtLocation(item1, loc, container): self.log.debug("getStartupProgItemsPairs. firstItemPlaced") container.collect(ItemLocation(item1, loc)) firstItemPlaced = True break if not firstItemPlaced: saveEmptyContainer.restore(container) continue saveAfterFirst = ContainerSoftBackup(container) curLocsAfterFirst = self.currentLocations(ap, container) if not curLocsAfterFirst: saveEmptyContainer.restore(container) continue for item2, locs2 in uniqItemLocDict.items(): if item1.Type == item2.Type: continue if (item1, item2) in pairItemLocDict.keys() or ( item2, item1) in pairItemLocDict.keys(): continue # collect second item in first available location if self.cache: self.cache.reset() secondItemPlaced = False for loc in curLocsAfterFirst: if self.restrictions.canPlaceAtLocation( item2, loc, container): container.collect(ItemLocation(item2, loc)) secondItemPlaced = True break if not secondItemPlaced: saveAfterFirst.restore(container) continue curLocsAfterSecond = self.currentLocations(ap, container) if not curLocsAfterSecond: saveAfterFirst.restore(container) continue pairItemLocDict[(item1, item2)] = [ curLocsBefore, curLocsAfterFirst, curLocsAfterSecond ] saveAfterFirst.restore(container) saveEmptyContainer.restore(container) # check if a pair was found if len(pairItemLocDict) == 0: self.log.debug("no pair was found") return None else: if self.log.getEffectiveLevel() == logging.DEBUG: self.log.debug("pairItemLocDict:") for key, locs in pairItemLocDict.items(): self.log.debug( "{}->{}: {}".format(key[0].Type, key[1].Type, [l['Name'] for l in locs[2]])) return pairItemLocDict