webdevpuneet.com

Robot Loop Programmer Game — Free HTML CSS JS Snippet

Robot Loop Programmer Game · Games · Plain HTML, CSS & JS · Live preview

CategoryGames

Copy & paste

Source Code

<div class="demo-wrap">
  <div class="rb-game">
    <div class="rb-head">
      <div class="rb-meta"><span class="rb-label">Level</span><span class="rb-value" id="rbLevel">1 / 5</span></div>
      <div class="rb-meta rb-right"><span class="rb-label">Blocks / par</span><span class="rb-value"><span id="rbCount">0</span> / <span id="rbPar">4</span></span></div>
    </div>

    <p class="rb-goal" id="rbGoal">Drive the robot to the flag.</p>

    <div class="rb-board" id="rbBoard">
      <div class="rb-grid" id="rbGrid"></div>
      <div class="rb-robot" id="rbRobot">▲</div>
    </div>

    <div class="rb-palette">
      <button class="rb-cmd" data-cmd="F">Forward</button>
      <button class="rb-cmd" data-cmd="L">Turn ↺</button>
      <button class="rb-cmd" data-cmd="R">Turn ↻</button>
    </div>

    <div class="rb-program" id="rbProgram"></div>
    <p class="rb-tip">Click a block in your program to raise its repeat count. Right-click removes it.</p>

    <div class="rb-controls">
      <button class="rb-btn rb-run" id="rbRun">Run</button>
      <button class="rb-btn rb-ghost" id="rbClear">Clear</button>
    </div>

    <p class="rb-status" id="rbStatus">Build a program, then press Run.</p>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Block programs with per-block repeat counts, introducing loops without any syntax to learn
Par block count per level, creating real pressure to use counts instead of repeated blocks
Two-phase execution: blocks expanded into flat steps, then interpreted one step per interval tick
Each expanded step remembers its source block, so the running block highlights and the failing block is marked
Direction stored as an integer indexed into a delta table, with (dir + 3) % 4 avoiding JavaScript's negative-modulo trap
Distinct crash reasons for hitting a wall versus driving off the edge, each pointing to a different fix
MAX_STEPS ceiling rejecting runaway programs before execution starts
Levels authored as plain ASCII maps (. floor, # wall, S start, G goal) parsed at load time

About this UI Snippet

Robot Loop Programmer Game — Block Programs With Repeat Counts, Stepped Interpretation & Crash Reporting

Screenshot of the Robot Loop Programmer Game snippet rendered live

Sequencing, loops, and debugging are the first three ideas in programming, and all three are far easier to feel than to read about. This snippet is a small visual programming game built around exactly those ideas: the player assembles a program from Forward, Turn-left and Turn-right blocks, raises the repeat count on any block, presses Run, and watches a robot execute the program one step at a time across a grid of walls toward a flag. When the robot crashes, the block that was executing is highlighted — which is the whole debugging loop in miniature.

Repeat counts instead of a repeat block

Rather than a nested loop construct, each block carries a times count that the player raises by clicking it. F ×4 is a loop, expressed in the way beginners meet loops first: "do this thing four times". It also creates a genuine optimisation pressure, because every level shows a par block count — solving a spiral with eight separate Forward blocks works but misses par, while four blocks with counts clears it. That gap between "it works" and "it is concise" is the loop lesson, made visible without any syntax to learn.

Expansion, then interpretation

expand() flattens the block list into a list of single steps, each remembering the index of the block it came from. The interpreter then walks that flat list on a setInterval, applying one step per tick — which is what makes the execution watchable rather than instantaneous, and is also how a real stepping debugger works. Because each step retains its source block index, the UI can highlight the currently executing block and, on a crash, mark the exact block that failed. Separating expansion from execution keeps both halves simple: the interpreter never has to think about repeat counts, and the expander never has to think about walls.

Direction as modular arithmetic

Heading is stored as an integer 0-3 indexed into a DIRS table of row/column deltas. Turning right is (dir + 1) % 4 and turning left is (dir + 3) % 4 — adding three rather than subtracting one, which avoids the negative-modulo trap where (0 - 1) % 4 evaluates to -1 in JavaScript rather than 3. The robot's on-screen rotation comes from the same integer via rotate(dir * 90deg), so the sprite can never point somewhere the model disagrees with.

Failure that names the cause and the culprit

applyStep() returns a result object rather than a boolean: { ok: false, why: 'Hit a wall' } or 'Drove off the edge'. The runner stops the interval immediately on a failure, adds a crash class to the robot, marks the offending block red, and prints both the reason and the block number. Distinguishing the two failure modes matters pedagogically — driving off the edge means the program went too far, hitting a wall means it turned too late, and those are different fixes.

A step ceiling as a runaway guard

Because repeat counts can reach nine per block, a program can easily describe hundreds of steps. MAX_STEPS rejects any program whose expanded length exceeds the ceiling before execution begins, which is both a practical guard against a several-minute animation and an honest introduction to the idea that a loop needs a bound. Levels are plain ASCII maps — . floor, # wall, S start, G goal — parsed at load, so adding a level means drawing one, not writing coordinates.

Step by step

How to Use

  1. 1
    Read the level and find the flagThe purple-bordered line describes the challenge and the board shows walls in grey, the flag in purple, and the robot as an arrow pointing in its current heading — it always starts facing right.
  2. 2
    Add blocks from the paletteForward, Turn ↺ and Turn ↻ append a block to your program. The program strip below shows the sequence you have built and the block count against the level's par.
  3. 3
    Click a block to raise its repeat countClicking a block in the program cycles its count from 1 up to 9 and back around, so F ×4 replaces four separate Forward blocks. Right-clicking a block removes it.
  4. 4
    Press Run and watch it executeThe program is flattened into single steps and executed one every 300ms, with the currently running block highlighted — the same stepped execution a debugger gives you, which is what makes a mistake visible rather than mysterious.
  5. 5
    Read the crash reportIf the robot hits a wall or drives off the edge, execution stops immediately, the robot turns red, and the block that was executing is marked — along with whether the cause was a wall or the edge, which point to different fixes.
  6. 6
    Beat par to advance wellReaching the flag clears the level and reports your block count against par. Levels four and five are built so that solving at par genuinely requires repeat counts rather than repetition.

Real-world uses

Common Use Cases

Teaching sequencing, loops and debugging to beginners
Block programming with a visible execution pointer is the standard first-programming format for a reason — the program, the state and the failure are all on screen at once. Follow it with a stack and queue visualizer when moving from control flow to data structures.
Kids' coding club, STEM outreach or museum kiosk
The game needs no typing, no account and no build step, which makes it well suited to a shared screen or an event laptop where visitors play for a minute and move on.
Reference implementation of a tiny interpreter
Expansion, a step list, an execution pointer, per-step result objects and a step ceiling are the bones of every interpreter. Studying this one is a gentle route into how program execution is modelled before tackling parsers or bytecode.
Stepped-execution UI pattern for workflow and automation tools
Automation builders, CI pipeline views and rule engines all need to show a sequence executing with the current step highlighted and the failing step marked. This snippet is a compact model of that interaction, independent of the domain.
Grid-and-sprite movement without a game engine
Positioning the robot with percentage offsets over a CSS grid, animating with transitions on left/top, and rotating from the same integer that drives the model is a dependency-free approach that works for any turn-based grid movement UI.
Onboarding puzzle for developer-tool products
Products that involve composing steps — data pipelines, macro recorders, robotic process automation — can use a level or two of this as a playful introduction to their own composition model before the real editor appears.
Related: Tank Arena Game
See the Tank Arena Game for a related games pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

A count on a block is how beginners first meet iteration — "do this four times" — and it needs no nesting UI, no drag targets, and no block-scope rules. It still creates the real lesson: every level has a par block count, and the later levels only reach par if you use counts instead of repeating blocks, which is exactly the trade a loop exists to make.

expand() flattens the blocks into a flat list of single steps, and each step stores the index of the block it came from. The interpreter walks that list one step per tick, so when applyStep() returns a failure the runner already knows which block produced the failing step and can mark it red while reporting the reason.

Because JavaScript's % operator returns a negative result for negative operands: (0 - 1) % 4 is -1, not 3, which would index outside the direction table. Adding 3 is congruent to subtracting 1 modulo 4 and always stays non-negative, so the heading integer remains a valid index without any extra branching.

Push an object onto LEVELS with a goal string, a par block count, and a map: an array of equal-length strings where . is floor, # is a wall, S is the start and G is the flag. parseMap() reads the start and goal positions out of the characters at load time, so no coordinates need to be written by hand and the grid size is derived from the map length.

Yes. Keep LEVELS, DIRS, expand() and applyStep() in a plain module — they are all pure data and pure functions. Hold the program array, robot position and running flag in component state, and render the grid, program strip and robot position from that state. The one thing to get right is the interval: start it in an effect when running turns true and clear it in the cleanup (useEffect return, onUnmounted, ngOnDestroy) so a level change or unmount cannot leave the interpreter ticking.