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)
Exemple #4
0
    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