'...but it's dead!' and my people freeze!


#1

I 'm using ‘chain-lightning’ and after successful and lethal hit my people freeze.

while True:
    commandPeasants(peasantsByPos)
    enemy = hero.findNearestEnemy()
    if enemy :
        if hero.canCast('chain-lightning', enemy):
            hero.cast('chain-lightning', enemy)
        if hero.isReady('bash'):
            hero.bash(enemy)
        else:
            hero.attack(enemy)
    else:
        hero.move(hPos)

How to avoid this problem?
Changed “if hero.isReady(‘bash’)” to “elif hero.isReady(‘bash’)” but I think if there is no enemy the people will freeze again.


#2

Make it a separate for loop that way this does not happen


#3

I didn’t grasp your idea? Can you elaborate how, when, where to use this ‘separate for loop’ . I suppose the attacking code must be inside it.
/ The message ‘…but it’s dead!’ is like a warning for me for doing something inefficient.
I’ve succeeded to pass Cloudrip Treasure Level 2 and 3 without changing a bit of my code, but this message keeps to haunt me./


#4

You have not defined “hpos” on your last line of code


#5

For chain-lightning, i ussually use if ready :grin:


#6

hPos is a constant position in the map.
“For chain-lightning, i usually use if ready” - that sounds right - merci :slight_smile:


#7

Let me troubleshoot your code right now. Thx


#8

Is this all of your code because when i ran it it said that peasantpos was not defined


#9

Also, when you said “if hero.isReady(‘bash’):” you put ’ instead of "


#10

This is where I thought the problem is. The code run without problems for 1, 2, 3 of Cloudrip Treasure. It crashed only once when submitting for level 2


#11

Back to what i said, when i ran your code it said that you have not defined peasantpos :wink:


#12


#13

It crashed on level 2. peasantpos is a result of a function. The code will be deleted here, cause it’s a working solution.


#14

I might be wrong but I think it is bash the problem,
the code will check if bash is ready but not if the enemy alive after you casted "chain-ligthing"
chain lightning might have killed the next target who is specified as enemy variable.
But the enemy is dead.
and then your code get stuck there.

Try running the code without bash I would say and check if it bugs again


#15

the enemy is still alive, and the hero only attacks if the hero is able to bash and if hero wasn’t ready to cast chain-lightning to the enemy. The elif statement works like else, as it works if the previous if statement(s) didn’t work, but you could specify what it should check like the if statement. Also you could place multiple elif statements, unlike the else statement.


#16
if enemy :
    if hero.canCast('chain-lightning', enemy):
        hero.cast('chain-lightning', enemy) # the enemy is dead here
    if hero.isReady('bash'):
        hero.bash(enemy) # the enemy is None, so the people freeze

I changed if hero.isReady(‘bash’) to elif hero.isReady(‘bash’) and the problem was resolved . The problem arose after I cut&paste

    if hero.canCast('chain-lightning', enemy):
        hero.cast('chain-lightning', enemy)

without changing the previous first ‘if’ to ‘elif’ . So the lesson learned: " Better to type everything, cut&paste is dangerous!" Gabriel_Dupuis and Seojin_Roy_Lee nailed the problem! Thanks also to TheDemonPrince!
The second question remains: How to get rid of '… BUT IT’S DEAD". I suppose someone of my warriors killed the enemy and my hero wandered aimlessly.


#17

It seems like a lot of extra, but I check both if the attack is ready AND if the target is alive before attacking on each of those if statements.

You have to remember, any given attack can kill the enemy, bringing their health <0, making the next attack a waste of time at best, an attack against a null target at worst. If attacking a null target, you bring back the issue of not being able to perform the function.

You can also break down each step into a function that you can save for later levels.

function castChain(enemy) {
Validate
attack
}

It will increase your overall code size a little, but you’ll be able to create a library of functions that you can use in all of your missions, and it should run a little faster/better because functions should be pre-loaded before the main loop begins, but that can be tested and verified in console.

Then instead of "if enemy: if hero… elif hero… else: … you could simply call the functions in order, knowing that they will self check/validate and if good, attack.

So your main() gets simplified.