예제 #1
0
 def __init__(self, startAP, graph, restrictions, emptyContainer):
     self.startAP = startAP
     self.cache = RequestCache()
     self.graph = graph
     self.services = RandoServices(graph, restrictions, self.cache)
     self.restrictions = restrictions
     self.settings = restrictions.settings
     self.runtimeLimit_s = self.settings.runtimeLimit_s
     self.baseContainer = emptyContainer
     self.maxDiff = self.settings.maxDiff
     self.log = log.get('Filler')
예제 #2
0
 def __init__(self, startAP, graph, restrictions, emptyContainer, endDate=infinity):
     self.startAP = startAP
     self.cache = RequestCache()
     self.graph = graph
     self.services = RandoServices(graph, restrictions, self.cache)
     self.restrictions = restrictions
     self.settings = restrictions.settings
     self.endDate = endDate
     self.baseContainer = emptyContainer
     self.maxDiff = self.settings.maxDiff
     self.log = utils.log.get('Filler')
예제 #3
0
 def randomize(self, randoSettings, graphSettings):
     self.restrictions = Restrictions(randoSettings)
     graphBuilder = GraphBuilder(graphSettings)
     container = None
     i = 0
     attempts = 500 if graphSettings.areaRando else 1
     while container is None and i < attempts:
         self.areaGraph = graphBuilder.createGraph()
         services = RandoServices(self.areaGraph, self.restrictions)
         setup = RandoSetup(graphSettings, graphLocations, services)
         container = setup.createItemLocContainer()
         if container is None:
             sys.stdout.write('*')
             sys.stdout.flush()
             i += 1
     if container is None:
         if graphSettings.areaRando:
             self.errorMsg = "Could not find an area layout with these settings"
         else:
             self.errorMsg = "Unable to process settings"
         return (True, [], [])
     graphBuilder.escapeGraph(container, self.areaGraph,
                              randoSettings.maxDiff)
     self.areaGraph.printGraph()
     filler = self.createFiller(randoSettings, graphSettings, container)
     vcr = VCR(self.seedName, 'rando') if self.vcr == True else None
     ret = filler.generateItems(vcr=vcr)
     self.errorMsg = filler.errorMsg
     return ret
예제 #4
0
 def randomize(self):
     vcr = VCR(self.seedName, 'rando') if self.vcr == True else None
     self.errorMsg = ""
     split = self.randoSettings.restrictions['MajorMinor']
     graphBuilder = GraphBuilder(self.graphSettings)
     container = None
     i = 0
     attempts = 500 if self.graphSettings.areaRando or self.graphSettings.doorsColorsRando or split == 'Scavenger' else 1
     now = time.process_time()
     endDate = sys.maxsize
     if self.randoSettings.runtimeLimit_s < endDate:
         endDate = now + self.randoSettings.runtimeLimit_s
     self.updateLocationsClass(split)
     while container is None and i < attempts and now <= endDate:
         self.restrictions = Restrictions(self.randoSettings)
         if self.graphSettings.doorsColorsRando == True:
             DoorsManager.randomize(self.graphSettings.allowGreyDoors)
         self.areaGraph = graphBuilder.createGraph(
             self.randoSettings.maxDiff)
         services = RandoServices(self.areaGraph, self.restrictions)
         setup = RandoSetup(self.graphSettings, Logic.locations, services)
         container = setup.createItemLocContainer(endDate, vcr)
         if container is None:
             sys.stdout.write('*')
             sys.stdout.flush()
             i += 1
         else:
             self.errorMsg += '\n'.join(setup.errorMsgs)
         now = time.process_time()
     if container is None:
         if self.graphSettings.areaRando:
             self.errorMsg += "Could not find an area layout with these settings\n"
         if self.graphSettings.doorsColorsRando:
             self.errorMsg += "Could not find a door color combination with these settings\n"
         if split == "Scavenger":
             self.errorMsg += "Scavenger seed generation timed out\n"
         if self.errorMsg == "":
             self.errorMsg += "Unable to process settings\n"
         return (True, [], [])
     self.areaGraph.printGraph()
     filler = self.createFiller(container, endDate)
     self.log.debug("ItemLocContainer dump before filling:\n" +
                    container.dump())
     ret = filler.generateItems(vcr=vcr)
     if not ret[0]:
         itemLocs, progItemLocs = (ret[1], ret[2])
         escapeTrigger = (
             itemLocs, progItemLocs, split
         ) if self.randoSettings.restrictions["EscapeTrigger"] else None
         escapeOk = graphBuilder.escapeGraph(container, self.areaGraph,
                                             self.randoSettings.maxDiff,
                                             escapeTrigger)
         if not escapeOk:
             self.errorMsg += "Could not find a solution for escape"
             ret = (True, ret[1], ret[2])
     self.errorMsg += filler.errorMsg
     return ret
예제 #5
0
 def randomize(self):
     self.restrictions = Restrictions(self.randoSettings)
     self.errorMsg = ""
     graphBuilder = GraphBuilder(self.graphSettings)
     container = None
     i = 0
     attempts = 500 if self.graphSettings.areaRando or self.graphSettings.doorsColorsRando else 1
     now = time.process_time()
     endDate = sys.maxsize
     if self.randoSettings.runtimeLimit_s < endDate:
         endDate = now + self.randoSettings.runtimeLimit_s
     self.updateLocationsClass()
     while container is None and i < attempts and now <= endDate:
         if self.graphSettings.doorsColorsRando == True:
             DoorsManager.randomize(self.graphSettings.allowGreyDoors)
         self.areaGraph = graphBuilder.createGraph()
         services = RandoServices(self.areaGraph, self.restrictions)
         setup = RandoSetup(self.graphSettings, Logic.locations, services)
         container = setup.createItemLocContainer()
         if container is None:
             sys.stdout.write('*')
             sys.stdout.flush()
             i += 1
         else:
             self.errorMsg += '\n'.join(setup.errorMsgs)
         now = time.process_time()
     if container is None:
         if self.graphSettings.areaRando:
             self.errorMsg += "Could not find an area layout with these settings"
         else:
             self.errorMsg += "Unable to process settings"
         return (True, [], [])
     graphBuilder.escapeGraph(container, self.areaGraph,
                              self.randoSettings.maxDiff)
     self.areaGraph.printGraph()
     filler = self.createFiller(container, endDate)
     vcr = VCR(self.seedName, 'rando') if self.vcr == True else None
     self.log.debug("ItemLocContainer dump before filling:\n" +
                    container.dump())
     ret = filler.generateItems(vcr=vcr)
     self.errorMsg += filler.errorMsg
     return ret
예제 #6
0
 def randomize(self):
     vcr = VCR(self.seedName, 'rando') if self.vcr == True else None
     self.errorMsg = ""
     split = self.randoSettings.restrictions['MajorMinor']
     graphBuilder = GraphBuilder(self.graphSettings)
     container = None
     i = 0
     attempts = 500 if self.graphSettings.areaRando or self.graphSettings.doorsColorsRando or split == 'Scavenger' else 1
     now = time.process_time()
     endDate = sys.maxsize
     if self.randoSettings.runtimeLimit_s < endDate:
         endDate = now + self.randoSettings.runtimeLimit_s
     self.updateLocationsClass(split)
     while container is None and i < attempts and now <= endDate:
         self.restrictions = Restrictions(self.randoSettings)
         if self.graphSettings.doorsColorsRando == True:
             DoorsManager.randomize(self.graphSettings.allowGreyDoors,
                                    self.player)
         self.areaGraph = graphBuilder.createGraph()
         services = RandoServices(self.areaGraph, self.restrictions)
         setup = RandoSetup(self.graphSettings, Logic.locations, services,
                            self.player)
         self.setup = setup
         container = setup.createItemLocContainer(endDate, vcr)
         if container is None:
             sys.stdout.write('*')
             sys.stdout.flush()
             i += 1
         else:
             self.errorMsg += '\n'.join(setup.errorMsgs)
         now = time.process_time()
     if container is None:
         if self.graphSettings.areaRando:
             self.errorMsg += "Could not find an area layout with these settings"
         else:
             self.errorMsg += "Unable to process settings"
     self.areaGraph.printGraph()
     return container
예제 #7
0
class Filler(object):
    def __init__(self, startAP, graph, restrictions, emptyContainer):
        self.startAP = startAP
        self.cache = RequestCache()
        self.graph = graph
        self.services = RandoServices(graph, restrictions, self.cache)
        self.restrictions = restrictions
        self.settings = restrictions.settings
        self.runtimeLimit_s = self.settings.runtimeLimit_s
        self.baseContainer = emptyContainer
        self.maxDiff = self.settings.maxDiff
        self.log = log.get('Filler')

    # reinit algo state
    def initFiller(self):
        self.ap = self.startAP
        self.initContainer()
        self.nSteps = 0
        self.errorMsg = ""
        self.settings.maxDiff = self.maxDiff
        self.runtime_s = 0

    # sets up container initial state
    def initContainer(self):
        self.container = copy.copy(self.baseContainer)

    # default continuation condition: item pool is not empty
    def itemPoolCondition(self):
        return not self.container.isPoolEmpty()

    # factory for step count condition
    def createStepCountCondition(self, n):
        return lambda: self.nSteps < n

    # calls step while condition is fulfilled and we did not hit runtime limit
    # condition: continuation condition
    # vcr: debug VCR object
    # shall return (stuck, itemLoc dict list, progression itemLoc dict list)
    def generateItems(self, condition=None, vcr=None):
        self.vcr = vcr
        self.initFiller()
        if condition is None:
            condition = self.itemPoolCondition
        isStuck = False
        startDate = time.process_time()
        while condition(
        ) and not isStuck and self.runtime_s <= self.runtimeLimit_s:
            isStuck = not self.step()
            if not isStuck:
                self.nSteps += 1
            self.runtime_s = time.process_time() - startDate
        if condition():
            isStuck = True
            if self.runtime_s > self.runtimeLimit_s:
                self.errorMsg = "Exceeded time limit of " + str(
                    self.runtimeLimit_s) + " seconds"
            else:
                self.errorMsg = "STUCK !\n" + self.container.dump()
        else:
            # check if some locations are above max diff and add relevant message
            locs = self.container.getUsedLocs(
                lambda loc: loc['difficulty'].difficulty > self.maxDiff)
            aboveMaxDiffStr = '[ ' + ' ; '.join([
                loc['Name'] + ': ' +
                diffValue2txt(loc['difficulty'].difficulty) for loc in locs
            ]) + ' ]'
            if aboveMaxDiffStr != '[  ]':
                self.errorMsg += "Maximum difficulty could not be applied everywhere. Affected locations: {}".format(
                    aboveMaxDiffStr)
            isStuck = False
        print('\n%d step(s) in %dms' %
              (self.nSteps, int(self.runtime_s * 1000)))
        if self.vcr != None:
            self.vcr.dump()
        return (isStuck, self.container.itemLocations,
                self.getProgressionItemLocations())

    # helper method to collect in item/location with logic. updates self.ap and VCR
    def collect(self, itemLoc, container=None, pickup=True):
        if container is None:
            container = self.container
        location = itemLoc['Location']
        item = itemLoc['Item']
        pickup &= 'restricted' not in location or location[
            'restricted'] == False
        self.ap = self.services.collect(self.ap,
                                        container,
                                        itemLoc,
                                        pickup=pickup)
        if self.vcr is not None:
            self.vcr.addLocation(location['Name'], item.Type)

    # called by generateItems at the end to knows which particulier
    # item/locations were progression, if the info is available
    def getProgressionItemLocations(self):
        return []

    # performs a fill step. can be multiple item/locations placement,
    # not necessarily just one.
    # return True if ok, False if stuck
    def step(self):
        pass
예제 #8
0
class Filler(object):
    def __init__(self,
                 startAP,
                 graph,
                 restrictions,
                 emptyContainer,
                 endDate=infinity):
        self.startAP = startAP
        self.cache = RequestCache()
        self.graph = graph
        self.services = RandoServices(graph, restrictions, self.cache)
        self.restrictions = restrictions
        self.settings = restrictions.settings
        self.endDate = endDate
        self.baseContainer = emptyContainer
        self.maxDiff = self.settings.maxDiff
        self.log = utils.log.get('Filler')

    # reinit algo state
    def initFiller(self):
        self.ap = self.startAP
        self.initContainer()
        self.nSteps = 0
        self.errorMsg = ""
        self.settings.maxDiff = self.maxDiff
        self.startDate = time.process_time()

    # sets up container initial state
    def initContainer(self):
        self.container = copy.copy(self.baseContainer)

    # default continuation condition: item pool is not empty
    def itemPoolCondition(self):
        return not self.container.isPoolEmpty()

    # factory for step count condition
    def createStepCountCondition(self, n):
        return lambda: self.nSteps < n

    # calls step while condition is fulfilled and we did not hit runtime limit
    # condition: continuation condition
    # vcr: debug VCR object
    # shall return (stuck, itemLoc dict list, progression itemLoc dict list)
    def generateItems(self, condition=None, vcr=None):
        self.vcr = vcr
        self.initFiller()
        if condition is None:
            condition = self.itemPoolCondition
        isStuck = False
        date = self.startDate
        while condition() and not isStuck and date <= self.endDate:
            isStuck = not self.step()
            if not isStuck:
                self.nSteps += 1
            date = time.process_time()
        if condition() or date > self.endDate:
            isStuck = True
            if date > self.endDate:
                self.errorMsg = "Exceeded time limit of " + str(
                    self.settings.runtimeLimit_s) + " seconds"
            else:
                self.errorMsg = "STUCK !\n" + self.container.dump()
        else:
            # check if some locations are above max diff and add relevant message
            locs = self.container.getUsedLocs(
                lambda loc: loc.difficulty.difficulty > self.maxDiff)
            aboveMaxDiffStr = '[ ' + ' ; '.join([
                loc.Name + ': ' + diffValue2txt(loc.difficulty.difficulty)
                for loc in locs
            ]) + ' ]'
            if aboveMaxDiffStr != '[  ]':
                self.errorMsg += "\nMaximum difficulty could not be applied everywhere. Affected locations: {}".format(
                    aboveMaxDiffStr)
            isStuck = False
        print('\n%d step(s) in %dms' %
              (self.nSteps, int((date - self.startDate) * 1000)))
        if self.vcr != None:
            self.vcr.dump()
        return (isStuck, self.container.itemLocations,
                self.getProgressionItemLocations())

    # helper method to collect in item/location with logic. updates self.ap and VCR
    def collect(self, itemLoc, container=None, pickup=True):
        containerArg = container
        if container is None:
            container = self.container
        location = itemLoc.Location
        item = itemLoc.Item
        pickup &= location.restricted is None or location.restricted == False
        self.ap = self.services.collect(self.ap,
                                        container,
                                        itemLoc,
                                        pickup=pickup)
        self.log.debug("AP=" + self.ap)
        if self.vcr is not None and containerArg is None:
            self.vcr.addLocation(location.Name, item.Type)

    # collect item pair as returned by RandoServices.getStartupProgItemsPairs
    def collectPair(self, pairItemLocDict):
        # choose a pair of items which create progression
        keys = list(pairItemLocDict.keys())
        key = random.choice(keys)

        # collect them
        availableLocs = pairItemLocDict[key]
        self.collect(ItemLocation(key[0], availableLocs[0][0]))
        self.collect(ItemLocation(key[1], availableLocs[1][0]))

    # called by generateItems at the end to knows which particulier
    # item/locations were progression, if the info is available
    def getProgressionItemLocations(self):
        return []

    # performs a fill step. can be multiple item/locations placement,
    # not necessarily just one.
    # return True if ok, False if stuck
    def step(self):
        pass