Help with an infinite loop error in Sarven Brawl

Hi, I have been trying to solve the Sarven Brawl level, and it won’t let me finish because it keeps giving me an error message.

> Your code never finished. It is either slow, or it has an infinite loop.

I am pretty sure that it is the while true loop that makes it infinite, but before I have used while true loops and it has always worked. I tried to fix this myself by making the while true into while hero.time<=120: but it still gives me the same error message. Could you please help me? Here is my code:

def onSpawn():
    pet.moveXY(28, 110)
    while hero.time<=120: # I'm trying to make it not an infinite loop
        
        if pet.isReady("shape-shift"): # This is for telling my pet to shape shift
            pet.shapeShift()
            
        enemy = hero.findNearestEnemy()
        
        if hero.gold >=hero.costOf("soldier"): # I am getting some soldiers
            hero.summon("soldier")
        
        for friend in hero.findFriends():
            enemy = friend.findNearestEnemy()
            
            # The next 4 lines are for commanding my skeletons and soldiers
            if friend.type=="soldier":
                hero.command(friend, "defend", hero)
            if friend.type=="skeleton":
                hero.command(friend, "defend", hero)
        
    
pet.on("spawn", onSpawn) # This is for my pet to do the function pet

if not hero.hasEffect("invisibility"): 
    if hero.canCast("invisibility", hero):
        hero.cast("invisibility", hero)


hero.moveXY(93,64)

while hero.time<=120: # I'm tying to make it not an infinite loop
    flag = hero.findFlag()
    enemy = hero.findNearestEnemy()
    
    if enemy and enemy.health>0: # I'm cheacking whether I should attack the enemy 
        hero.attack(enemy)
        if hero.cast("drain-life", enemy):
            hero.cast("drain-life", enemy)
        if hero.canCast("poison-cloud", enemy):
            hero.cast("poison-cloud", enemy)
    
    if hero.canCast("summon-undead", hero): # This summons my skeletons
        hero.cast("summon-undead")
    if hero.canCast("summon-burl", hero): # Here I'm summoning the burls
        hero.cast("summon-burl")
    
    dead_Corpses = hero.findCorpses() # I'm finding a array of Corpses
    for dead in dead_Corpses:
        if dead and hero.canCast("raise-dead"):
            hero.cast("raise-dead") # RAISE THE DEAD!
    
    if hero.canCast("sacrifice"): # This sacrifices my skeletons which I command  
        skeleton = hero.findNearest( hero.findByType( "skeleton" ) )
        if skeleton:
            hero.cast( "sacrifice", skeleton, hero )

Thank you!

2 Likes

Welcome back, @nathannaveen! :partying_face:

I know that this

Does not work as intended for some reason. Try to make that a while True loop and then break when hero.time > 120 instead.

Andrei

I totally agree with Deadpool from another post:

onSpawn() is wrong: You hero is told to do different things simultaneously in two places ( the main while loop and onSpawn()). Only the code about the pet must be in onSpawn(). Pets also have a bunch of abilities:
image
image

1 Like

I tried to do what both of you said to, but it doesn’t seem to work for me. I changed my code to:

def onSpawn():
    pet.moveXY(28, 110)
    while True:
        
        if pet.isReady("shape-shift"): # This is for telling my pet to shape-shift
            pet.shapeShift()
            
        enemy = hero.findNearestEnemy()
        
    
pet.on("spawn", onSpawn) # This is for my pet to do the function pet

hero.moveXY(93,64)

while True:
    flag = hero.findFlag()
    enemy = hero.findNearestEnemy()
    
    if enemy and enemy.health>0: # I'm cheacking whether I should attack the enemy 
        hero.attack(enemy)
        if hero.cast("drain-life", enemy):
            hero.cast("drain-life", enemy)
        if hero.canCast("poison-cloud", enemy):
            hero.cast("poison-cloud", enemy)
    
    if hero.canCast("summon-undead", hero): # This summons my skeletons
        hero.cast("summon-undead")
    if hero.canCast("summon-burl", hero): # Here I'm summoning the burls
        hero.cast("summon-burl")
    
    dead_Corpses = hero.findCorpses() # I'm finding a array of Corpses
    for dead in dead_Corpses:
        if dead and hero.canCast("raise-dead"):
            hero.cast("raise-dead") # RAISE THE DEAD!
    
    if hero.gold >=hero.costOf("soldier"): # I am getting some soldiers
        hero.summon("soldier")
    
    for friend in hero.findFriends():
        enemy = friend.findNearestEnemy()
        
        # The next 4 lines are for commanding my skeletons and soldiers
        if friend.type=="soldier":
            hero.command(friend, "defend", hero)
        if friend.type=="skeleton":
            hero.command(friend, "defend", hero)
    
    if hero.time > 120:
        break

After that didn’t work, I commented out my onSpawn code, but it still says that it takes too long, or it is an infinite loop. Is there a way to expand the amount of time I can have on this level, like:

import sys
sys.setExecutionLimit(120)

That’s probably due the number of ogres getting spawned by your level of Sarven Brawl (quite high I presume).
I’ve got a pretty much invincible (because of the maths of the combo) tactic for Saven Statue (I’m on 10), but I can’t do number 10 because the massive numbers of ogres slow down the level so much it makes an infinite loop. If you don’t want to get a more powerful computer (I’m not sure that would even solve the problem) then you may just have to end Sarven Brawl there.
Reloading the whole page works quite a lot as well. You could also try a different browser. If you’re submitting some successful code don’t skip it or it will make it more likely that it will crash.
Danny

1 Like

I’m not sure a better PC helps much either. I’m running on a Zbook workstation (Xion proc, 32 gb…yada yada yada) and I seem to have similar problems.

Didn’t Nick once post that Firefox was the best for running simulations (or maybe it was Chaboi)? Perhaps the same is true here too.

2 Likes

If I’m not mistaken it was MunkeyShynes. But I think Mozilla maybe is good for simulation, but not for replayable levels coding. Besides, does anybody remember the url for ogres, munchkins and so on images?

Looks a little bit strange to me;)

  hero.canCast("summon-undead", hero)
  hero.canCast("summon-burl", hero)

t̶h̶e̶ ̶p̶a̶r̶a̶m̶e̶t̶e̶r̶ ̶h̶e̶r̶o̶ ̶i̶n̶ ̶b̶o̶t̶h̶ ̶e̶x̶p̶r̶e̶s̶s̶i̶o̶n̶s̶ ̶i̶s̶ ̶a̶l̶s̶o̶ ̶s̶t̶r̶a̶n̶g̶e̶ ̶t̶o̶ ̶m̶e̶ : it’s OK
Running your code I’ve been instantly killed by a sand yak but i didn’t get an infinite loop
Your pet code is OK if you delete

        enemy = hero.findNearestEnemy()

I deleted also the flag code

1 Like

Thanks for the suggestions, I will try and keep you posted.

Right now I’m using Brave, so I tried it on Firefox but it didn’t help. Do you have any other suggestions?

Thanks

Why does it look strange?

Because in case of “poison-cloud” you check if hero can cast spell correctly. But with “drain-life” condition differs and it looks like it won’t work.

1 Like

The reason I do:

dead_Corpses = hero.findCorpses() 
    for dead in dead_Corpses:
        if dead and hero.canCast("raise-dead"):
            hero.cast("raise-dead") 

is because in the methods section it says that it should be "drain-life"

image

Uhm, well try to change

if hero.cast("drain-life", enemy):
            hero.cast("drain-life", enemy)

to

if hero.canCast("drain-life", enemy):
            hero.cast("drain-life", enemy)
2 Likes

Thank you I didn’t see that, I will have to fix it.

2 Likes

At which repeatable level are you? You don’t avoid the yaks with this code if you don’t hide in the middle of the map between the rocks.

1 Like

I am at level 6, and I hide in the rocks.

1 Like

I fixed that but it is still an infinite loop.

1 Like

Maybe there is some more things. Try to add one line of moving somewhere at the start. Sometimes it might help. As @xython mentioned your code is qiute fine, so it should work. Unfortunatly I can’t try cause I’m not sub.

2 Likes