Define the job before the loop
For a four-target teaching example, the job is “process these four targets once.” Start with remaining = 4. After confirmed work, subtract one. The normal end is remaining = 0; an unsuccessful action goes to a recovery branch instead of silently pretending to finish.
This is a model of loop reasoning, not a DLC command listing. The game’s actual action result and failure signal must come from its current documentation.
A useful progress measure has three properties: it starts with a bound, it changes after meaningful success, and it cannot decrease forever. “The program is still running” is not progress.
Trace four successful steps
| Turn | Before | Observed result | After |
|---|---|---|---|
| 1 | 4 remaining | Target 1 completed | 3 remaining |
| 2 | 3 remaining | Target 2 completed | 2 remaining |
| 3 | 2 remaining | Target 3 completed | 1 remaining |
| 4 | 1 remaining | Target 4 completed | 0 — stop |
The next condition check sees zero and does not start a fifth action. Position and completion may be related, but they are not interchangeable: arriving at a target does not prove the intended work happened there.
For a visible route with a different end condition, compare 16 visited cells reached by 15 moves.
Handle a failed move without losing the truth
Now suppose the second attempt fails. You still have three targets remaining, and the next intended target is still pending. Do not subtract one and do not advance a stored position unless movement actually occurred.
- Keep the last confirmed position and remaining-work count.
- Record which target or action failed.
- Leave the repeating path, or enter a deliberately bounded recovery attempt.
- Resume only when a changed condition can make the next attempt different.
Retrying the same failed move forever is not a recovery strategy. A retry limit prevents endless execution; it does not make the underlying path valid. At the limit, stop with enough state to diagnose the problem.
Three stopping mistakes to look for
- The condition never changes.
- A loop checks “remaining is above zero” but updates a different variable. Trace the value used by the condition, not the similarly named value you meant to update.
- A skip bypasses progress.
- A
continue-style branch can return to the condition before the update. Decide whether that branch completed work, changed the next target or needs to stop. - An inner exit is mistaken for a whole-program exit.
- Leaving an inner loop can let the outer loop start it again. Write down which loop owns the job’s completion state.
When the program repeats, reduce it to the smallest repeated sequence and inspect its condition, state update and failure branch. Follow the first incorrect state before changing the whole routine.