[SOLVED] Can't solve Sarven Shepherd

I’ve been trying to solve this for weeks with no luck, and I’ve almost every single thing possible but it yielded the same results. If there’s something I’m doing wrong, please tell me.

# Use while loops to pick out the ogre

while True:
    enemies = hero.findEnemies()
    enemyIndex = 0

    # Wrap this logic in a while loop to attack all enemies.
    # Find the array's length with:  len(enemies)
while enemyIndex < len(enemies):
    enemy = enemies[enemyIndex]
    # "!=" means "not equal to."
    if enemy.type != "sand-yak":
        # While the enemy's health is greater than 0, attack it!
        while enemy.health > 0:
            hero.attack(enemy)
        pass

    # Between waves, move back to the center.
hero.moveXY(40, 32)

The code will only iterate through a single time because you aren’t incrementing. Also, there is a structural problem. The line, while enemyIndex < len(enemies): is not inside the while True: loop (it should be).

3 Likes

Thank you! I was able to solve the level.

2 Likes

This is too slow

while True:
    enemies = hero.findEnemies()
    enemyIndex = 0
    
    # Wrap this logic in a while loop to attack all enemies.
    # Find the array's length with:  len(enemies)
    while enemyIndex < len(enemies):
        enemy = enemies[enemyIndex]
        # "!=" means "not equal to."
        if enemy.type != "sand-yak":
            # While the enemy's health is greater than 0, attack it!
            while enemy.health > 0:
                hero.attack(enemy)
            pass
        # Between waves, move back to the center.
    hero.moveXY(40, 32)

That is because you currently have an infinite loop. Remember that your second while loop is looking for a condition. In this instance it is whether or not:

enemyIndex < len(enemies) # if number in enemyIndex is less than the count of enemies

Your enemyIndex starts at Zero which is less than the length of enemies (or count of enemies in a general sense), at what point in your code do you increase your enemyIndex to eventually go through all of the enemies? Your enemyIndex helps you walk through all the enemies in the array (enemies) to compare each one at a time. If you need more help, below is another post that covers the topic a little more.

2 Likes

I just removed this line of code and it worked :D. Plus I can never understand why if it is not a sand yak it doesn’t move on to the next closest enemy!

DYK that the code

enemyIndex = 0
for enemy in enemies:
    hero.attack(enemy)

would do this entire loop through the array index for me!!!
so much easier!

You are correct. A for loop will get the same results with this problem and I prefer to use that option if I can because it is quite simple.

Although, you didn’t learn the structure of the while loop with the condition which will be used in a few levels coming up. The only detail you were missing in your first code is to increment (increase) the index by 1 after every loop.

enemyIndex +=1

There are certain situations where a for loop won’t work well and you will need to use the while loop with a condition. Below is the basic structure for a while condition loop using the index method.

index = 0
while index < len(arrayVariable): # later you will need the range(len(arrayVariable)) for certain levels.  Will learn range() later.
    object = arrayVariable[index] # the index gives the position number for the array
    # add the rest of your code to loop through
    index += 1 # at the end to change to the next position in the array

My enemy.type isn’t working. do you have to have a certain item on?

No specific item is needed for enemy.type that I know of. Are you working on this same level?

There are two parts to the enemy.type.

  1. You have to create a variable name, in this case enemy. (The variable name can be anything)
enemy = hero.findNearestEnemy()
#or
for enemy in enemies
  1. You need to know the different types of enemy to compare and make sure they are in quotations
"sand-yak", "munchkin", "shaman"

When you click on the enemy, it will show you their type next to their name.

type

Hi I don’t find where is the problem… thanks for your time

return  #Commented out to stop infinite loop.
# Use while loops to pick out the ogre

while True:
    enemies = hero.findEnemies()
    enemyIndex = 0
    
    # Wrap this logic in a while loop to attack all enemies.
    
    while enemyIndex < len(enemies):
        # Find the array's length with:  len(enemies)
        enemy = enemies[enemyIndex]
        
        # "!=" means "not equal to."
        if enemy.type != "sand-yak":
            # While the enemy's health is greater than 0, attack it!
            while enemy.health < 0:
                hero.attack(enemy)
                enemyIndex += 1
        
    pass
    # Between waves, move back to the center.
    hero.moveXY(40, 30)
    

Hi @albert, I can see two problems here:

  1. is here:
# While the enemy's health is greater than 0, attack it!
while enemy.health < 0:

It’s just a simple typo, you’ll probably be able to see it now. (p.s. it involves what the comment says. And if you think about it your code doesn’t make sense, why attack a dead enemy?)
2. the placement of this line:

if you put it there what happens if the enemy is a sand yak? That’s why you’ve got an infinite loop, you need to put it somewhere else (same line but different level of indentation).
I hope this helps,
Danny

hi deadpool198 thanks for your answer

I changed the > symbol but I didn’t understand where I should put enemyIndex… I tried on a lot of places but … nothing, The point is that I didn’t really understand how it works…

@ albert, notice how your loop statements are stacked:

while True:
    enemies = hero.findEnemies()
    enemyIndex = 0
    
    # Wrap this logic in a while loop to attack all enemies.
    
    while enemyIndex < len(enemies):
        # Find the array's length with:  len(enemies)
        enemy = enemies[enemyIndex]
        
        # "!=" means "not equal to."
        if enemy.type != "sand-yak":
            # While the enemy's health is greater than 0, attack it!
            while enemy.health < 0:
                hero.attack(enemy)
                enemyIndex += 1
        
    pass
    # Between waves, move back to the center.
    hero.moveXY(40, 30)

You start with the ‘while true’…let’s call that the parent loop.
This runs the whole thing.

Then, you embed another while loop, ‘while enemyIndex < len(enemies’. Let’s call this the ‘child1’ loop.
This iterates through each enemy found.

You also embed in child1, the if statement, 'if enemy.type != “sand-yak”.
This acts on those enemies, but only if they are not a sand-yak.

Finally, you have ‘while enemy.health > 0’.
This acts on the enemy currently being fought.

Thinking of these levels, where would you want to increment enemyIndex? It would be after attacking an enemy that IS other than a yak, not while attacking it, but before moving to the next enemy. You have the statement in almost the proper spot.

1 Like

Thanks for your response dedreous
i thought that i have to place enemyIndex += 1 after the attack
but if the program doesn’t count the yaks that appear i tought it wouldn’t count all other enemies…
I tried “enemyIndex += 1” after attack inside the “while enemy.health > 0:” loop, outside of it but inside
“if enemy.type != “sand-yak”:” after and before the “while enemy.health>0:” loop
also outside of them on while true loop but after all the other code…
i had no problems before placing enemyIndex += 1…

i tried your code and didn’t work

it says code never finished it’s either really slow or has an infinite loop

sorry for my english

Your enemyIndex += 1 should be the closing statement of the while enemyIndex loop, so yes, it does need to be after the attack. As such, it should be placed in line with the while enemyIndex statement, not the other if and while ones. In your code above, you have it as the closing statement of the embedded while enemy.health loop.

Your English is just fine :wink:

1 Like

Hi this level is becoming a nightmare :crazy_face: :crazy_face: :crazy_face: :crazy_face:

There is my new code:

# Use while loops to pick out the ogre

while True:
    enemies = hero.findEnemies()
    enemyIndex = 0
    
    # Wrap this logic in a while loop to attack all enemies
    while enemyIndex < len(enemies):
        # Find the array's length with:  len(enemies)
        enemy = enemies[enemyIndex]
        
        
        # "!=" means "not equal to."
        if enemy.type != "sand-yak":
            # While the enemy's health is greater than 0, attack it!
            while enemy.health < 0:
                hero.attack(enemy)
                
        enemyIndex += 1
    # Between waves, move back to the center.
    hero.moveXY(40, 30)
    pass


The hero just walks to the 40,30 point

I feel that I should program something to count the yak that is in the screen, when I see the program I think that the logic of it doesn’t allow the program to restart the while true loop.
Like if the program blocked on it, so the program can continue reading the new “enemies” that come on the screen… but of course I am not a programer.

Thanks for your time guys,…

@albert: Well, your enemyIndex is in the right spot now, but you still have ‘enemy.health < 0’…you want to keep attacking if enemy.health is more than zero.

:upside_down_face: :upside_down_face: :upside_down_face: :upside_down_face: :upside_down_face: :upside_down_face: :upside_down_face: :upside_down_face: :upside_down_face:
I have no merit because I didn’t solve it but I learnt a lot…
thank you guys so much
really thank you all

Hi again, @dedreous.
I am stuck on Sarven Shepherd.
Here’s my code:

# Use while loops to pick out the ogre
while True:
    enemies = hero.findEnemies()
    enemyIndex = 0
    if enemyIndex < len(enemies):
        enemy = enemies[enemyIndex]
    # "!=" means "not equal to."
    if enemy.type != "sand-yak":
        # While the enemy's health is greater than 0, attack it!
        while enemy.health > 0:
            hero.attack(enemy)
        pass
    enemyIndex += 1
# Between waves, move back to the center.
hero.moveXY(40, 32)

My hero is standing still.
Looked at other forums similar to this one (inclusive of this one) and added the pieces of code necessary and still my hero is stationary. Can you edit my code and explain how to beat this level?