Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Online Chess Game

Two-player chess that runs entirely in the browser. No server, no build step, no libraries — open index.html and play. All the rules are implemented: castling, en passant, promotion, check, checkmate and stalemate.

Running it

Download or clone the repo and open index.html in any browser.

git clone https://github.com/tsarumar/Online-Chess-Game.git
cd Online-Chess-Game

Then double-click index.html. That's it — there is nothing to install.

Click a piece to select it and the legal moves appear as dots. Click one to move, or drag the piece where you want it. Both work. New game resets, Flip board turns it around so black is at the bottom.

Screenshots

Starting position:

Starting board

A knight selected, with its legal moves marked. Captures show as a ring around the piece:

Legal moves

Checkmate. The king in check turns red and the move list records it as Qxf7#:

Checkmate

How the code is split

Each class has one job, and the layers only talk downward.

  • js/piece.js — a Piece base class and one subclass per piece type. Each one knows how it moves and nothing else. Pawn also overrides getAttacks() because a pawn moves forward but captures diagonally, and check detection has to know the difference.
  • js/board.jsBoard holds the 8x8 grid, applies moves to itself, and answers questions like "is this square attacked" and "is this king in check". It has no idea whose turn it is.
  • js/game.jsGame owns the rules. It filters the pieces' moves down to the genuinely legal ones, handles castling, tracks the history and captures, and works out check, checkmate and stalemate.
  • js/ui.jsChessUI draws the board and handles clicks and drag-and-drop. It never decides whether a move is allowed, it asks Game and renders the answer.
  • js/main.js — creates a Game, hands it to the UI.

How legal moves are worked out

In two passes, which is what keeps the piece classes simple.

First each piece generates its pseudo-legal moves — squares it could reach following its own movement pattern, ignoring the king entirely. A rook slides until something blocks it, a knight jumps to eight fixed offsets.

Then Game filters them. For every candidate it clones the board, plays the move on the copy, and asks whether the mover's own king is now attacked. If it is, the move is thrown away. That single check handles pins, moving into check, and being obliged to answer a check, without any of those cases needing their own code.

Checkmate falls out of the same machinery: if the side to move is in check and has zero legal moves, it is mate. If it is not in check and still has zero legal moves, it is stalemate.

The awkward rules

Three rules do not fit the "each piece knows its own moves" pattern, so they are handled specially.

Castling lives in Game, not King. It depends on whether squares are attacked, and asking that question from inside move generation would recurse forever — generating the king's moves would need to know if a square is attacked, which would need to generate the enemy's moves, which would need to check castling, and so on. Keeping it a level up breaks the loop.

En passant needs memory of the previous move, which a piece does not have. Board stores an enPassantTarget square when a pawn double-steps, and clears it after any other move, so the window is exactly one move wide as the rules require.

Promotion needs a decision from the player, so the move is generated with a default of queen and the UI opens a dialog to override it before the move is actually played.

Testing

The move generator was checked with perft — the standard method, where you count every possible sequence of moves to a given depth and compare against published values. Getting these exactly right is difficult unless castling, en passant, promotion and pinned pieces are all correct, so matching them is strong evidence the rules are right.

Position Depth Expected Result
Starting position 4 197,281 match
Kiwipete (castling and en passant heavy) 3 97,862 match
Pawn endgame 4 43,238 match

On top of that: Scholar's mate and Fool's mate both register as checkmate, a known stalemate position registers as stalemate, castling produces O-O and O-O-O and is correctly refused when the king would pass through an attacked square, en passant removes the right pawn, underpromotion to a knight works, and a pinned piece reports zero legal moves.

Notes

Pieces are Unicode characters styled with CSS rather than image files, so the repo has no assets and nothing to load. The board is generated by JavaScript into an empty <div> — the HTML contains no squares.

Flipping the board only changes where each square is drawn. The underlying grid never moves, which means none of the rules code has to know or care which way round the display is.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages