How to cleave when multiple enemies nearby? (Python)


#1

As the topic says, how do I cleave when multiple enemies are nearby? My code below:

while True:
enemies = hero.findEnemies()

for enemy in enemies:
    distance = hero.distanceTo(enemy)
    enemyCount = 0
    if distance < 5:
        enemyCount = enemyCount + 1
        
    if enemyCount = 4 and hero.isReady("cleave"):
            hero.say("Cleaving " + enemyCount + " Enemies!")
            hero.cleave(enemy)
    else:
        hero.attack(enemy)

I wasn’t sure if the code was working, so I had the hero say how many enemies are nearby, but all he says is “Cleaving True Enemies”

There’s another topic that talked about this, but I still didn’t understand what to do.


#2

###I see multiple problems here:

  • everything under the while loop should be indented at least one level
  • enemyCount is reset for every enemy, so you never reach more than one
  • the for loop should end after the first if, otherwise the last commands are run for every enemy
  • in the if statement you have to use a double equal sign not a single one (e.g. if a == 1)

###So let’s see the corrected code:

while True:
    enemies = hero.findEnemies()
    enemyCount = 0             # reset the counter once per loop, not for each enemy

    for enemy in enemies:
        distance = hero.distanceTo(enemy)
        if distance < 5:
            enemyCount = enemyCount + 1
    # the 'for' loop should end here

    if enemyCount == 4 and hero.isReady("cleave"):     # use '==' not '='
        hero.say("Cleaving " + enemyCount + " Enemies!")  # remove this line once OK
        hero.cleave(enemy)
    else:
        hero.attack(enemy)        # this way you attack the last enemy in the list

###And now let’s optimize it a bit:

  • rename enemyCount to nearEnemies to make it more clear
  • cleave if there are 4 or more enemies (use >= instead of ==)
  • if too few enemies are near, attack the nearest enemy
while True:
    # populate variables once per loop
    enemies = hero.findEnemies()
    nearEnemies = 0
    
    # count the number of near enemies
    for enemy in enemies:
        if hero.distanceTo(enemy) < 5:      # don't really need a 'distance' variable
            nearEnemies += 1                # same as 'nearEnemies = nearEnemies + 1'

    # if enough enemies are near and 'cleave' is ready
    if enemyCount >= 4 and hero.isReady("cleave"):
        hero.cleave(enemy)
    # otherwise attack the nearest one
    else:
        hero.attack(hero.findNearest(enemies))   # or 'hero.findNearestEnemy()' depending on your glasses


#3

There is missprint in your code.
It the same that you checkin if operation

enemyCount = (4 and hero.isReady("cleave"))

is Success.

The code have to be

if enemyCount == 4 and hero.isReady("cleave"):

#4

Many thanks for the help, and for optimizing the code too! I haven’t actually gotten through the 4th world yet (clouddrip mountain, I’m on the 3rd world right now) so I had no idea how to use the for-loop properly.


#5

This problem can be spitted into two parts:

  • Finding the enemies that are close enough to you
  • Cleave if the amount of the close enough enemies is big enough to be worthwhile cleaving
def countNearbyEnemies(range_in_metres)
    count = 0
    enemies = hero.findEnemies():
    for enemy in enemies:
        if hero.distanceTo(enemy) < range_in_metres:
            count += 1
    return count
end

def worthwhileCleaving(minimumNearbyEnemiesCount):
    range = 5 # you can change it to whatever makes sense in a level
    count = countNearbyEnemies(range)
    return count >= minimumNearbyEnemiesCount

while True:
    if hero.isReady('cleave') and worthwhileCleaving(3): # more than 3 enemies 
        hero.cleave(hero.findNearest(hero.findEnemies()))
    else:
        # blah blah blah
        pass