For some reason, when I make an “if self.now = 16:”, my hero goes and does the things inside that “if” statement before it is really 16 seconds.
Also, do you have to finish the code for the code to really work correctly?
For help, I will show you my code. I would really appreciate the help.
# Fight enemies for 15 seconds.
# Keep count whenever an enemy is defeated.
enemiesDead = 0
coinsCollected = 0
while self.now < 16:
enemy = self.findNearest(self.findEnemies())
if enemy:
while enemy.health > 0:
self.attack(enemy)
enemiesDead = enemiesDead + 1
else:
self.moveXY(54, 33)
# Tell Naria how many enemies you defeated.
elif self.now = 16:
self.moveXY(59, 33)
self.say(enemiesDead)
# Collect coins until the clock reaches 30 seconds.
while self.now < 31 & self.now > 16:
coin = self.findNearest(self.findItems())
if coin:
pos = coin.pos
x = coin.pos.x
y = coin.pos.y
self.moveXY(x, y)
# Tell Naria how much gold you collected.
# Fight enemies until the clock reaches 45 seconds.
# Remember to reset the count of defeated enemies!
# Tell Naria how many enemies you defeated.
P.S. : I am not finished with the code yet, I am just solving this problem right now.
This means you are creating a new variable called self.now and you are giving it the value 16
Writing a=16 will always evaluate to true so the program immediately jumps inside the elif
What you need:
# first loop
while self.now() <= 15:
# first loop stuff here
# kill enemies, increase counters, etc.
# first loop finished when self.now() is more than 15
# observe the line indentation - the lines start directly from the margin
# so they are not part of the first loop
# go to Naria tell her stuff
# initialize the counters for the second loop
while self.now() <= 30:
# and so on
# these lines are indented so they are inside the second loop
Loop and while(True) are are changed in code combat to add a wait at the end of the loop, preventing a loop execution that will take 0 time. Such a loop execution will crash your code because it creates an infinite cycle
Just add a move to the center to make sure your hero always does something (and thus make the time pass)
while self.now()<=16:
if coin:
# collect coin
else:
# move to the center OR
self.wait(0.001)
results in an infinite loop (not sure why).
However, you can do this:
while True:
#block of code
if self.now() >= number:
break #breaks out of the current loop
This looks like it has the same effect (terminating the outer loop when the time reaches number), but it doesn’t result in an infinite loop.
Also check the level’s guide if you’re stuck or need more information. I think it outlines the same method.
If your loop takes zero frames to execute, it will execute indefinitely preventing the game from advancing. That is, your code will be stuck running in the same game frame forever with the same outcome in all iterations.
That is because CodeCombat’s interpreter applies special treatment to the loop: and while True: constructs—if an iteration takes zero frames to execute, the interpreter will automatically wait for the next game frame before running the next iteration. You can read more about this in this GitHub issue.
This also means that the “automatically wait for next game frame” behavior is only applied when you explicitly input loop: or while True:, not when the while condition expression evaluates to true (e.g. while 1==1:, while self.now() < 9000: etc) which can then result in an infinite loop that may prevent the game state from advancing if all loop iterations take zero frames to execute.
I believe this is all very tricky for the target audience which is people that are learning to code. Even regular contributors like @zuf didn’t know about these intricacies. In my humble opinion, the game engine should handle this problem so the players don’t need to. But, in fact, this is pretty tricky to do as it may result in an unwanted delay in your loops, as you can see from the comments in the linked issue.
I also found that several people (including me!) have run into this issue while playing the Bookkeper level, as you can see in the relevant thread.
Perhaps it is time to try to address this, or maybe this will be solved by the new interpreter that is in the works?
/cc @nick