Chess Engine BETA

Play

A chess engine that runs entirely in your browser. You play White; drag a piece to move. Nothing is sent anywhere, and the search runs on your own machine.

Even Your turn.
WhiteBlack

Captured

Nothing captured yet.

Settings

Search log

DepthSel.EvalNodesTimeSpeedBest line

Move history

No moves yet.

How it works

Everything happens in this page. There is no server, no call to an outside service and no database of games: when the engine plays a move, your own computer worked it out a moment ago, using only the code in this file.

The engine plays the way the first chess programs did, only faster. It has no intuition and no memory of famous games. Instead, it imagines moves, then the replies to those moves, then the replies to the replies, and gives a score to each position it reaches. It then plays the move that leads to the best position it can force, assuming you always answer well. That makes two jobs: searching, which decides which positions to look at, and evaluating, which decides how good each one is. Most of what follows is about doing each quickly enough to look far ahead in a second or two.

A board built for arithmetic

The board you drag pieces on is a picture. The engine keeps its own board, a plain list of numbers, one per square, where 0 means empty and other numbers stand for pieces. Its trick is to make that list twice as wide as the real board: every row has eight real squares followed by eight invisible ones. The arrangement, known as 0x88, means that when a piece's move runs off the edge, it lands on an invisible square, and a single quick check spots it. The engine therefore never has to ask "is this still on the board?" in several different ways, which matters when it asks the question millions of times a second.

♘︎ × the real board invisible squares off the board: one quick test catches it

Moves are made and taken back on this one board, rather than by copying it. For each move, the engine notes the few things it changes (what was captured, the castling rights, the en passant square), so that taking the move back simply restores them.

Looking ahead

From the starting position White has 20 possible moves. After Black's reply there are 400 possible positions, after three half-moves almost 9,000, after four nearly 200,000, and after six about 119 million. This fan of possibilities is called the game tree. The engine can't see all of it, so everything that follows is about looking deep where it matters and barely looking where it doesn't.

now 20 400 8,902 …

Assume the best reply

The core rule is simple. At the end of a line, the engine scores the position. Going back up the tree, it assumes that each side picks the move that is best for it: you pick your best, your opponent picks what is worst for you. This is called minimax. A move that wins a pawn but allows a mate is judged by the mate, because that is the reply a good opponent would find.

+3 +5 +3 +6 −2 −2 +4 +7 +4 +4: play the third move you reply

Stop as soon as a move is refuted

Minimax alone would have to look at every branch. Alpha-beta pruning avoids most of the work with one observation: once you have found a good move, another move doesn't need to be fully examined as soon as the opponent has one strong answer to it. In the drawing, the first move already guarantees +3. The second move's first reply leaves you at −2, so the second move can't beat the first, whatever its other replies do, and they are never looked at.

+3 +5 +3 −2 ? skipped −2 or less +4 +7 +4 +4: play the third move you reply

How much this saves depends on luck: it works best when the strongest moves are tried first. With perfect ordering, alpha-beta can look about twice as deep as plain minimax in the same time.

Trying the likeliest moves first

Much of the engine's strength comes from guessing which moves are good before searching them. It tries them in this order:

tried first 1 Best move from the previous pass 2 Captures that win material, biggest prize first 3 Killer moves: refutations that worked next door 4 Other quiet moves, ranked by past success 5 Captures that lose material tried last

The first comes from memory: the best move found on the previous, shallower pass. Captures come next, sorted by how much they win. Taking a queen with a pawn comes before taking a pawn with a queen, and each exchange is first counted out in advance: who can recapture on that square, and with what, until nobody gains from continuing. This count is called static exchange evaluation, and captures that simply lose material are sent to the back of the queue. Then come "killer" moves: quiet moves that refuted something at the same depth in a neighbouring line, and so often refute again. Finally, the remaining quiet moves are ranked by their track record in this game. In practice, when a move turns out to refute the position, it's the first one tried more than nine times out of ten; the stats line under the board reports this as "first-move cut-offs".

Deepening one step at a time, against the clock

The engine doesn't decide in advance how deep to look. It searches one half-move deep, then two, then three, and so on, each pass taking roughly twice as long as the last. That sounds wasteful but costs little, because each pass mostly re-reads what the previous one learned, and it is what makes the ordering above possible. It also means there is always a finished answer: when time runs out, the engine plays the best move from the last completed pass.

5 6 7 8: cut off soft limit hard limit passes 1 to 5 take a blink time → Pass 8 is stopped at the hard limit; the move from pass 7 is played.

The thinking time you choose is split in two. After the soft limit no new pass is started, since it would probably not finish. The hard limit stops a pass that is still running. If the best move keeps changing from one pass to the next, or the score suddenly drops, the engine takes this as a sign the position is tricky and allows itself more time, up to the hard limit.

Remembering positions

The same position can be reached by different move orders. Rather than work it out again each time, the engine keeps a large table of positions it has already scored: about a million entries, each holding the score, how deep it was searched and the best move found.

1. d4 … d5 2. Nf3 1. Nf3 … d5 2. d4 start same position: scored once

To look positions up quickly, each one gets a fingerprint. When the page loads, the engine draws a random number for every piece on every square, and a position's fingerprint combines the numbers of all the pieces on the board. When a piece moves, two numbers are swapped in or out, so the fingerprint updates in an instant instead of being recalculated. Everything is generated inside the page; nothing is downloaded. The table survives from one move to the next, so the engine starts each turn already knowing a lot about the positions it expects.

Searching with narrow windows

Once a first move has been searched fully, the engine mostly asks a cheaper question of the others: "is this move better than the one I have, yes or no?" A yes-or-no question can be answered with far less searching than an exact score, and only moves that answer yes get a second, full look. This is called principal variation search.

The same idea applies to each new pass as a whole. The engine expects the score to be close to the last pass's, so it first searches with a narrow range around it, called an aspiration window. If the true score falls outside, it widens the range and searches again.

−2 −1 0 +1 +2 last pass: +0.30 outside the window? widen it, search again score, in pawns

Shortcuts that look deeper where it matters

A few more techniques trade a small risk of missing something for a large gain in depth.

Passing a turn. If a position still looks good for the side to move even after doing nothing, letting the opponent move twice in a row, the engine concludes the position is strong and stops searching it early. This is null-move pruning. It is switched off when in check, and when only kings and pawns are left, because then being forced to move can genuinely hurt (zugzwang).

A shallower look at unpromising moves. Moves late in the order are rarely best, so they get a shallower search. If one surprises, it is searched again at full depth. These are late-move reductions.

best-looking moves least promising how deep each move is searched

Ignoring hopeless quiet moves. Close to the end of a line, a quiet move that could not bring the score back even with a generous margin is skipped. Captures, checks and escapes from check are never skipped this way.

Never stopping in the middle of a fight

Any search has to stop somewhere, and stopping at the wrong moment gives absurd results. If the last move looked at is "queen takes pawn", a program that stops there thinks it has won a pawn, without seeing that the pawn was defended and the queen will be lost. This is called the horizon effect.

depth limit stopping at the depth limit your move reply Queen takes pawn “a pawn up!” playing out the captures your move reply Queen takes pawn pawn takes queen queen lost

So at the end of every line the engine keeps going, but only with captures and queen promotions, until the position is quiet; only then does it score it. This quiescence search skips captures that the exchange count shows are losing, which keeps it short. Checks get the opposite treatment in the main search: a move that gives check makes the line one half-move longer, because checks are forcing and often lead somewhere.

Mates and draws

A checkmate is scored as a huge number, reduced a little for every half-move it takes to deliver, so the engine prefers the quickest mate and, when it is losing, the longest resistance. Draws are recognised inside the search too: a position repeated in the line being examined, fifty moves without a capture or pawn move, and material that can't mate (a lone king, or king with a single bishop or knight) all score zero. This lets the engine steer towards a draw when it is behind and avoid one when it is ahead.

Judging a position

At the end of each line the engine gives the position a score in centipawns, hundredths of a pawn, from White's point of view in the eval bar: +1.00 means White is a pawn better, or has an equivalent advantage. The score adds up a number of small judgements, each written by hand as a rule of thumb from chess practice.

Material. Each piece has a value, and the totals are compared.

♙︎ pawn 100 ♘︎ knight 320 ♗︎ bishop 330 ♖︎ rook 500 ♕︎ queen 950

Where each piece stands. A piece's value depends on its square, so each type of piece has a table giving a bonus or a penalty for every square. Knights are strong in the centre and poor on the rim; bishops like long diagonals; pawns gain value as they advance; the king wants shelter while the queens are on the board.

♞︎ centre: +0.20 corner: −0.50 A knight in the corner reaches 2 squares; in the centre, 8.

Pawn structure. Pawns can't move backwards, so their formation shapes the whole game. A passed pawn, with no enemy pawns in front of it or on the neighbouring files, earns a bonus that grows quickly as it advances, especially in the endgame. Doubled pawns (two on one file) and isolated pawns (no friendly pawn on either neighbouring file) are penalised, and pawns protected by another pawn get a small bonus. Pawn formations repeat constantly during a search, so the engine keeps these results in a separate table and works each formation out only once.

♙︎ ♙︎ ♙︎ ♙︎ ♙︎ ♙︎ ♟︎ ♟︎ ♟︎ ♟︎ passed: nothing can stop it doubled: two on one file isolated: no neighbours

King safety. While there is plenty of material on the board, the engine checks the pawns in front of each king. Pawns in place are good; a pawn that has moved forward is less good; an open file next to the king is a real weakness. It also counts the enemy pieces that attack the squares around the king. The penalty grows much faster than the count, because two or three pieces attacking together are far more dangerous than one, and it is halved if the attacker no longer has a queen.

♔︎ ♙︎ ♙︎ ♙︎ ♛︎ ♞︎ ♜︎ dashed: the king's zone f2, g2: shield pawns in place h3: shield pawn has advanced queen and knight bear on the zone: the penalty grows with every attacker

Activity. Each knight, bishop, rook and queen gets credit for the squares it can reach, not counting squares guarded by enemy pawns, where it would simply be lost. Pieces that bear on the four central squares earn a little extra. Rooks like open files, with no pawns on them, and half-open files, with only enemy pawns. The two bishops together are worth a bonus, since between them they cover both colours of square.

Development. In the opening, knights and bishops still on their starting squares cost a little, and so does a centre pawn blocked on its home square by its own piece. This nudges the engine to bring its pieces out and not to trap its own bishops.

From middlegame to endgame

Good advice changes as pieces come off the board. In the middlegame the king should hide; in the endgame it becomes a fighting piece that belongs in the centre. The engine therefore keeps two scores for every position, one with middlegame judgement and one with endgame judgement, and blends them according to how much material remains. There is no sudden switch, only a gradual shift.

middlegame view: −0.40 endgame view: +0.35 the blend all pieces on few pieces left Score for a king standing in the centre

In the endgame, the kings are also scored by how close they are to the passed pawns: close to your own, to escort it, and close to the enemy's, to stop it. When one side has only its king left, the engine rewards pushing that king towards the edge and bringing its own king closer, which is how the basic mates with queen or rook are delivered. Endings that can't be won, such as a single minor piece and no pawns, have their score scaled down, so the engine doesn't play for a win that isn't there.

♚︎ ♔︎ ♖︎ The lone king is pushed towards the edge and corner, while the other king walks up to help deliver mate.

Thinking without freezing the page

The search runs in a background thread, separate from the page you interact with, so you can scroll, open the search log and read while the engine thinks. The search log under the settings shows each pass as it finishes: how deep it went, how deep the longest line reached ("selective depth", usually well beyond the nominal depth because of captures and checks), the score, the number of positions examined, the speed, and the line of play it expects. A typical move examines several hundred thousand to a few million positions.

Opening book

For the first few moves the engine can follow a short, hand-written book of standard openings instead of searching. When the moves played so far match the start of a book line, it plays the next move of that line, choosing at random when several lines match. The book lives in this page; it is not a database. Switching it off makes the engine think from the very first move, which is slower and sometimes stranger, but every move is then its own.

House rules

Colours
You play White and move first. The engine plays Black.
Special moves
Castling and en passant are allowed. A pawn reaching the last rank always promotes to a queen.
Draws
Threefold repetition, the fifty-move rule, stalemate and insufficient material all end the game.
No undo
Once a move is released it is final. Start again with New game.
Waiting
The engine thinks in a background thread, so the page stays responsive, and it stops by itself when its thinking time is up.