fultonbot Posted June 1, 2021 Share Posted June 1, 2021 Is this the best way to exit a loop since there is no way to break out? Some pseudocode: for i = 0 to num_shots for j= 0 to num_enemies if j collides with i then j = num_enemies next next It appears to work, and save me a ton of cycles (removed a messy stutter), but not sire it' the best way. Quote Link to comment Share on other sites More sharing options...
+Karl G Posted June 1, 2021 Share Posted June 1, 2021 If you don't need to preserve the value of j, then that would work fine for breaking out of the inner for loop. Doing a goto to label after the first "next" would work fine, too. 1 Quote Link to comment Share on other sites More sharing options...
zzip Posted June 1, 2021 Share Posted June 1, 2021 6 minutes ago, fultonbot said: Is this the best way to exit a loop since there is no way to break out? Some pseudocode: for i = 0 to num_shots for j= 0 to num_enemies if j collides with i then j = num_enemies next next It appears to work, and save me a ton of cycles (removed a messy stutter), but not sire it' the best way. if there's no "break" command, this is the next best way 1 Quote Link to comment Share on other sites More sharing options...
fultonbot Posted June 1, 2021 Author Share Posted June 1, 2021 (edited) 25 minutes ago, Karl G said: If you don't need to preserve the value of j, then that would work fine for breaking out of the inner for loop. Doing a goto to label after the first "next" would work fine, too. for i = 0 to num_shots for j= 0 to num_enemies if j collides with I then goto break_inner_loop next _break_inner_loop next With nested loops, will the next after the jump label affect the inner loop or the outer loop if I jump out of the inner loop? Edited June 1, 2021 by fultonbot 1 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted June 1, 2021 Share Posted June 1, 2021 I *think* it should work, but when I get a chance, I can look at the generated assembly to confirm. 2 Quote Link to comment Share on other sites More sharing options...
fultonbot Posted June 1, 2021 Author Share Posted June 1, 2021 1 hour ago, Karl G said: I *think* it should work, but when I get a chance, I can look at the generated assembly to confirm. Cool, thanks. Quote Link to comment Share on other sites More sharing options...
RevEng Posted June 2, 2021 Share Posted June 2, 2021 9 hours ago, fultonbot said: for i = 0 to num_shots for j= 0 to num_enemies if j collides with I then goto break_inner_loop next _break_inner_loop next With nested loops, will the next after the jump label affect the inner loop or the outer loop if I jump out of the inner loop? Karl is correct. You can just break out of the inner loop with a goto, as you have here. The outer loop "next" won't get confused with the inner loop one. 3 Quote Link to comment Share on other sites More sharing options...
ChildOfCv Posted June 2, 2021 Share Posted June 2, 2021 If it works like M$ BASIC does, when the interpreter/compiler encounters the first FOR, it searches forward for the matching NEXT. That means it also accounts for inner-loop FORs in its search. Then it notes the location of the FOR and its NEXT as part of an internal state. This is important to note, because it shows that 1) the NEXT must be "near" the FOR. You can't have it in a GOSUB routine or behind the FOR. Also, you can only have one NEXT per FOR. So you can't have multiple cases that might NEXT themselves back to the FOR. You just have to GOTO the correct one. Quote Link to comment Share on other sites More sharing options...
fultonbot Posted June 2, 2021 Author Share Posted June 2, 2021 9 hours ago, ChildOfCv said: If it works like M$ BASIC does, when the interpreter/compiler encounters the first FOR, it searches forward for the matching NEXT. That means it also accounts for inner-loop FORs in its search. Then it notes the location of the FOR and its NEXT as part of an internal state. This is important to note, because it shows that 1) the NEXT must be "near" the FOR. You can't have it in a GOSUB routine or behind the FOR. Also, you can only have one NEXT per FOR. So you can't have multiple cases that might NEXT themselves back to the FOR. You just have to GOTO the correct one. Okay, this is good news. I think it will save my games tons of unused cycles with for/next loops running that are unnecessary. I already saw a frame-loss "stutter" go away by using this method in a collision loop. Quote Link to comment Share on other sites More sharing options...
SlidellMan Posted June 4, 2021 Share Posted June 4, 2021 I think I could try using a for/next loop for my vertical shooter. Quote Link to comment Share on other sites More sharing options...
fultonbot Posted June 7, 2021 Author Share Posted June 7, 2021 On 6/4/2021 at 7:55 AM, SlidellMan said: I think I could try using a for/next loop for my vertical shooter. What are you using now? Quote Link to comment Share on other sites More sharing options...
Pokeypy Posted June 7, 2021 Share Posted June 7, 2021 (edited) If "while" is available, but not "break", (which to my displeasure was the situation in a Pascal class I took only a few years ago) you could do: for i = 1 to num_shots j = 0 while j <= num_enemies if j collides with i then j = num_enemies j = j + 1 next i Edited June 7, 2021 by Pokeypy 1 Quote Link to comment Share on other sites More sharing options...
ChildOfCv Posted June 7, 2021 Share Posted June 7, 2021 Once you're ready to get more advanced, you could also keep the list of shots and enemies sorted by x or y, so that you can do a single-pass loop between the two where shot index and enemy index are advanced only as needed during the compare, so that you reduce the number of comparisons. Something like: x010 enemy = 1: enemy2 = 2 x020 if enemy > num_enemies then return x030 for shot = 1 to num_shots x040 if shotx(shot) < enemyx(enemy) then x120 x050 if shotx(shot) = enemyx(enemy) then x080 x060 enemy = enemy2 x070 while enemy <= num_enemies and enemyx(enemy) < shotx(shot): enemy = enemy + 1: wend: if enemy > num_enemies then return x080 for enemy2 = enemy to num_enemies x090 if enemyx(enemy2) <> shotx(shot) then x120 x100 if enemyy(enemy2) = shoty(shot) then <do collision stuff> x110 next enemy2 x120 next shot x130 return So the idea is that if all the shots are left of the leftmost enemy, you only end up going through one loop. If a shot is in the same horizontal plane with an enemy, compare all enemies in that plane. If a shot is to the right of the current leftmost enemy, choose the first enemy to the right of that one which is in the same plane or to the right. This (minus any bugs this back of the napkin loop might have) would reduce the number of comparisons from strict n^2 order to smaller pockets of n^2, but trending toward single pass. 2 Quote Link to comment Share on other sites More sharing options...
fultonbot Posted June 10, 2021 Author Share Posted June 10, 2021 On 6/7/2021 at 1:03 PM, ChildOfCv said: Once you're ready to get more advanced, you could also keep the list of shots and enemies sorted by x or y, so that you can do a single-pass loop between the two where shot index and enemy index are advanced only as needed during the compare, so that you reduce the number of comparisons. Something like: x010 enemy = 1: enemy2 = 2 x020 if enemy > num_enemies then return x030 for shot = 1 to num_shots x040 if shotx(shot) < enemyx(enemy) then x120 x050 if shotx(shot) = enemyx(enemy) then x080 x060 enemy = enemy2 x070 while enemy <= num_enemies and enemyx(enemy) < shotx(shot): enemy = enemy + 1: wend: if enemy > num_enemies then return x080 for enemy2 = enemy to num_enemies x090 if enemyx(enemy2) <> shotx(shot) then x120 x100 if enemyy(enemy2) = shoty(shot) then <do collision stuff> x110 next enemy2 x120 next shot x130 return So the idea is that if all the shots are left of the leftmost enemy, you only end up going through one loop. If a shot is in the same horizontal plane with an enemy, compare all enemies in that plane. If a shot is to the right of the current leftmost enemy, choose the first enemy to the right of that one which is in the same plane or to the right. This (minus any bugs this back of the napkin loop might have) would reduce the number of comparisons from strict n^2 order to smaller pockets of n^2, but trending toward single pass. Oh, I like this! I do some Y locations checks right now to only do collisions is they could possibly be in the same zone (it's a vertical shooter), but I do not resort the objects in a single display list. I will need to take a look a this closer. Quote Link to comment Share on other sites More sharing options...
fultonbot Posted June 10, 2021 Author Share Posted June 10, 2021 On 6/7/2021 at 7:35 AM, Pokeypy said: If "while" is available, but not "break", (which to my displeasure was the situation in a Pascal class I took only a few years ago) you could do: for i = 1 to num_shots j = 0 while j <= num_enemies if j collides with i then j = num_enemies j = j + 1 next i There is no while loop in 7800 Basic. You must simulate it with goto, or just use for/next. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.