Binary Bit Flip Game — Free HTML CSS JS Snippet

Binary Bit Flip Game · Games · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Single-integer game state with bit toggling via XOR against a one-bit mask
Bit on/off state read with a bitwise AND rather than tracked separately, so display and state cannot drift
Live binary (toString(2) padded), decimal, and hex (toString(16) padded) readouts on every flip
Plain-arithmetic place-value line spelling out the sum that produces the current number
Place values computed from Math.pow(2, BITS - 1 - i), so changing the BITS constant rebuilds the board
Click and keyboard (1-8) input paths routed through one toggle function with delegated event handling
Win check embedded in the toggle, ending the round the moment the target is reached
Streak tracking with a best-streak record persisted to localStorage under a single named key, with guarded reads and writes for sandboxed frames

About this UI Snippet

Binary Bit Flip Game — XOR Toggling, Place-Value Sums & Live Binary, Decimal and Hex Readouts

Screenshot of the Binary Bit Flip Game snippet rendered live

Binary is one of those topics that stays abstract for as long as it is taught on paper and becomes obvious the moment you can flip a bit and watch a number change. This snippet is a small, genuinely playable number-building game: a random target between 1 and 255 appears, eight bit buttons sit below it labelled with their place values, and the player toggles bits until the running total equals the target. Every representation the player might meet in real code — the binary string, the decimal value, the hex byte, and the place-value sum — updates on every flip, so the relationship between them is visible rather than described.

Toggling a single bit with XOR

Flipping bit i is a single expression: value ^= placeValue(i). Exclusive-or with a mask that has exactly one set bit inverts that bit and leaves every other bit untouched, which is precisely what a toggle means at the bit level — and it is meaningfully better than the alternatives a beginner reaches for first. Tracking eight separate boolean variables and recomputing a sum keeps two sources of truth that can drift; adding or subtracting the place value works only if you first check the current state, which is the check XOR makes unnecessary. The whole game state is one integer between 0 and 255.

Deriving the display from the number, never the other way around

render() reads the single value integer and regenerates everything: each button's on/off class and its 0-or-1 digit come from (value & placeValue(i)) !== 0, the binary string from value.toString(2).padStart(8, '0'), the hex byte from value.toString(16) uppercased and padded, and the arithmetic line from collecting the place values of the set bits and joining them with plus signs. Because every visual element is derived from the same integer on every render, the display cannot disagree with the state — the same one-way data flow a framework enforces, done here in a dozen lines.

Place values as first-class UI

Each bit button shows its weight — 128, 64, 32, 16, 8, 4, 2, 1 — under the digit, computed as Math.pow(2, BITS - 1 - i) rather than hardcoded, so changing BITS to 4 or 16 rebuilds the whole board correctly. The running line beneath the readouts spells out the arithmetic in full ("64 + 32 + 8 = 104"), which is the step that converts pattern-matching into actual understanding: the player sees that a binary number is nothing more than a sum of the powers of two whose bits are set.

Keyboard and pointer paths through one function

Number keys 1 through 8 flip the corresponding bit from the left, and clicking a button does the same, because both paths call toggleBit(i) — a delegated click listener on the container resolves the index from a data-index attribute rather than binding eight separate handlers. Win detection lives inside that one function too: after every flip it compares value === target, so there is no separate check step and no way for the two input methods to behave differently.

Streaks that survive a refresh

Consecutive solves build a streak, and the best streak is written to localStorage under a single clearly named key, read back on load, and only rewritten when the record actually breaks. A short lock after a win prevents further flips from registering during the celebration delay before the next target appears, which is the small guard that stops a fast player from accidentally scoring the next round with a stale click.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet into an AI assistant like Claude and ask it to add a bitwise-operator mode where the player is shown two bytes and an operator (AND, OR, XOR, NOT, or a shift) and has to build the result — the natural next lesson once place value is understood. Other extensions worth asking for: a signed two's-complement mode that shows how -1 becomes 11111111, a timed challenge with a par number of flips per target so players learn to work from the largest place value down, a hex-target mode where the goal is given as 0x6C rather than 108, or an RGB mode where three of these byte builders drive a live colour swatch.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a playable binary bit-flipping game in plain HTML, CSS, and JavaScript — no frameworks or libraries.

Requirements:
- Keep the entire game state in ONE integer between 0 and 255. Flip a bit with XOR against a single-bit mask (value ^= 2 ** (BITS - 1 - i)) rather than tracking separate booleans or adding/subtracting with a conditional.
- Render eight bit buttons, each showing its current digit (0 or 1) and its place value (128 down to 1) computed from the BITS constant, not hardcoded — changing BITS must rebuild the board correctly.
- Read each bit's state for rendering with a bitwise AND against the same mask, so every displayed element is derived from the state integer and cannot drift from it.
- Show live readouts of the binary string (toString(2) zero-padded to BITS), the decimal value, and the hex byte (toString(16) uppercased and padded), plus a plain-arithmetic line listing the place values of the set bits joined with plus signs and equalling the total.
- Generate a random target between 1 and 255 each round, guaranteed different from the previous target, and detect the win inside the toggle function itself so the round ends the instant the value matches.
- Support both clicking a bit and pressing number keys 1-8, routed through the same toggle function, using event delegation with a data-index attribute rather than eight individual listeners.
- Track a streak of consecutive solves and persist the best streak to localStorage under one clearly named key, rewriting it only when the record actually breaks, and lock input briefly after a win so a fast click cannot leak into the next round.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Read the target numberA random value between 1 and 255 appears at the top of the card — that is the number you have to build out of place values. A new target is guaranteed to differ from the previous one, so no round repeats back to back.
  2. 2
    Flip bits by clicking or with the keyboardClick any of the eight bit buttons, or press keys 1 through 8 to flip bits from the left. Both routes call the same toggleBit() function, which XORs the bit's place value into the running number.
  3. 3
    Watch all four representations updateEvery flip re-renders the binary string, the decimal value, the hex byte, and a plain-arithmetic line showing the place values being added — for example "64 + 32 + 8 = 104".
  4. 4
    Match the target exactly to scoreThe win check runs inside the toggle itself, so the round ends the instant the running value equals the target. The target and decimal readout both turn green and the binary equation is echoed in the status line.
  5. 5
    Build a streakConsecutive correct rounds increase your streak, and the best streak persists in localStorage under the binary-bit-flip-best key so it survives a page reload.
  6. 6
    Use the place labels as a crib sheetEach button shows its weight (128, 64, 32, 16, 8, 4, 2, 1) computed from Math.pow(2, BITS - 1 - i). Working from the largest place value down is the standard technique for converting decimal to binary by hand.

Real-world uses

Common Use Cases

Teaching binary and place value in a CS fundamentals course
The arithmetic line turns the abstract "binary is base two" statement into a visible sum the student assembles themselves. It pairs naturally with a hash table visualizer when moving from number representation to how those numbers get used as indexes.
Explaining bitwise operators and flag masks in documentation
Permission flags, feature bitmasks and protocol headers all rely on the same AND-to-read, XOR-to-toggle pattern this game is built on. Embedding it beside a bitmask API reference gives readers a hands-on way to see why masking works before they read the field table.
Warm-up game on a developer education or interview-prep site
Rounds last a few seconds, so it works as a quick daily drill rather than a time sink, and the streak counter gives repeat visitors a reason to come back to the page.
Reference for derived-render state management without a framework
One integer as the entire state, with every DOM element regenerated from it on each change, is a compact demonstration of unidirectional data flow — useful as a teaching example before introducing a framework that formalises the same idea.
Toggle-grid UI pattern for settings and permission editors
The eight-button grid with active states, weights, and a live summary line transfers directly to permission matrices and feature-flag panels where users toggle options and need to see the combined result immediately.
Interactive explainer for colour, IP or Unicode byte values
Because the readouts already show hex alongside decimal and binary, the same component is a good starting point for explaining hex colour channels, IPv4 octets, or byte-level character encodings, where the value being built has a concrete real-world meaning.

Got questions?

Frequently Asked Questions

value ^= placeValue(i) inverts exactly the target bit and leaves the other seven untouched, which is what a toggle means at the bit level. Keeping eight separate booleans plus a derived total creates two sources of truth that can drift out of sync, and add/subtract approaches need a conditional to check the current state first — XOR needs none, and keeps the entire game state in one integer.

With a bitwise AND: (value & placeValue(i)) !== 0. The mask has exactly one set bit, so the AND is non-zero only when that bit is set in the current value. Every rendered element — the digit, the highlight class, the arithmetic line — is derived from the value integer this way, so nothing can display a state the number does not actually have.

Yes. The BITS constant drives the button count, each place value via Math.pow(2, BITS - 1 - i), the zero-padding of the binary string, and the keyboard range. For 16 bits you would also want to widen the hex padding beyond two characters and reduce the target range accordingly, and the eight-column CSS grid needs its column count updated to match.

In localStorage under the key binary-bit-flip-best, written only when the current streak exceeds the stored record. Clear it with localStorage.removeItem('binary-bit-flip-best') from the console, or change the BEST_KEY constant if you embed several instances and want them scored separately.

Yes, and it ports unusually cleanly because the state is a single integer. Hold value, target and streak in component state, derive the bit array, binary string, hex string and sum line during render rather than mutating the DOM, and dispatch toggles with a setValue(v => v ^ mask) style updater. Attach the document keydown listener in useEffect / onMounted / ngAfterViewInit and remove it on cleanup, and clear the post-win setTimeout on unmount so the next round cannot fire after the component is gone.