webdevpuneet.com

Color Sort Water Puzzle with 20 Levels – HTML, CSS & JS

Color Sort Water Puzzle · Games · Plain HTML, CSS & JS · Live preview

CategoryGames

For supporters

Source Code

Want the source code?

Play the game for free. Become a WebDevPuneet supporter to unlock the complete HTML, CSS and JavaScript source code, the exports (HTML, React, Vue, Angular, Tailwind) and Fork.

Play freeSource code: Patreon

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), 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

20 levels in four tiers from 3 to 12 colours, defined as data, plus a Daily Puzzle with a streak
Boards generated by scrambling backwards from the solved state, so every level is solvable and has a known par
Seeded generator: level i is the same board for every player
Hidden layers from level 11: only the top unit of each tube is visible until it is exposed
Hint solver: greedy best-first search with a heap, a canonical state key and node and time caps
Free undo through snapshots, restart, and a locked state for finished tubes
Pour animation: the tube lifts and tilts, a stream of colour flows, new layers grow in, with bubble sounds from a Web Audio synth
Colour-blind friendly: optional symbols on every colour, focusable tubes with labels and full keyboard play
Stars from moves against par, unlocks, best moves and the streak saved to localStorage inside try/catch
Scales to its preview area (down to 40 percent) and stacks on phones, with confetti, a result screen and a copy result button

About this UI Snippet

Color Sort Water Puzzle — 20 Levels, Hidden Layers, a Hint Solver, Pour Animation and a Daily Puzzle

Screenshot of the Color Sort Water Puzzle snippet rendered live

Color Sort, also known as water sort, is a puzzle where coloured liquid is poured between glass tubes until every tube holds a single colour. The rule is simple: a tube holds four units, a pour needs an empty tube or a tube whose top colour matches, and the whole run of that colour moves at once if it fits. This version is a complete game with 20 levels in four tiers, hidden layers, a hint solver, free undo, a Daily Puzzle with a streak and a pour animation, in plain HTML, CSS and JavaScript with no libraries, images or audio files.

Boards that are always solvable, generated backwards

A random deal can produce a board nobody can finish. Instead scramble() starts from the solved board and plays moves backwards. Each step is the exact inverse of a legal pour: take k units from the top of one tube and put them on a tube whose top colour is different (or empty). Played forwards in reverse order, those steps solve the board, so a solution is guaranteed, and the number of steps is the par. Boards that are not mixed enough, or that start already sorted, are thrown away and the next seed is tried. A seeded random generator (mulberry32) means level i is the same board for every player.

Levels as data

The LEVELS array holds, for each level, the number of colours, the number of empty tubes, how many scramble steps to apply and whether layers are hidden. The four tiers (Splash, Stream, Torrent, Flood) grow from 3 colours to 12. From level 11, only the top unit of each tube is visible and the layers underneath show a question mark until they reach the top, so you have to plan with partial information. Adding a level means adding one row.

A hint solver, not a canned answer

The Hint button runs a greedy best-first search (solve()) from the current board, with a small heuristic: how many units sit on top of a different colour, and how many tubes start with the same colour. It uses a binary heap, a canonical key that ignores the order of the tubes, and caps on the number of nodes and the time. The first move of the solution found is highlighted: the source tube in amber and the target tube in green. A hint costs one star, and each level gives three.

Pouring you can see and hear

When you pour, the source tube lifts, tilts toward the target and a stream of the right colour flows down before the units change tubes. The new layers grow into place, and the sound is a run of short bubble tones whose length matches the number of units moved. A completed tube glows green and is locked. Pours that would only waste a move, such as emptying a single-colour tube into an empty tube, are refused with a short explanation.

Stars, undo and the daily puzzle

Moves are counted against the par. Three stars for par plus about 25 percent, two stars for about 70 percent more, and one star for any solution, minus one star if you used a hint. Undo is free and removes the move from the counter, because it restores a snapshot of the tubes and the hidden layers. Winning a level unlocks the next. The Daily Puzzle builds its board from the date, so everyone plays the same one, and clearing it on consecutive days builds a streak. Progress, best moves and the streak are saved to localStorage inside try/catch.

Accessible and responsive

Every colour can show a symbol (a circle, triangle, square and so on), so the game does not depend on telling colours apart. Tubes are focusable buttons with labels such as "Tube 3: colour 2, colour 5", and the keyboard works: arrow keys move focus, Enter or Space selects and pours, the number keys pick a tube, and Z, H and R undo, hint and restart. The whole game scales to short preview areas, and on phones the layout stacks and the page scrolls.

Step by step

How to Use

  1. 1
    Pick a level or the Daily PuzzleThe menu shows 20 levels in four tiers, with your stars on each. Level 1 is open at first and each solved level unlocks the next. The gold Daily Puzzle card starts the puzzle of the day, which is the same for everyone.
  2. 2
    Select a tube and pourTap a tube to lift it, then tap another tube to pour into it. You can pour onto an empty tube or onto a tube whose top colour matches, as long as there is room. The whole top run of that colour moves at once if it fits.
  3. 3
    Sort every colourYou win when every colour fills a single tube. A finished tube glows green and locks, and the progress bar above the board shows how many colours are done.
  4. 4
    Watch for hidden layersFrom level 11 only the top unit of each tube is visible. The layers below show a question mark and are revealed when they reach the top, so plan your pours with what you can see.
  5. 5
    Use undo and hintsUndo (Z) is free and takes the move back off the counter. Hint (H) shows a good next pour, highlighting the source in amber and the target in green. You get three hints per level and each one costs a star. Restart (R) starts the level again.
  6. 6
    Earn stars, turn on symbolsFinish within about 25 percent of the par for three stars. The Symbols button shows a different shape on every colour, which helps if colours are hard to tell apart. Your stars, best moves and daily streak are saved in this browser.

Real-world uses

Common Use Cases

Teaching puzzle generation by reversing the rules
Generating the board by scrambling backwards from the solved state is a neat trick that works for many puzzles: if every step is the inverse of a legal move, the puzzle is solvable by construction and the number of steps gives you a par.
A compact best-first search with a heap
solve() is a short, readable search with a heuristic, a priority queue, canonical state keys and resource caps. It is a good example of how to add a hint system to any state-based puzzle.
A relaxing game for a site or app
Water sort is calm and quick to learn. The daily puzzle and streak give visitors a reason to return, and progress is saved without an account.
Accessible colour-based games
The optional symbols, labelled focusable tubes and keyboard controls show how to make a game that depends on colour playable for everyone.
Animating state changes with CSS only
The tilt, stream and fill animations are plain CSS transitions and keyframes driven by a few class changes and inline transforms, with the logic state updated at the right moment.
Related: Lights Out Puzzle Game
See the Lights Out Puzzle Game for another puzzle that can be generated from a solved state.
Related: Cave Flyer Game
See the Cave Flyer Game for a related games pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The board is not dealt at random. scramble() starts from the solved board and applies inverse pours: it takes k units from the top of a tube and puts them on a tube whose top is a different colour or empty. Each of those steps, played forwards, is a legal pour, so playing the steps in reverse order solves the board. The number of steps is the par shown in the HUD.

It would only waste a move, because the colour is already sorted and nothing changes about the puzzle. legal() refuses it and the game shows a short message. Full single-colour tubes are also locked, since taking units out of a finished tube is never useful.

solve() runs a greedy best-first search from the current board. The heuristic counts units that sit on a different colour and tubes that start with the same colour, a binary heap picks the most promising state, and a canonical key ignores the order of the tubes so equal boards are not searched twice. The first move of the path it finds is shown. Because a hint does part of the thinking, the star rating drops by one when you use it.

From level 11 each unit has a revealed flag. At the start only the top unit of every tube is revealed, and a unit is revealed as soon as it becomes the top of its tube. Units you pour keep being visible, and a finished tube reveals everything. Undo restores the flags together with the tubes.

Add a row to the LEVELS array with the number of colours (up to 12), the number of empty tubes, the scramble depth and whether layers are hidden. More scramble steps mix the board more and raise the par. The menu shows five levels per tier, so add levels in groups of five, or edit the TIERS array. Colours and their symbols are in the COLORS array.

Yes. All localStorage reads and writes are wrapped in try/catch, so a blocked storage only means that progress is not saved. The AudioContext is created when a level starts and every sound call is wrapped. Tubes respond to pointer events, and on narrow screens the layout stacks and the page scrolls.