Does Toil and Trouble have a bug?

What do you mean? I don’t get it. How do you do it? You made it kind of confusing.

# When no enemies
enemies = findEnemies() # enemies is []
enemy = findNearest(enemies) # enemy == None, because no enemy in enemies
command(friend, "attack", enemy) # enemy == None, error occurs

You seem to already know this, as you account for the issue in the main loop. The main modification you’ll really need to make is to change chooseTarget() such that you aren’t commanding a friend, but rather using return to return the appropriate enemy target.

I thought you were supost to attack the enemy directly from the chooseTarget()?

here is my edited code:


# Ogre Witches have some unpleasant surprises ready for you.

# Define a chooseTarget function which takes a friend argument
# Returns a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
def chooseTarget(friend):
    enemies = self.findEnemies()
    if len(enemies) is not 0:
        enemy = self.findNearest(enemies)
        if friend and friend.type is "soldier" and enemy and enemy.type is "witch":
                self.command("soldier", "attack", "witch")
        elif enemy:
            self.command("soldier", "attack", enemy)
        if friend and friend.type is "archer" and enemy:
            self.command("archer", "attack", enemy)
loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        chooseTarget(friend)

but on this line:

elif enemy:
            self.command("soldier", "attack", enemy)

It says “Hero Placeholder needs something to command”.

“soldier” is a string, a piece of text. You need an object to order just like you need an object to attack.
Only the name of the action “attack” is a string.

self.command(friend,"attack",enemy);

ok thanks

hghghghghghg

It’s still not working. Here is my code:

# Ogre Witches have some unpleasant surprises ready for you.

# Define a chooseTarget function which takes a friend argument
# Returns a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
def chooseTarget(friend):
    enemies = self.findEnemies()
    enemy = self.findNearest(enemies)
    if friend and friend.type is "soldier" and enemy and enemy.type is "witch":
            self.command(friend, "attack", enemy)
    if friend and friend.type is "archer" and enemy:
        self.command(friend, "attack", enemy)
loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        chooseTarget(friend)

@UltCombo@trotod I need help!!! I’ve been stuck on it for like a month now!!!:unamused::unamused::unamused::unamused::worried::worried::cry::cry::cry:

You are only ever commanding your friends to attack the nearest enemy to your hero. You will need to re-add the logic to find witches from the enemies array, or use the self.findByType('witch') method.

O. Ok thx a lot.:grinning:

EDIT: Is this what you mean?:


# Define a chooseTarget function which takes a friend argument
# Returns a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
def chooseTarget(friend):
    enemies = friend.findEnemies()
    enemy = friend.findNearest(enemies)
    targets = friend.findByType("witch")
    if friend and friend.type is "soldier" and enemy and enemy.type is "witch":
            self.command(friend, "attack", enemy)
    if friend and friend.type is "archer" and enemy:
        self.command(friend, "attack", enemy)
loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        chooseTarget(friend)

Because it isn’t working. @UltCombo Are you there?:broken_heart:

I’m on my working time here, so please have patience. :stuck_out_tongue_winking_eye:

Yes, that is what I meant, but you also have to update the code to command soldiers to attack the nearest witch if there are any witches still alive.

ok thx

hghghghghghghgh

IT DIDN’T WORK. I just can’t believe it. The archers can’t kill the ogres quickly enough and all the troops die leaving the ogres and witches alive. However, the soldiers go for only one witch and since the witches heal each other that witch doesn’t die.

Here is my code:

# Ogre Witches have some unpleasant surprises ready for you.

# Define a chooseTarget function which takes a friend argument
# Returns a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
def chooseTarget(friend):
    enemies = friend.findEnemies()
    enemy = friend.findNearest(enemies)
    witches = self.findByType("witch", enemies)
    witch = self.findNearest(witches)
    if friend and friend.type is "soldier" and enemy and witch and witch.health > 0:
            self.command(friend, "attack", witch)
    if friend and friend.type is "archer" and enemy:
        self.command(friend, "attack", enemy)
loop:
    friends = self.findFriends()
    for friend in friends:
        # Use your chooseTarget function to decide what to attack.
        chooseTarget(friend)

I really need help.

Also I think there actually is bug. However, it is different than I thought.

You’re very close to winning! :slight_smile:

Only one problem remains: you are telling all soldiers to attack the same witch (the nearest one to your hero). Command your soldiers to attack the nearest witch to them—that is, change self.findNearest(witches) to friend.findNearest(witches). After making this small change, your code should be able to win. Congratulations! :smile:

I know :grinning::grinning: I changed it before I saw the post!! Thanks a lot. :smile:

1 Like

Actually Toil and Trouble may have a bug because this:

# Ogre Witches have some unpleasant surprises ready for you. 
# Define a chooseTarget function which takes a friend argument
# Returns a target to attack, depending on the type of friend. 
# Soldiers should attack the witches, archers should attack nearest enemy. 
def chooseTarget(friend): 
    enemies = friend.findEnemies()
    enemy = friend.findNearest(enemies) 
    witches = self.findByType("witch", enemies) 
    witch = friend.findNearest(witches) 
    if friend and friend.type is "soldier" and enemy and witch and witch.health > 0: 
        self.command(friend, "attack", witch)
    else:
        self.command(friend, "attack", enemy)
    if friend and friend.type is "archer" and enemy: 
        self.command(friend, "attack", enemy) 
loop: 
    friends = self.findFriends() 
    for friend in friends:
    # Use your chooseTarget function to decide what to attack. 
        chooseTarget(friend) 
    # I have to say that these witches are tough to kill
    

And this:

# Define a chooseTarget function which takes a friend argument
# Returns a target to attack, depending on the type of friend. 
# Soldiers should attack the witches, archers should attack nearest enemy. 
def chooseTarget(friend): 
    enemies = friend.findEnemies()
    enemy = friend.findNearest(enemies) 
    witches = self.findByType("witch", enemies) 
    witch = friend.findNearest(witches) 
    if friend and friend.type is "soldier" and enemy and witch and witch.health > 0: 
        self.command(friend, "attack", witch)
    else:
        self.command(friend, "attack", enemy)
    if friend and friend.type is "archer" and enemy: 
        self.command(friend, "attack", enemy) 
loop: 
    friends = self.findFriends() 
    for friend in friends:
    # Use your chooseTarget function to decide what to attack. 
    chooseTarget(friend) 
    # I have to say that these witches are tough to kill
    

Both work! Unless you can persuade me that it isn’t a bug I have no other issues with it.

Your second snippet is equivalent to having no code at all, you are not actually commanding any of your friends. They will just act according to their default AI, which might just be enough to beat the level if you are lucky enough.

Please try resubmitting your second snippet (or just submit with no code at all) a couple more times, if you manage to beat the level frequently enough then please open a GitHub issue reporting your findings.

It does it every time.

The problem is I don’t know how to do it after i’ve created an account. Can you go to this topic and help me?