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.
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.
What's included
Features
About this UI Snippet
Dots and Boxes: A Line-Based Grid, an Extra-Turn Rule and a CPU That Solves the Endgame

Dots and Boxes is a pencil-and-paper classic: two players take turns drawing one line between two neighbouring dots, and whoever draws the fourth side of a box claims it, marks it and goes again. This snippet is a complete version in plain HTML, CSS and JavaScript on an inline SVG board, with three board sizes (3×3, 4×4 and 5×5 boxes), a computer opponent on three levels, a two-player mode on one screen, undo, hints and a win record that is kept in the browser.
The game state is the lines, not the cells
Most grid games store a value for every cell. Here the lines between dots are what players take, so the state is one array of lines (horizontals numbered first, then verticals) plus a counter of how many sides each box has. buildGeometry() creates the line list and, for each box, its four lines (top, bottom, left, right); each line also remembers the one or two boxes it touches. Taking a line adds one to those boxes' counters, and a counter that reaches four means the box is closed and belongs to the player who took the last side. A line shared by two boxes can close both at once.
The extra-turn rule
Closing a box gives the same player another move, and the turn only passes after a move that closes nothing. That single rule creates the whole strategy of the game: drawing a box's third side hands the opponent a box and another turn. doMove() returns the list of boxes the move closed, and the turn switches only when that list is empty.
A computer player in three levels
Easy takes a box some of the time and otherwise plays a random line, so it makes mistakes you can punish. Medium always takes a box when one is available, otherwise plays a line that gives nothing away (no box reaches three sides), and when every line gives something away it picks the line that gives away the fewest boxes. Hard plays like Medium until 18 or fewer lines are left, then switches to an exact solver. The solver treats the remaining lines as the bits of a number, scores every position once with a memo table (my boxes minus yours, with the extra-turn rule), and picks the best line. Because it searches the real rules, it finds the "double-cross" sacrifice (leaving the opponent two boxes to keep control of the rest of a chain) without that strategy being coded in. On the 3×3 board that means Hard plays almost perfectly from about the middle of the game.
Built to feel good
The board is built once and moves only change classes, so lines draw themselves with a stroke animation, boxes pop in with the owner's letter, the last line played is thickened, and the hover colour matches whose turn it is. Each line has a wide invisible hit line on top of the thin visible one, so it is easy to tap on a phone, and every line is also reachable with the keyboard (Tab, then Enter or Space). Undo restores a saved copy of the state, and Hint asks the Hard solver for a good move and flashes it. Sound effects are made with the Web Audio API and can be muted.
Step by step
How to Use
- 1Choose how to playPick vs CPU or 2 players, a difficulty (Easy, Medium or Hard for the CPU) and a board size (3×3, 4×4 or 5×5 boxes). Changing a setting starts a new game.
- 2Draw a lineClick or tap the gap between two neighbouring dots. The line is drawn in your colour, and the last line played is highlighted so you can follow the game.
- 3Close a box and go againThe player who draws the fourth side of a box claims it, marks it with their letter and plays again. Avoid drawing a box’s third side, because that gives the opponent a free box.
- 4Use Undo and HintUndo takes back your last move (or the last move in 2-player mode). Hint flashes a strong line, picked by the Hard solver.
- 5Win the boardThe game ends when every box is claimed, and whoever has more boxes wins. Against the CPU your won, lost and drawn games are kept for each difficulty and size.
- 6Customise itThe sizes, the EXACT_MAX number (how late Hard starts solving exactly) and the colours are plain constants and CSS values, and the three CPU levels live in one function, chooseMove().
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
That is the real rule of Dots and Boxes. doMove() collects the boxes the move closed, and the turn only passes to the other player when that list is empty. It is also why drawing a box’s third side is a mistake: it lets the opponent close that box and keep playing.
Easy takes an available box 60% of the time and otherwise plays a random line. Medium always takes a box, otherwise plays a line that does not give a box its third side, and when it has to give something away it picks the line that gives away the fewest boxes. Hard plays like Medium until 18 or fewer lines are left and then solves the rest of the game exactly.
It looks at every way the remaining lines can be played, with the extra-turn rule, and scores each position as (my boxes minus your boxes). The remaining lines are the bits of a number, so each position is stored once in a typed-array memo table. This is why Hard finds the double-cross sacrifice, where it leaves you two boxes on purpose to keep control of the rest of a chain.
Yes. A line between two boxes adds a side to both, and if both reach four sides the move closes both. applyMove() returns every box it closed, and each one is scored and animated.
The size buttons set cfg.n, and buildGeometry(n) builds the lines and boxes for any n. To offer 6×6, add a button with data-v="6" and add 6 to the allowed sizes. Hard still solves exactly at 18 or fewer lines left, which is a fast search; with larger boards it plays like Medium for longer.
Each line is drawn twice: a thin visible line and a 22px-wide invisible hit line on top. The hit line takes the clicks, the Enter and Space keys and the focus ring, so a line is easy to tap and reachable with the keyboard.