Summit's Gate Trouble Finder

Can someone help me?
The bug finder thing says “else: for-else statment unsupoorted”
and it doesn’t tell me what line its on.

Here’s my code. I’ve been struggling on this level for nearly 5 days now.

def commandArchers():
    for archer in self.findByType(archer, self.findFriends()):
        nearestEnemy = archer.findNearestEnemy()
    if nearestEnemy:
        self.command(archer, 'attack', nearestEnemy)
    else:
        hero.command(archer, 'defend', hero)

def commandSoldiers():
    for soldier in self.findByType('soldier', self.findFriends()):
        nearestEnemy = soldier.findNearestEnemy()
    if nearestEnemy:
        self.command(soldier, 'attack', nearestEnemy)
    else:
        hero.command(soldier, 'defend', hero)

def summonGriffins():
    if hero.gold > hero.costOf('griffin-rider'):
        hero.summon('griffin-rider')
        
def pick():
    item = hero.findNearestItem()
    flag = hero.findFlag()
    if item:
        hero.moveXY(item.pos.x, item.pos.y)
    if flag:
        hero.pickUpFlag(flag)

def commandGriffins():
    for griffin in self.findByType('griffin-rider', self.findFriends()):
        enemies = griffin.findEnemies()
        nearestEnemy = self.findNearest(enemies)    
    if nearestEnemy:
        self.command(griffin, 'attack', nearestEnemy)
    else:
        self.command(griffin, 'defend', self)


def weakestFriend():
    weakestFriend = None
    weakestHealth = 999
    for friend in self.findFriends():
        if friend.health < friend.maxHealth and friend.health < weakestHealth:
            weakestHealth = friend.health
            weakestFriend = friend
        if weakestFriend:
            return weakestFriend


def commandPaladins():
    for paladin in self.findByType('paladin', self.findFriends()):
        if paladin.canCast('heal', self):   
            if self.health < 3000:
                self.command(paladin, 'cast', 'heal', self)
            else:
                weakestFriend2 = weakestFriend()
            if weakestFriend2:
                self.command(paladin, 'cast', 'heal', weakestFriend2)
            else:
                hero.command(paladin, 'defend', hero)

                
def summonGriffin():
    if self.gold >= self.costOf('griffin-rider'):
        self.summon('griffin-rider')

def moveForward():
    targetPos = {"x": 328, "y": 35}
    self.move(targetPos)


def pickTarget():
    enemies = self.findEnemies()
    target = None
    minDistance = 9999
    for enemy in enemies:
        if enemy.type is not 'door':
            if enemy.type is 'catapult':
                target = enemy
                break
        elif enemy.type is 'warlock':
            target = enemy
            break
        elif enemy.type is 'witch':
            target = enemy
            break
        elif enemy.type is 'chieftain':
            target = enemy
            break   
    else:
        
        if self.distanceTo(enemy) < minDistance:
            minDistance = self.distanceTo(enemy)
            target = enemy
        if target:
            return target


def commandHero():
    target = pickTarget()   
    if target:
        while target.health > 0:
            if hero.canCast('chain-lightning', target):
                hero.cast('chain-lightning', target)
        if hero.isReady('stomp'):
            hero.stomp()
    elif hero.isReady('throw'):
        hero.throw(target)
    else:
        self.attack(target)
        hero.shield()
        moveForward()
    def attackCatapults():
        catapults = self.findByType('catapult')

if len(catapults):
    for catapult in catapults:
        while catapult.health > 0:
            self.attack(catapult)
    while True:
        pick()
        summonGriffins()
        commandPaladins()
        commandArchers()
        commandSoldiers()
        commandGriffins()
        pickTarget()
        commandHero()
        attackCatapults()

It’s in the pickTarget() function. You’ve put an else statement after a for statement (as the bug finder said). Did you mean to put that else inside the for loop?

Also, the second half (after the first else) won’t run, because else finishes a line of conditional statements.

Is this supposed to be indented backwards?

This should be “archer”. You’re looking for a type inside friends, not an object.
I hope this helps,
Danny

1 Like

So for the second half, would it just be best to delete this:
< if weakestFriend: return weakestFriend >

and I meant to put an else in the pickTarget() spot.

Any advice on what I should do for that to correct it? Would an Elif work better?

and its now

def commandArchers():
    for archer in self.findByType(archer, self.findFriends()):
        nearestEnemy = archer.findNearestEnemy()
        if nearestEnemy:
            self.command(archer, 'attack', nearestEnemy)
        else:
            hero.command(archer, 'defend', hero)

I fixed the for-else issue.

now im having this:
TypeError: needs an object

def commandHero():
    target = pickTarget()   
    if target:
        while target.health > 0:
            if hero.canCast('chain-lightning', target):
                hero.cast('chain-lightning', target)
        if hero.isReady('stomp'):
            hero.stomp()
    elif hero.isReady('throw'):
        hero.throw(target)
    else:
        self.attack(target)
        hero.shield()
        moveForward()
    def attackCatapults():
        catapults = self.findByType('catapult')

You’ve used target here without checking if it exists. In fact, because they are elif to the if target, they will only run when there isn’t a target, yet you still throw and attack it.
Make sure you check target exists for those statements too.