The level promised "toil and trouble", and boy did it deliver

I’ve been working on this level for days, coming back to it anew, reloading the code and trying and again and again. Nothing seems to work. The level says that the soldiers should attack the witches, and the archers should attack the nearest enemy. There are a few ways to implement this, most of them very wrong. Here is what I have tried, with the differences highlighted.

def chooseTarget(friend):
if friend.type == "archer":
    return friend.findNearest(friend.findEnemies())
elif friend.type == "soldier":
    return self.findNearest(self.findByType("witch"))

loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        self.command(friend, "attack", chooseTarget(friend))

This results in archers targetting the nearest throwers while the soldiers make a beeline for the bottom witch, getting whalloped by the ogres on their way past and then quickly eradicated after reaching the witch. Bummer.

def chooseTarget(friend):
    if friend.type == "archer":
        return friend.findNearest(friend.findEnemies())
    elif friend.type == "soldier":
        return ***friend***.findNearest(self.findByType("witch"))

loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        self.command(friend, "attack", chooseTarget(friend))

The archers take out the throwers, as per usual, and again they focus on the ogres as the ogres beat up the soldiers as they march past in two lines to attack both witches at the same time. There is a bloodbath resulting in a lot of humans on the ground, and no dead witches or ogres. Bummer.

def chooseTarget(friend):
    if friend.type == "archer":
        return friend.findNearest(***self***.findEnemies())
    elif friend.type == "soldier":
        return friend.findNearest(self.findByType("witch"))

loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        self.command(friend, "attack", chooseTarget(friend))

This is the best so far. The archers focus on the throwers at the top of the field, ignoring the bottom ones for some reason, and then the soldiers attack both witches at the same time. For some reason the bottom soldiers prevail before all the soldiers die and the remaining witch, both ogres and the bottom throwers turn on my archers. Slightly less of a bummer.

I’ve scoured the other post on this level and I really can’t figure out what I’m doing wrong. At one point I even just cut and pasted Midnight’s code and made the change he reported and still couldn’t make it work. Anyway, some help from one of you python gurus would be very much appreciated.

@trotod In a related post you asked if I had attempted having the archers prioritize the witches after defeating the throwers. I had not, so I amended my code to this:

def chooseTarget(friend):
    if friend.type == "archer":
        if len(self.findByType("thrower")) > 0:
            return friend.findNearest(friend.findByType("thrower"))
        elif len(self.findByType("witch")) > 0:
            return friend.findNearest(friend.findByType("witch"))
        else:
            return friend.findNearest(self.findEnemies())
    elif friend.type == "soldier":
        return friend.findNearest(self.findByType("witch"))

loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        self.command(friend, "attack", chooseTarget(friend))

The first thing it did was to throw an error. The second thing it did was have both the soldiers and the archers attack the ogres, kill them quickly, and then move on to the witches who were strangely helpless. I don’t understand it at all, but I’m glad to be past the level.

Sorry @glyph250, looks like the balance was thrown off by a recent change to add a graphics mark to the spell. It unintentionally caused it so that witches don’t heal a target which has just been healed–so in this level, the witches would end up healing each other when they first start taking damage instead of both healing the hurt ogres in front of them. I fixed it so that the old behavior was preserved and now the level should work properly with the soldiers-kill-nearest-witch-and-archers-kill-nearest strategy.

Thanks for the bug report!

    def chooseTarget(friend):
        if friend.type == "archer":
            if len(self.findByType("thrower")) > 0:
                return friend.findNearest(self.findByType("thrower"))
            elif len(self.findByType("witch")) > 0:
                return friend.findNearest(self.findByType("witch"))
            elif len(self.findByType("ogre")) > 0:
                return friend.findNearest(self.findByType("ogre"))
            else:
                return friend.findNearest(self.findEnemies())
        elif friend.type == "soldier":
            
            enemy = hero.findByType("witch")
            if enemy.health != 0:
                return friend.findNearest(self.findByType("witch")) #this is line 30
            else:
                return friend.findNearest(self.findByType("ogre"))
    
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        self.command(friend, "attack", chooseTarget(friend))

I was trying to use the code from above and work my way through the error but i can’t seem to get it, any ideas? the error is

Thank you, my new code has both of those, and it also has an Error, but it worked :smiley:

(solution removed)

Please don’t post solutions ( even those which aren’t totally correct ) on the forum as it defeats the point of the game.
Thank you.