# Ogre Witches have some unpleasant surprises ready for you.
def chooseTarget(friend):
friends = hero.findFriends()
for friend in friends:
soldier = hero.findNearest(hero.findByType("soldier")
if friend and friend.type == "soldier":
return "witch"
else:
return "enemy"
# Define a chooseTarget function which takes a friend argument
# Returns the a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
while True:
friends = hero.findFriends()
enemy = hero.findNearestEnemy()
for friend in friends:
hero.command(friend, "attack", chooseTarget())
pass
Been messing with various code on this level and cannot get through it. My latest code above seems to have some kind of parsing t colon error? Help!
# Ogre Witches have some unpleasant surprises ready for you.
def chooseTarget(friend):
friends = hero.findFriends()
witch = friend.findNearest(hero.findByType("witch"))
enemy = friend.findNearestEnemy()
soldier = hero.findNearest(hero.findByType("soldier"))
for friend in friends:
if friend.type == "soldier":
hero.command(friend, "attack", witch)
else:
hero.command(friend, "attack", enemy)
# Define a chooseTarget function which takes a friend argument
# Returns the a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
while True:
friends = hero.findFriends()
enemy = hero.findNearestEnemy()
if enemy:
hero.attack(enemy)
for friend in friends:
chooseTarget(friend)
pass
I’m getting closer! thanks. They target correctly now, but the soldiers all attack one witch. Not sure how to split them out - friend.findNearest works but then friend.findByType does not…
def chooseTarget(friend): # a single friend enters the function
friends = hero.findFriends() # then you redefine this friend
for friend in friends:
# code
while True:
friends = hero.findFriends()
# code
for friend in friends:
chooseTarget(friend) # you are passing a single friend to the function
You have a mismatch of friend in friends and a friend. You have to get rid of some code.
# Ogre Witches have some unpleasant surprises ready for you.
def chooseTarget(friend):
witch = friend.findNearest(hero.findByType("witch"))
enemy = friend.findNearestEnemy()
soldier = hero.findNearest(hero.findByType("soldier"))
for friend in friends:
if friend.type == "soldier":
hero.command(friend, "attack", witch)
else:
hero.command(friend, "attack", enemy)
# Define a chooseTarget function which takes a friend argument
# Returns the a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
while True:
friends = hero.findFriends()
enemy = hero.findNearestEnemy()
if enemy:
hero.attack(enemy)
for friend in friends:
chooseTarget(friend)
pass
Took the redefinition line out but exactly the same thing happens. All the soldiers run to one witch…
Get rid of for friend in friends in def chooseTarget. And in the beginning get rid of soldier = hero.findNearest etc
and put enemy = friend.findNearestEnemy() at the top
you also want to add enemies.findNearestEnemies() at the top to.
You have to add witches = hero.findByType("witch", enemies) and witch = friend.findNearest (witches). Get rid of if enemy: and hero.attack(enemy) but keep enemy = hero.findNearestEnemy()
It looks to me like your function is trying to do too much. If you reset the code on this level, the for loop in the while True loop is where you should be commanding the troops to attack, not the function. The function should just define which type of enemy the soldiers and archers should attack. See the comments:
# Define a chooseTarget function which takes a friend argument
# Returns the a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
Use the function to return witch or enemy based upon the type of friend. Then use the while True loop to command your troops. Also, in your function you’ve only defined one type of friend; soldier. You need to define archers as well.
Thanks for reply. In my first post this is what I had but then others’ advise changed it to how it is now. I will change back to my original post and include a definition of archers. I was hoping that because they are not soldiers it would just follow the else path.
# Ogre Witches have some unpleasant surprises ready for you
def chooseTarget(friend):
for friend in friends:
soldier = hero.findNearest(hero.findByType("soldier"))
archer = hero.findNearest(hero.findByType("archer"))
if friend and friend.type == "soldier":
return witch
if friend and friend.type == "archer":
return enemy
# Define a chooseTarget function which takes a friend argument
# Returns the a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
while True:
friends = hero.findFriends()
enemy = hero.findNearestEnemy()
witch = hero.findNearest(hero.findByType("witch"))
for friend in friends:
hero.command(friend, "attack", chooseTarget())
pass
Now everyone just goes forward… I am literally going round in circles!
That’s much closer but you need to get rid of the for loop in the function. It doesn’t belong there. The rest of the function is good.
In your while True loop, you don’t do a check for the existence of an enemy, nor do you use the variable enemy or witch, so they don’t need to be there. It will work without defining enemy and using if enemy, but when the enemies aren’t there in the end you’ll get a null error. The correct way to do it would be to define the variable enemy as the output of your function and then do an ```if enemy`` conditional inside the for loop. Then command the attack but by using enemy as the object to attack. Since it’s defined as the output of your function, it will send the troops to their respective targets.
# Ogre Witches have some unpleasant surprises ready for you
def chooseTarget(friend):
soldier = hero.findNearest(hero.findByType("soldier"))
archer = hero.findNearest(hero.findByType("archer"))
if friend and friend.type == "soldier":
return witch
if friend and friend.type == "archer":
return enemy
# Define a chooseTarget function which takes a friend argument
# Returns the a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
while True:
friends = hero.findFriends()
enemy = chooseTarget()
for friend in friends:
if enemy:
hero.command(friend, "attack", enemy)
pass
Fairly sure this replicates your direction. I think I have reached my programming limit for now! Because this still doesn’t work!
did you tab back all the lines in the function so they are properly aligned? They should just be one tab or four spaces over from the left. It doesn’t look like it. Also, put your enemy definition inside the for loop, just before the if enemy: conditional. Make these corrections and it should work.
One more thing I just noticed. You have defined soldier and archer so they are variables, but then you use them as strings. Either use them as strings as you presently have and do away with the variable definition, or change the strings to use the variables. Either should work.
And one more, you don’t define witch as a variable in your function.
# Ogre Witches have some unpleasant surprises ready for you
def chooseTarget(friend):
soldier = hero.findNearest(hero.findByType("soldier"))
archer = hero.findNearest(hero.findByType("archer"))
witch = hero.findNearest(hero.findByType("witch"))
if friend and friend.type == soldier:
return witch
if friend and friend.type == archer:
return enemy
# Define a chooseTarget function which takes a friend argument
# Returns the a target to attack, depending on the type of friend.
# Soldiers should attack the witches, archers should attack nearest enemy.
while True:
friends = hero.findFriends()
for friend in friends:
enemy = chooseTarget()
if enemy:
hero.command(friend, "attack", enemy)
pass
I think I made the recommended changes but it still doesn’t work. They all die!
You don’t have a definition for the variable, enemy, in your function.
Also, it definitely works better with the archers and soldiers used as strings instead of variables in the function. I’m not sure why but it probably has something to do with how the methods defining them are processed. Just use them as strings and do away with the variables.
One more thing, you are using hero.findNearest for the method to define witch. Who should be finding the witch? The same goes for the method used in the enemy definition. Read this hint again: