{"id":22938132,"url":"https://github.com/sandy98/-sandy98-chess.js","last_synced_at":"2025-04-01T19:32:59.135Z","repository":{"id":48030086,"uuid":"149882652","full_name":"sandy98/-sandy98-chess.js","owner":"sandy98","description":"@sandy98/chess.js is a Javascript chess library that is used for chess move generation/validation, piece placement/movement, and check/checkmate/stalemate detection - basically everything but the AI. See demo at:","archived":false,"fork":false,"pushed_at":"2022-12-02T12:12:21.000Z","size":1019,"stargazers_count":1,"open_issues_count":11,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-07T12:39:56.016Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://sandy98.github.com/public/chess-board-test/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sandy98.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-22T14:07:06.000Z","updated_at":"2019-10-18T21:34:04.000Z","dependencies_parsed_at":"2023-01-22T22:16:08.881Z","dependency_job_id":null,"html_url":"https://github.com/sandy98/-sandy98-chess.js","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandy98%2F-sandy98-chess.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandy98%2F-sandy98-chess.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandy98%2F-sandy98-chess.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandy98%2F-sandy98-chess.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sandy98","download_url":"https://codeload.github.com/sandy98/-sandy98-chess.js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246700697,"owners_count":20819921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T12:16:09.858Z","updated_at":"2025-04-01T19:32:59.112Z","avatar_url":"https://github.com/sandy98.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @sandy98/chess.js\n\n## Warning: this project is deprecated since october 2019 in favor of the newer and more functional sandy98/chess-rules, so it's no longer mantained.\n\n@sandy98/chess.js is a Javascript chess library that is used for chess move\ngeneration/validation, piece placement/movement, and check/checkmate/stalemate\ndetection - basically everything but the AI.\n\nIt is inspired on [jhlywa](https://github.com/jhlywa)'s excelent chess.js, and follows its API to the detail wherever possible, so users with experience in it will find almost no difference in use. Motivation behind this development is to have a version which keeps an internal collection of positions, so user interfaces (like chessboard.js, or my own [@sandy98/chess-board](https://github.com/sandy98/chess-board) can show differents stages of a game without resorting to undos/redos of movements, which is expensive in terms of computation, and not elegant in terms of development. I had previously done a (now deprecated) fork of jhlywa's library which did exactly that, but eventually decided a complete rewrite to put modern tooling (typescript, parcel.js) to good use, and to have which I considered a clearer version in terms of both object orientation and functional techniques. The source code is quite self-explanatory.\n\n## Installation\n\nTo install the stable version:\n\n```sh\nnpm install --save @sandy98/chess.js\n```\n\n\n## Example Code\nThe code below plays a complete game of chess ... randomly.\n\n```js\nvar Chess = require('./chess').Chess;\nvar chess = new Chess();\n\nwhile (!chess.game_over()) {\n  var moves = chess.moves();\n  var move = moves[Math.floor(Math.random() * moves.length)];\n  chess.move(move);\n}\nconsole.log(chess.pgn());\n```\n\nNeed a user interface?  Try my very own\n[@sandy99/chess-board](http://github.com/sandy98/chess-board) library.\n\n## API (Doc currently under rewriting to stress minor differences between this @sandy98/chess.js and original chess.js)\n\n### Constructor: Chess([ fen ])\nThe Chess() constructor takes an optional parameter which specifies the board configuration\nin [Forsyth-Edwards Notation](http://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation).\n\n```js\n// board defaults to the starting position when called with no parameters\nvar chess = new Chess();\n\n// pass in a FEN string to load a particular position\nvar chess = new Chess('r1k4r/p2nb1p1/2b4p/1p1n1p2/2PP4/3Q1NB1/1P3PPP/R5K1 b - c3 0 19');\n```\n\n### .ascii()\nReturns a string containing an ASCII diagram of the current position.\n\n```js\nvar chess = new Chess();\n\n// make some moves\nchess.move('e4');\nchess.move('e5');\nchess.move('f4');\n\nchess.ascii();\n// -\u003e '   +------------------------+\n//      8 | r  n  b  q  k  b  n  r |\n//      7 | p  p  p  p  .  p  p  p |\n//      6 | .  .  .  .  .  .  .  . |\n//      5 | .  .  .  .  p  .  .  . |\n//      4 | .  .  .  .  P  P  .  . |\n//      3 | .  .  .  .  .  .  .  . |\n//      2 | P  P  P  P  .  .  P  P |\n//      1 | R  N  B  Q  K  B  N  R |\n//        +------------------------+\n//          a  b  c  d  e  f  g  h'\n```\n\n\n### .board()\nNot implemented in this version.\n\n### .clear()\nClears the board.\n\n```js\nchess.clear();\nchess.fen();\n// -\u003e '8/8/8/8/8/8/8/8 w - - 0 1' \u003c- empty board\n```\n\n### .fen()\nReturns the FEN string for the current position.\n\n```js\nvar chess = new Chess();\n\n// make some moves\nchess.move('e4');\nchess.move('e5');\nchess.move('f4');\n\nchess.fen();\n// -\u003e 'rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq f3 0 2'\n```\n\n### .game_over()\nReturns true if the game has ended via checkmate, stalemate, draw, threefold repetition, or insufficient material. Otherwise, returns false.\n\n```js\nvar chess = new Chess();\nchess.game_over();\n// -\u003e false\n\nchess.load('4k3/4P3/4K3/8/8/8/8/8 b - - 0 78');\nchess.game_over();\n// -\u003e true (stalemate)\n\nchess.load('rnb1kbnr/pppp1ppp/8/4p3/5PPq/8/PPPPP2P/RNBQKBNR w KQkq - 1 3');\nchess.game_over();\n// -\u003e true (checkmate)\n```\n\n### .get(square)\nReturns the piece on the square:\n\n```js\nchess.clear();\nchess.put({ type: chess.PAWN, color: chess.BLACK }, 'a5') // put a black pawn on a5\n\nchess.get('a5');\n// -\u003e { type: 'p', color: 'b' },\nchess.get('a6');\n// -\u003e null\n```\n\n### .history([ options ])\nReturns a list containing the moves of the current game.  Options is an optional\nparameter which may contain a 'verbose' flag.  See .moves() for a description of the\nverbose move fields.\n\n```js\nvar chess = new Chess();\nchess.move('e4');\nchess.move('e5');\nchess.move('f4');\nchess.move('exf4');\n\nchess.history();\n// -\u003e ['e4', 'e5', 'f4', 'exf4']\n\nchess.history({ verbose: true });\n// -\u003e [{ color: 'w', from: 'e2', to: 'e4', flags: 'b', piece: 'p', san: 'e4' },\n//     { color: 'b', from: 'e7', to: 'e5', flags: 'b', piece: 'p', san: 'e5' },\n//     { color: 'w', from: 'f2', to: 'f4', flags: 'b', piece: 'p', san: 'f4' },\n//     { color: 'b', from: 'e5', to: 'f4', flags: 'c', piece: 'p', captured: 'p', san: 'exf4' }]\n```\n\n### .in_check()\nReturns true or false if the side to move is in check.\n\n```js\nvar chess = new Chess('rnb1kbnr/pppp1ppp/8/4p3/5PPq/8/PPPPP2P/RNBQKBNR w KQkq - 1 3');\nchess.in_check();\n// -\u003e true\n```\n\n### .in_checkmate()\nReturns true or false if the side to move has been checkmated.\n\n```js\nvar chess = new Chess('rnb1kbnr/pppp1ppp/8/4p3/5PPq/8/PPPPP2P/RNBQKBNR w KQkq - 1 3');\nchess.in_checkmate();\n// -\u003e true\n```\n\n### .in_draw()\nReturns true or false if the game is drawn (50-move rule or insufficient material).\n\n```js\nvar chess = new Chess('4k3/4P3/4K3/8/8/8/8/8 b - - 0 78');\nchess.in_draw();\n// -\u003e true\n```\n\n### .in_stalemate()\nReturns true or false if the side to move has been stalemated.\n\n```js\nvar chess = new Chess('4k3/4P3/4K3/8/8/8/8/8 b - - 0 78');\nchess.in_stalemate();\n// -\u003e true\n```\n\n### .in_threefold_repetition()\nReturns true or false if the current board position has occurred three or more\ntimes.\n\n```js\nvar chess = new Chess('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1');\n// -\u003e true\n// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq occurs 1st time\nchess.in_threefold_repetition();\n// -\u003e false\n\nchess.move('Nf3'); chess.move('Nf6'); chess.move('Ng1'); chess.move('Ng8');\n// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq occurs 2nd time\nchess.in_threefold_repetition();\n// -\u003e false\n\nchess.move('Nf3'); chess.move('Nf6'); chess.move('Ng1'); chess.move('Ng8');\n// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq occurs 3rd time\nchess.in_threefold_repetition();\n// -\u003e true\n```\n\n### .header()\nAllows header information to be added to PGN output. Any number of key/value\npairs can be passed to .header().\n\n```js\nchess.header('White', 'Robert James Fischer');\nchess.header('Black', 'Mikhail Tal');\n\n// or\n\nchess.header('White', 'Morphy', 'Black', 'Anderssen', 'Date', '1858-??-??');\n```\n\nCalling .header() without any arguments returns the header information as an object.\n\n```js\nchess.header();\n// -\u003e { White: 'Morphy', Black: 'Anderssen', Date: '1858-??-??' }\n```\n\n### .insufficient_material()\nReturns true if the game is drawn due to insufficient material (K vs. K,\nK vs. KB, or K vs. KN); otherwise false.\n\n```js\nvar chess = new Chess('k7/8/n7/8/8/8/8/7K b - - 0 1');\nchess.insufficient_material()\n// -\u003e true\n```\n\n### .load(fen)\nThe board is cleared, and the FEN string is loaded.  Returns true if the position was\nsuccessfully loaded, otherwise false.\n\n```js\nvar chess = new Chess();\nchess.load('4r3/8/2p2PPk/1p6/pP2p1R1/P1B5/2P2K2/3r4 w - - 1 45');\n// -\u003e true\n\nchess.load('4r3/8/X12XPk/1p6/pP2p1R1/P1B5/2P2K2/3r4 w - - 1 45');\n// -\u003e false, bad piece X\n```\n\n### .load_pgn(pgn)\nLoad the moves of a game stored in\n[Portable Game Notation](http://en.wikipedia.org/wiki/Portable_Game_Notation).\n`pgn` should be a string. \nThe method will return `true` if the PGN was parsed successfully, otherwise `false`.\n\n```js\nvar chess = new Chess();\npgn = ['[Event \"Casual Game\"]',\n       '[Site \"Berlin GER\"]',\n       '[Date \"1852.??.??\"]',\n       '[EventDate \"?\"]',\n       '[Round \"?\"]',\n       '[Result \"1-0\"]',\n       '[White \"Adolf Anderssen\"]',\n       '[Black \"Jean Dufresne\"]',\n       '[ECO \"C52\"]',\n       '[WhiteElo \"?\"]',\n       '[BlackElo \"?\"]',\n       '[PlyCount \"47\"]',\n       '',\n       '1.e4 e5 2.Nf3 Nc6 3.Bc4 Bc5 4.b4 Bxb4 5.c3 Ba5 6.d4 exd4 7.O-O',\n       'd3 8.Qb3 Qf6 9.e5 Qg6 10.Re1 Nge7 11.Ba3 b5 12.Qxb5 Rb8 13.Qa4',\n       'Bb6 14.Nbd2 Bb7 15.Ne4 Qf5 16.Bxd3 Qh5 17.Nf6+ gxf6 18.exf6',\n       'Rg8 19.Rad1 Qxf3 20.Rxe7+ Nxe7 21.Qxd7+ Kxd7 22.Bf5+ Ke8',\n       '23.Bd7+ Kf8 24.Bxe7# 1-0'];\n\nchess.load_pgn(pgn.join('\\n'));\n// -\u003e true\n\nchess.fen();\n// -\u003e 1r3kr1/pbpBBp1p/1b3P2/8/8/2P2q2/P4PPP/3R2K1 b - - 0 24\n\nchess.ascii();\n// -\u003e '  +------------------------+\n//     8 | .  r  .  .  .  k  r  . |\n//     7 | p  b  p  B  B  p  .  p |\n//     6 | .  b  .  .  .  P  .  . |\n//     5 | .  .  .  .  .  .  .  . |\n//     4 | .  .  .  .  .  .  .  . |\n//     3 | .  .  P  .  .  q  .  . |\n//     2 | P  .  .  .  .  P  P  P |\n//     1 | .  .  .  R  .  .  K  . |\n//       +------------------------+\n//         a  b  c  d  e  f  g  h'\n\n\n### .move(move, [ options ])\nAttempts to make a move on the board, returning a move object if the move was\nlegal, otherwise null.  The .move function can be called two ways, by passing\na string in Standard Algebraic Notation (SAN):\n\n```js\nvar chess = new Chess();\n\nchess.move('e4')\n// -\u003e { color: 'w', from: 'e2', to: 'e4', flags: 'b', piece: 'p', san: 'e4' }\n\nchess.move('nf6') // SAN is case sensitive!!\n// -\u003e null\n\nchess.move('Nf6')\n// -\u003e { color: 'b', from: 'g8', to: 'f6', flags: 'n', piece: 'n', san: 'Nf6' }\n```\n\nOr by passing .move() a move object (only the 'to', 'from', and when necessary\n'promotion', fields are needed):\n\n```js\nvar chess = new Chess();\n\nchess.move({ from: 'g2', to: 'g3' });\n// -\u003e { color: 'w', from: 'g2', to: 'g3', flags: 'n', piece: 'p', san: 'g3' }\n```\n\nAn optional sloppy flag can be used to parse a variety of non-standard move\nnotations:\n\n```js\n\nvar chess = new Chess();\n\n// various forms of Long Algebraic Notation\nchess.move('e2e4', {sloppy: true});\n// -\u003e { color: 'w', from: 'e2', to: 'e4', flags: 'b', piece: 'p', san: 'e4' }\nchess.move('e7-e5', {sloppy: true});\n// -\u003e { color: 'b', from: 'e7', to: 'e5', flags: 'b', piece: 'p', san: 'e5' }\nchess.move('Pf2f4', {sloppy: true});\n// -\u003e { color: 'w', from: 'f2', to: 'f4', flags: 'b', piece: 'p', san: 'f4' }\nchess.move('Pe5xf4', {sloppy: true});\n// -\u003e { color: 'b', from: 'e5', to: 'f4', flags: 'c', piece: 'p', captured: 'p', san: 'exf4' }\n\n\n// correctly parses incorrectly disambiguated moves\nchess = new Chess('r2qkbnr/ppp2ppp/2n5/1B2pQ2/4P3/8/PPP2PPP/RNB1K2R b KQkq - 3 7');\n\nchess.move('Nge7');  // Ne7 is unambiguous because the knight on c6 is pinned\n// -\u003e null\n\nchess.move('Nge7', {sloppy: true});\n// -\u003e { color: 'b', from: 'g8', to: 'e7', flags: 'n', piece: 'n', san: 'Ne7' }\n```\n### .moves([ options ])\nReturns a list of legal moves from the current position.  The function takes an optional parameter which controls the single-square move generation and verbosity.\n\n```js\nvar chess = new Chess();\nchess.moves();\n// -\u003e ['a3', 'a4', 'b3', 'b4', 'c3', 'c4', 'd3', 'd4', 'e3', 'e4',\n//     'f3', 'f4', 'g3', 'g4', 'h3', 'h4', 'Na3', 'Nc3', 'Nf3', 'Nh3']\n\nchess.moves({square: 'e2'});\n// -\u003e ['e3', 'e4']\n\nchess.moves({square: 'e9'}); // invalid square\n// -\u003e []\n\nchess.moves({ verbose: true });\n// -\u003e [{ color: 'w', from: 'a2', to: 'a3',\n//       flags: 'n', piece: 'p', san 'a3'\n//       # a captured: key is included when the move is a capture\n//       # a promotion: key is included when the move is a promotion\n//     },\n//     ...\n//     ]\n```\n\nThe _piece_, _captured_, and _promotion_ fields contain the lowercase\nrepresentation of the applicable piece.\n\nThe _flags_ field in verbose mode may contain one or more of the following values:\n\n- 'n' - a non-capture\n- 'b' - a pawn push of two squares\n- 'e' - an en passant capture\n- 'c' - a standard capture\n- 'p' - a promotion\n- 'k' - kingside castling\n- 'q' - queenside castling\n\nA flag of 'pc' would mean that a pawn captured a piece on the 8th rank and promoted.\n\n### .pgn([ options ])\nReturns the game in PGN format. Options is an optional parameter which may include\nmax width and/or a newline character settings.\n\n```js\nvar chess = new Chess();\nchess.header('White', 'Plunky', 'Black', 'Plinkie');\nchess.move('e4');\nchess.move('e5');\nchess.move('Nc3');\nchess.move('Nc6');\n\nchess.pgn({ max_width: 5, newline_char: '\u003cbr /\u003e' });\n// -\u003e '[White \"Plunky\"]\u003cbr /\u003e[Black \"Plinkie\"]\u003cbr /\u003e\u003cbr /\u003e1. e4 e5\u003cbr /\u003e2. Nc3 Nc6'\n```\n\n### .put(piece, square)\nPlace a piece on the square where piece is an object with the form\n{ type: ..., color: ... }.  Returns true if the piece was successfully placed,\notherwise, the board remains unchanged and false is returned.  `put()` will fail\nwhen passed an invalid piece or square, or when two or more kings of the\nsame color are placed.\n\n```js\nchess.clear();\n\nchess.put({ type: chess.PAWN, color: chess.BLACK }, 'a5') // put a black pawn on a5\n// -\u003e true\nchess.put({ type: 'k', color: 'w' }, 'h1') // shorthand\n// -\u003e true\n\nchess.fen();\n// -\u003e '8/8/8/p7/8/8/8/7K w - - 0 0'\n\nchess.put({ type: 'z', color: 'w' }, 'a1') // invalid piece\n// -\u003e false\n\nchess.clear();\n\nchess.put({ type: 'k', color: 'w' }, 'a1')\n// -\u003e true\n\nchess.put({ type: 'k', color: 'w' }, 'h1') // fail - two kings\n// -\u003e false\n\n```\n\n### .remove(square)\nRemove and return the piece on _square_.\n\n```js\nchess.clear();\nchess.put({ type: chess.PAWN, color: chess.BLACK }, 'a5') // put a black pawn on a5\nchess.put({ type: chess.KING, color: chess.WHITE }, 'h1') // put a white king on h1\n\nchess.remove('a5');\n// -\u003e { type: 'p', color: 'b' },\nchess.remove('h1');\n// -\u003e { type: 'k', color: 'w' },\nchess.remove('e1');\n// -\u003e null\n```\n\n### .reset()\nReset the board to the initial starting position.\n\n### .square_color(square)\nReturns the color of the square ('light' or 'dark').\n\n```js\nvar chess = Chess();\nchess.square_color('h1')\n// -\u003e 'light'\nchess.square_color('a7')\n// -\u003e 'dark'\nchess.square_color('bogus square')\n// -\u003e null\n```\n\n### .turn()\nReturns the current side to move.\n\n```js\nchess.load('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1')\nchess.turn()\n// -\u003e 'b'\n```\n\n### .undo()\nTakeback the last half-move, returning a move object if successful, otherwise null.\n\n```js\nvar chess = new Chess();\n\nchess.fen();\n// -\u003e 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'\nchess.move('e4');\nchess.fen();\n// -\u003e 'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'\n\nchess.undo();\n// -\u003e { color: 'w', from: 'e2', to: 'e4', flags: 'b', piece: 'p', san: 'e4' }\nchess.fen();\n// -\u003e 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'\nchess.undo();\n// -\u003e null\n```\n\n### .validate_fen(fen):\nReturns a validation object specifying validity or the errors found within the\nFEN string.\n\n```js\nchess.validate_fen('2n1r3/p1k2pp1/B1p3b1/P7/5bP1/2N1B3/1P2KP2/2R5 b - - 4 25');\n// -\u003e { valid: true, error_number: 0, error: 'No errors.' }\n\nchess.validate_fen('4r3/8/X12XPk/1p6/pP2p1R1/P1B5/2P2K2/3r4 w - - 1 45');\n// -\u003e { valid: false, error_number: 9,\n//     error: '1st field (piece positions) is invalid [invalid piece].' }\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandy98%2F-sandy98-chess.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsandy98%2F-sandy98-chess.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandy98%2F-sandy98-chess.js/lists"}