def getVariableSpeed(self):
     ranges = getRangeDict({
         'slowest':7,
         'slow':20,
         'medium':35,
         'fast':27,
         'fastest':11
     })
     return chooseFromRange(ranges)
Example #2
0
    def getItemPool(self):
        exceptionMessage = "Too many items already placed by the plando or not enough available locations:"
        self.itemManager.newItemPool(addBosses=False)

        # add the already placed items by the plando
        for item in self.exclude:
            if item == 'total':
                continue
            itemClass = 'Major'
            if item in [
                    'Missile', 'Super', 'PowerBomb', 'Kraid', 'Phantoon',
                    'Draygon', 'Ridley', 'MotherBrain'
            ]:
                itemClass = 'Minor'
            for i in range(self.exclude[item]):
                self.itemManager.addItem(item, itemClass)

        remain = self.maxItems - self.exclude['total']
        self.log.debug("Plando: remain start: {}".format(remain))
        if remain > 0:
            # add missing bosses
            for boss in [
                    'Kraid', 'Phantoon', 'Draygon', 'Ridley', 'MotherBrain'
            ]:
                if boss not in self.exclude or self.exclude[boss] == 0:
                    self.itemManager.addItem(boss, 'Minor')
                    self.exclude[boss] = 1
                    remain -= 1

            self.log.debug("Plando: remain after bosses: {}".format(remain))
            if remain < 0:
                raise Exception("{} can't add the remaining bosses".format(
                    exceptionMessage))

            # add missing majors
            majors = []
            for itemType in [
                    'Bomb', 'Charge', 'Ice', 'HiJump', 'SpeedBooster', 'Wave',
                    'Spazer', 'SpringBall', 'Varia', 'Plasma', 'Grapple',
                    'Morph', 'Gravity', 'XRayScope', 'SpaceJump', 'ScrewAttack'
            ]:
                if itemType not in self.exclude or self.exclude[itemType] == 0:
                    self.itemManager.addItem(itemType, 'Major')
                    self.exclude[itemType] = 1
                    majors.append(itemType)
                    remain -= 1

            self.log.debug("Plando: remain after majors: {}".format(remain))
            if remain < 0:
                raise Exception("{} can't add the remaining majors: {}".format(
                    exceptionMessage, ', '.join(majors)))

            # add minimum minors to finish the game
            for (itemType, minimum) in [('Missile', 3), ('Super', 2),
                                        ('PowerBomb', 1)]:
                if itemType not in self.exclude:
                    self.exclude[itemType] = 0
                while self.exclude[itemType] < minimum:
                    self.itemManager.addItem(itemType, 'Minor')
                    self.exclude[itemType] += 1
                    remain -= 1

            self.log.debug(
                "Plando: remain after minimum minors: {}".format(remain))
            if remain < 0:
                raise Exception(
                    "{} can't add the minimum minors to finish the game".
                    format(exceptionMessage))

            # add energy
            energyQty = self.qty['energy']
            limits = {
                "sparse": [('ETank', 4), ('Reserve', 1)],
                "medium": [('ETank', 8), ('Reserve', 2)],
                "vanilla": [('ETank', 14), ('Reserve', 4)]
            }
            for (itemType, minimum) in limits[energyQty]:
                if itemType not in self.exclude:
                    self.exclude[itemType] = 0
                while self.exclude[itemType] < minimum:
                    self.itemManager.addItem(itemType, 'Major')
                    self.exclude[itemType] += 1
                    remain -= 1

            self.log.debug("Plando: remain after energy: {}".format(remain))
            if remain < 0:
                raise Exception("{} can't add energy".format(exceptionMessage))

            # add ammo
            nbMinorsAlready = self.exclude['Missile'] + self.exclude[
                'Super'] + self.exclude['PowerBomb']
            minorLocations = max(0,
                                 0.66 * self.qty['minors'] - nbMinorsAlready)
            maxItems = len(
                self.itemManager.getItemPool()) + int(minorLocations)
            rangeDict = getRangeDict(self.qty['ammo'])
            while len(
                    self.itemManager.getItemPool()) < maxItems and remain > 0:
                item = chooseFromRange(rangeDict)
                self.itemManager.addMinor(item)
                remain -= 1

            self.log.debug("Plando: remain after ammo: {}".format(remain))

            # add nothing
            while remain > 0:
                self.itemManager.addMinor('Nothing')
                remain -= 1

            self.log.debug("Plando: remain after nothing: {}".format(remain))

        return self.itemManager.getItemPool()
Example #3
0
    def addAmmo(self):
        self.calcMaxAmmo()
        # we have to remove the minors already added
        maxItems = min(
            len(self.itemManager.getItemPool()) + int(self.minorLocations),
            self.maxItems)
        self.log.debug("maxItems: {}".format(maxItems))
        ammoQty = self.qty['ammo']
        if not self.qty['strictMinors']:
            rangeDict = getRangeDict(ammoQty)
            self.log.debug("rangeDict: {}".format(rangeDict))
            while len(self.itemManager.getItemPool()) < maxItems:
                item = chooseFromRange(rangeDict)
                self.itemManager.addMinor(item)
        else:
            minorsTypes = ['Missile', 'Super', 'PowerBomb']
            totalProps = sum(ammoQty[m] for m in minorsTypes)
            minorsByProp = sorted(minorsTypes, key=lambda m: ammoQty[m])
            maxMinors = 0.66 * (maxItems - 5)
            totalMinorLocations = int(maxMinors * self.qty['minors'] / 100)
            self.log.debug("totalProps: {}".format(totalProps))
            self.log.debug(
                "totalMinorLocations: {}".format(totalMinorLocations))

            def ammoCount(ammo):
                return float(
                    len([
                        item for item in self.itemManager.getItemPool()
                        if item.Type == ammo
                    ]))

            def targetRatio(ammo):
                return round(float(ammoQty[ammo]) / totalProps, 3)

            def cmpRatio(ammo, ratio):
                thisAmmo = ammoCount(ammo)
                thisRatio = round(thisAmmo / totalMinorLocations, 3)
                nextRatio = round((thisAmmo + 1) / totalMinorLocations, 3)
                self.log.debug(
                    "{} current, next/target ratio: {}, {}/{}".format(
                        ammo, thisRatio, nextRatio, ratio))
                return abs(nextRatio - ratio) < abs(thisRatio - ratio)

            def fillAmmoType(ammo, checkRatio=True):
                ratio = targetRatio(ammo)
                self.log.debug("{}: target ratio: {}".format(ammo, ratio))
                while len(self.itemManager.getItemPool()) < maxItems and (
                        not checkRatio or cmpRatio(ammo, ratio)):
                    self.log.debug("Add {}".format(ammo))
                    self.itemManager.addMinor(ammo)

            for m in minorsByProp:
                fillAmmoType(m)
            # now that the ratios have been matched as exactly as possible, we distribute the error
            def getError(m, countOffset=0):
                return abs((ammoCount(m) + countOffset) / totalMinorLocations -
                           targetRatio(m))

            while len(self.itemManager.getItemPool()) < maxItems:
                minNextError = 1000
                chosenAmmo = None
                for m in minorsByProp:
                    nextError = getError(m, 1)
                    if nextError < minNextError:
                        minNextError = nextError
                        chosenAmmo = m
                self.itemManager.addMinor(chosenAmmo)
        # fill up the rest with blank items
        for i in range(self.maxItems - maxItems):
            self.itemManager.addMinor('Nothing')
Example #4
0
 def determineParameters(self, progSpeed=None, progDiff=None):
     self.chooseLocRanges = getRangeDict(self.getChooseLocs(progDiff))
     self.chooseItemRanges = getRangeDict(self.getChooseItems(progSpeed))
     self.spreadProb = self.progSpeedParams.getSpreadFactor(progSpeed)
     self.lateDoorsProb = self.progSpeedParams.getLateDoorsProb(progSpeed)