To say something or "code never finished"?


#1

Is there anything wrong with the following code? I got very strange outcomes:

  1. if I comment out the two hero.say statements then I got stuck very early, the system reporting “the code never finished, either it is really slow or infinite loop”
  2. if I leave the first “say” but comment out the second then I got further but eventually the system still reporting “the code never finished…”
  3. if I have all the three say then I get to the end where I “ran out of time” because I spent so much time saying things!
def commandHeal(paladins, target):
    for paladin in paladins:
            if target.health < target.maxHealth:
                if paladin.canCast("heal"):
                    hero.say(paladin.id + " is healing " + target.id)
                    hero.command(paladin, "cast", "heal", target)
                else:
                    hero.command(paladin, "shield")
                    hero.say(paladin.id + " is shielding")
            else:
                #hero.say("fully healed")
                break  # previous paladin has fully healed the target

#2

@dliang What does your loop code look like?

The game normally needs something to slow the looping down if there is nothing happening in the loop besides your commandHeal then that might be why.


#3

there are multiple places I use this function.
for example:

while hero.health< hero.maxHealth:
    commandHeal(paladins, hero)

or

while towers[1].health > 0:
    hero.attack(towers[1])
    commandHeal(paladins, hero)

or

while towers[0].health > 0:
    hero.attack(towers[0])
    commandHeal(paladins, hero)
    for griffin in griffins:
        hero.command(friend, "attack", towers[0])

or

for griffin in griffins:
    while griffin.health < griffin.maxHealth:
        commandHeal(paladins, griffin)

which one of these is potentially problematic?


#4

If I remember correctly, there is (was?) an issue with the paladins shielding, but I don’t remember the details… Try to search for “paladin” and “shield” and read a bit around.

On the other hand, if the paladin recently cast heal (cooldown: 0.5 + 5s) then shielded (cooldown: 0.25s) then the next turn(s) he cannot do any of those, so it’s going to be an “empty” loop, which may result in an infinite loop.


#5

@dliang In many of the places that you are using a while loop I would suggest an if-then-else statement instead.

The combat loop, or main loop, is where most of the recursion should occur. Since the code will all execute on the same thread (unlike a pet) having so many loops won’t effectively do what you think they will. Although programmatically the statements may be correct, the game, I believe, is limited to a certain number of loop iterations. This is to prevent code that really doesn’t finish.