Example #1
0
    def canPassThreeMuskateers(self):
        sm = self.smbm
        destroy = sm.wor(
            sm.haveItem('Plasma'),
            sm.haveItem('ScrewAttack'),
            sm.wand(
                sm.heatProof(),  # this takes a loooong time ...
                sm.wor(sm.haveItem('Spazer'), sm.haveItem('Ice'))))
        if destroy.bool == True:
            return destroy
        # if no adapted beams or screw attack, check if we can go both ways
        # (no easy refill around) with supers and/or health

        # - super only?
        ki = 1800.0
        sup = 300.0
        nbKi = 6.0
        if sm.itemCount('Super') * 5 * sup >= nbKi * ki:
            return SMBool(True, 0, items=['Super'])

        # - or with taking damage as well?
        dmgKi = 200.0 / sm.getDmgReduction(False)
        if (sm.itemCount('Super') * 5 * sup) / ki + (
                sm.energyReserveCount() * 100 - 2) / dmgKi >= nbKi:
            return sm.wand(
                sm.heatProof(), SMBool(True, 0, items=[
                    'Super', 'ETank'
                ]))  # require heat proof as long as taking damage is necessary

        return SMBool(False, 0)
Example #2
0
 def enoughStuffGT(self):
     (ammoMargin, secs) = self.canInflictEnoughDamages(3000, ignoreMissiles=True) # requires 10 supers or charge for the fight
     if ammoMargin == 0:
         return SMBool(False)
     else:
         # TODO add energy check
         return SMBool(True, easy)
Example #3
0
 def itemCountOk(self, item, count, difficulty=0):
     if self.itemCount(item) >= count:
         if item in ['ETank', 'Reserve']:
             item = '{}-{}'.format(count, item)
         return SMBool(True, difficulty, items = [item])
     else:
         return SMBool(False)
Example #4
0
 def enoughStuffCroc(self):
     # say croc has ~5000 energy, and ignore its useless drops
     (ammoMargin, secs) = self.canInflictEnoughDamages(5000, givesDrops=False)
     if ammoMargin == 0:
         return SMBool(False)
     else:
         return SMBool(True, easy)
Example #5
0
    def canGoThroughLowerNorfairEnemy(self,
                                      nmyHealth,
                                      nbNmy,
                                      nmyHitDmg,
                                      supDmg=300.0):
        sm = self.smbm
        # supers only
        if sm.itemCount('Super') * 5 * supDmg >= nbNmy * nmyHealth:
            return SMBool(True, 0, items=['Super'])

        # - or with taking damage as well?
        (dmgRed, redItems) = sm.getDmgReduction(envDmg=False)
        dmg = nmyHitDmg / dmgRed
        if sm.heatProof(
        ) and (sm.itemCount('Super') * 5 * supDmg) / nmyHealth + (
                sm.energyReserveCount() * 100 - 2) / dmg >= nbNmy:
            # require heat proof as long as taking damage is necessary.
            # display all the available energy in the solver.
            return sm.wand(
                sm.heatProof(),
                SMBool(True,
                       0,
                       items=redItems + [
                           'Super', '{}-ETank - {}-Reserve'.format(
                               self.smbm.itemCount('ETank'),
                               self.smbm.itemCount('Reserve'))
                       ]))

        return sm.knowsDodgeLowerNorfairEnemies()
Example #6
0
    def enoughStuffsPhantoon(self):
        sm = self.smbm
        (ammoMargin, secs) = self.canInflictEnoughDamages(2500, doubleSuper=True)
        if ammoMargin == 0:
            return SMBool(False)
        # print('PHANTOON', ammoMargin, secs)
        difficulty = self.computeBossDifficulty(ammoMargin, secs,
                                                Settings.bossesDifficulty['Phantoon'])
        if difficulty < 0:
            return SMBool(False)
        hasCharge = sm.canFireChargedShots()
        hasScrew = sm.haveItem('ScrewAttack')
        if hasScrew:
            difficulty /= Settings.algoSettings['phantoonFlamesAvoidBonusScrew']
        elif hasCharge:
            difficulty /= Settings.algoSettings['phantoonFlamesAvoidBonusCharge']
        elif not hasCharge and sm.itemCount('Missile') <= 2: # few missiles is harder
            difficulty *= Settings.algoSettings['phantoonLowMissileMalus']
        difficulty = self.adjustHealthDropDiff(difficulty)
        fight = SMBool(True, difficulty)

        return sm.wor(fight,
                      sm.wand(sm.knowsMicrowavePhantoon(),
                              sm.haveItem('Plasma'),
                              sm.canFireChargedShots(),
                              sm.haveItem('XRayScope')))
Example #7
0
 def canFly(self):
     sm = self.smbm
     if sm.haveItem('SpaceJump') == True:
         return SMBool(True, easy, items=['SpaceJump'])
     elif sm.canInfiniteBombJump() == True:
         return sm.knowsInfiniteBombJump()
     else:
         return SMBool(False)
Example #8
0
 def enoughStuffBotwoon(self):
     # say botwoon has 5000 energy : it is actually 3000 but account for missed shots
     (ammoMargin, secs) = self.canInflictEnoughDamages(5000,
                                                       givesDrops=False)
     if ammoMargin == 0:
         return SMBool(False)
     else:
         return SMBool(True, easy)
Example #9
0
 def enoughStuffBotwoon(self):
     # say botwoon has 4000 energy : it is actually 3000 but account for missed shots
     # 4000 to allow for low% botwoon without charge beam (10 - 10 | missiles - supers)
     # there is a setup to "never" miss a shot by only shooting him when he exits through the top left hole
     (ammoMargin, secs) = self.canInflictEnoughDamages(4000, givesDrops=False)
     if ammoMargin == 0:
         return SMBool(False)
     else:
         return SMBool(True, easy)
Example #10
0
 def canFlyDiagonally(self):
     sm = self.smbm
     if sm.haveItem('SpaceJump') == True:
         return SMBool(True, easy, items=['SpaceJump'])
     elif sm.wand(sm.haveItem('Morph'), sm.haveItem('Bomb'),
                  sm.knowsDiagonalBombJump()) == True:
         return sm.knowsDiagonalBombJump()
     else:
         return SMBool(False)
Example #11
0
    def getPathDifficulty(self, path, availAps):
        pdiff = SMBool(True, 0)
        for ap in path:
            diff = availAps[ap]['difficulty']
            pdiff = SMBool(True,
                           difficulty=max(pdiff.difficulty, diff.difficulty),
                           knows=list(set(pdiff.knows + diff.knows)),
                           items=pdiff.items + diff.items)

        return pdiff
Example #12
0
    def removeItem(self, item):
        # randomizer removed an item (or the item was added to test a post available)
        if self.isCountItem(item):
            count = getattr(self, item + 'Count') - 1
            setattr(self, item + 'Count', count)
            if count == 0:
                setattr(self, item, SMBool(False))
        else:
            setattr(self, item, SMBool(False))

        Cache.reset()
Example #13
0
    def enoughStuffsRidley(self):
        (ammoMargin, secs) = self.canInflictEnoughDamages(18000, doubleSuper=True, power=True, givesDrops=False)
        if ammoMargin == 0:
            return SMBool(False)

        # print('RIDLEY', ammoMargin, secs)
        diff = self.computeBossDifficulty(ammoMargin, secs,
                                          Settings.bossesDifficulty['Ridley'])
        if diff < 0:
            return SMBool(False)
        else:
            return SMBool(True, diff)
Example #14
0
 def wor2(self, a, b):
     if a.bool is True and b.bool is True:
         if a.difficulty <= b.difficulty:
             return SMBool(True, a.difficulty, a.knows, a.items)
         else:
             return SMBool(True, b.difficulty, b.knows, b.items)
     elif a.bool is True:
         return SMBool(True, a.difficulty, a.knows, a.items)
     elif b.bool is True:
         return SMBool(True, b.difficulty, b.knows, b.items)
     else:
         return SMBool(False)
Example #15
0
    def enoughStuffsKraid(self):
        sm = self.smbm
        (ammoMargin, secs, ammoItems) = self.canInflictEnoughDamages(1000)
        if ammoMargin == 0:
            return SMBool(False)
        #print('KRAID True ', ammoMargin, secs)
        (diff, defenseItems) = self.computeBossDifficulty(ammoMargin, secs,
                                                          Settings.bossesDifficulty['Kraid'])
        if diff < 0:
            return SMBool(False)

        return SMBool(True, diff, items=ammoItems+defenseItems)
Example #16
0
 def energyReserveCountOk(self, count, difficulty=0):
     if self.energyReserveCount() >= count:
         nEtank = self.itemCount('ETank')
         if nEtank > count:
             nEtank = int(count)
         items = '{}-ETank'.format(nEtank)
         nReserve = self.itemCount('Reserve')
         if nEtank < count:
             nReserve = int(count) - nEtank
             items += ' - {}-Reserve'.format(nReserve)
         else:
             nReserve = 0
         return SMBool(True, difficulty, items = [items])
     else:
         return SMBool(False)
Example #17
0
    def removeItem(self, item):
        # randomizer removed an item (or the item was added to test a post available)
        if self.isCountItem(item):
            count = getattr(self, item + 'Count') - 1
            setattr(self, item + 'Count', count)
            if count == 0:
                setattr(self, item, SMBool(False))
        else:
            dup = 'dup_' + item
            if getattr(self, dup, None) is None:
                setattr(self, item, SMBool(False))
            else:
                delattr(self, dup)

        Cache.removeItem(item)
Example #18
0
 def __init__(self,
              name,
              graphArea,
              transitions,
              traverse=lambda sm: SMBool(True),
              exitInfo=None,
              entryInfo=None,
              roomInfo=None,
              shortName=None,
              internal=False,
              boss=False):
     self.Name = name
     self.GraphArea = graphArea
     self.ExitInfo = exitInfo
     self.EntryInfo = entryInfo
     self.RoomInfo = roomInfo
     self.Internal = internal
     self.Boss = boss
     self.transitions = transitions
     self.traverse = traverse
     if shortName is not None:
         self.ShortName = shortName
     else:
         self.ShortName = str(self)
     self.distance = 0
     # inter-area connection
     self.ConnectedTo = None
Example #19
0
 def wand(self, *args):
     if False in args:
         return self.smboolFalse
     else:
         return SMBool(True, sum([smb.difficulty for smb in args]),
                       [know for smb in args for know in smb.knows],
                       [item for smb in args for item in smb.items])
 def cleanLocsAfterSolver(self):
     # restricted locs can have their difficulty set, which can cause them to be reported in the
     # post randomization warning message about locs with diff > max diff.
     for il in self.itemLocations:
         loc = il['Location']
         if loc.get('restricted') == True and loc.get('difficulty', False) == True:
             loc['difficulty'] = SMBool(False)
Example #21
0
 def itemCountOk(self, item, count, difficulty=0):
     if self.itemCount(item) >= count:
         if item in ['ETank', 'Reserve']:
             item = str(count) + '-' + item
         return SMBool(True, difficulty, items=[item])
     else:
         return self.smboolFalse
Example #22
0
    def addItem(self, item):
        # a new item is available
        setattr(self, item, SMBool(True, items=[item]))
        if self.isCountItem(item):
            setattr(self, item + 'Count', getattr(self, item + 'Count') + 1)

        Cache.reset()
Example #23
0
    def enoughStuffsKraid(self):
        sm = self.smbm
        (ammoMargin, secs) = self.canInflictEnoughDamages(1000)
        if ammoMargin == 0:
            return SMBool(False)
        #print('KRAID True ', ammoMargin, secs)
        diff = self.computeBossDifficulty(ammoMargin, secs,
                                          Settings.bossesDifficulty['Kraid'])
        if diff < 0:
            return SMBool(False)

        # need missile or super to open the eye door
        if sm.wor(sm.haveItem('Missile'), sm.haveItem('Super')) == False:
            return SMBool(False)
        else:
            return SMBool(True, diff)
Example #24
0
 def __init__(self):
     self.smboolFalse = SMBool(False)
     Cache.reset()
     self.helpers = HelpersGraph(self)
     self.createFacadeFunctions()
     self.createKnowsFunctions()
     self.resetItems()
Example #25
0
    def load(self):
        # update the parameters in the parameters classes: Knows, Settings

        # Knows
        for param in self.params['Knows']:
            if isKnows(param) and hasattr(Knows, param):
                setattr(Knows, param, SMBool(self.params['Knows'][param][0],
                                             self.params['Knows'][param][1],
                                             ['{}'.format(param)]))
        # Settings
        ## hard rooms
        for hardRoom in ['X-Ray', 'Gauntlet']:
            if hardRoom in self.params['Settings']:
                Settings.hardRooms[hardRoom] = Settings.hardRoomsPresets[hardRoom][self.params['Settings'][hardRoom]]

        ## bosses
        for boss in ['Kraid', 'Phantoon', 'Draygon', 'Ridley', 'MotherBrain']:
            if boss in self.params['Settings']:
                Settings.bossesDifficulty[boss] = Settings.bossesDifficultyPresets[boss][self.params['Settings'][boss]]

        ## hellruns
        for hellRun in ['Ice', 'MainUpperNorfair', 'LowerNorfair']:
            if hellRun in self.params['Settings']:
                Settings.hellRuns[hellRun] = Settings.hellRunPresets[hellRun][self.params['Settings'][hellRun]]

        # Controller
        for button in self.params['Controller']:
            if isButton(button):
                setattr(Controller, button, self.params['Controller'][button])
Example #26
0
    def getNewAvailNodes(self,
                         availNodes,
                         nodesToCheck,
                         smbm,
                         maxDiff,
                         item=None):
        newAvailNodes = {}
        # with python >= 3.6 the insertion order in a dict is keeps when looping on the keys,
        # so we no longer have to sort them.
        for src in nodesToCheck:
            for dstName in src.transitions:
                dst = self.accessPoints[dstName]
                if dst in availNodes or dst in newAvailNodes:
                    continue
                if smbm is not None:
                    if self._useCache == True and (src, dst,
                                                   item) in self.apCache:
                        diff = self.apCache[(src, dst, item)]
                    else:
                        tFunc = src.transitions[dstName]
                        diff = smbm.eval(tFunc)
                        if self._useCache == True:
                            self.apCache[(src, dst, item)] = diff
                else:
                    diff = SMBool(True)
                if diff.bool and diff.difficulty <= maxDiff:
                    if src.GraphArea == dst.GraphArea:
                        dst.distance = src.distance + 0.01
                    else:
                        dst.distance = src.distance + 1
                    newAvailNodes[dst] = {'difficulty': diff, 'from': src}

                #self.log.debug("{} -> {}: {}".format(src.Name, dstName, diff))
        return newAvailNodes
Example #27
0
 def __init__(self,
              name,
              graphArea,
              transitions,
              traverse=lambda sm: SMBool(True),
              exitInfo=None,
              entryInfo=None,
              roomInfo=None,
              internal=False,
              boss=False,
              escape=False,
              start=None,
              dotOrientation='w'):
     self.Name = name
     self.GraphArea = graphArea
     self.ExitInfo = exitInfo
     self.EntryInfo = entryInfo
     self.RoomInfo = roomInfo
     self.Internal = internal
     self.Boss = boss
     self.Escape = escape
     self.Start = start
     self.DotOrientation = dotOrientation
     self.intraTransitions = self.sortTransitions(transitions)
     self.transitions = copy.copy(self.intraTransitions)
     self.traverse = traverse
     self.distance = 0
     # inter-area connection
     self.ConnectedTo = None
Example #28
0
 def computeLocDiff(self, tdiff, diff, pdiff):
     allDiff = SMBool(diff.bool,
                      difficulty=max(tdiff.difficulty, diff.difficulty,
                                     pdiff.difficulty),
                      knows=list(set(tdiff.knows + diff.knows +
                                     pdiff.knows)),
                      items=tdiff.items + diff.items + pdiff.items)
     return (allDiff, None)
Example #29
0
 def canPassTerminatorBombWall(self, fromLandingSite=True):
     sm = self.smbm
     return sm.wor(
         sm.wand(
             sm.haveItem('SpeedBooster'),
             sm.wor(SMBool(not fromLandingSite, 0),
                    sm.knowsSimpleShortCharge(), sm.knowsShortCharge())),
         sm.canDestroyBombWalls())
Example #30
0
 def enoughStuffsDraygon(self):
     sm = self.smbm
     (ammoMargin, secs) = self.canInflictEnoughDamages(6000)
     # print('DRAY', ammoMargin, secs)
     if ammoMargin > 0:
         diff = self.computeBossDifficulty(ammoMargin, secs,
                                           Settings.bossesDifficulty['Draygon'])
         if diff < 0:
             fight = SMBool(False)
         else:
             fight = SMBool(True, diff)
         if sm.haveItem('Gravity') == False:
             fight.difficulty *= Settings.algoSettings['draygonNoGravityMalus']
         fight.difficulty = self.adjustHealthDropDiff(fight.difficulty)
     else:
         fight = SMBool(False)
     return sm.wor(fight,
                   sm.wand(sm.knowsDraygonGrappleKill(),
                           sm.haveItem('Grapple')),
                   sm.wand(sm.knowsMicrowaveDraygon(),
                           sm.haveItem('Plasma'),
                           sm.canFireChargedShots(),
                           sm.haveItem('XRayScope')),
                   sm.wand(sm.haveItem('Gravity'),
                           sm.knowsDraygonSparkKill(),
                           sm.haveItem('SpeedBooster')))