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.
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./
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
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
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.
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.
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.