restore a game using chess.js

836 views Asked by At

I am running a project using chess.js and chessboard.js. Right now I want to store the history and FEN when the user quit the page, and restore the when the user is back. Restoring the FEN is easy, but I am not really sure about restoring the history. I am thinking to store the game.history() in the database and when the game is resumed, make newGame.history() = game.history(). Will this work? Will the new move history after the game is resumed be appended after the previous history? Thanks!

2

There are 2 answers

0
mazoula On BEST ANSWER

A bit late to answer but don't use history(). instead use pgn(). when you save the pgn of the game you save the fen (fen of last position) at the same time. pgn() gives you a string which you can save anywhere then to reload the game use load-pgn(mysavedgameinpgnformat). For instance on the client side which is the only place I have gotten this library to work:

var game = new Chess();
console.log(game.fen());
game.move("e4");
console.log(game.fen());
console.log(game.history());
var storegamepgn = game.pgn(); // a string which can be stored most anywhere
console.log(storegamepgn);
game = new Chess();
console.log(game.fen());
game.load_pgn(storegamepgn);
console.log(game.fen());
game.move("e5");
console.log(game.fen());
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.3/chess.min.js"></script>

0
Mr. Polywhirl On

I took mazoula's response and wrapped it with chessbard.js and use some async/await to demonstrate save/load.

const sleep = async (ms) => new Promise((res) => setTimeout(res, ms));
const run = async (fn) => { fn(); return sleep(1000); };

const board = Chessboard('board', {
  position: 'start',
  pieceTheme: 'https://chessboardjs.com/img/chesspieces/wikipedia/{piece}.png'
});

let game = new Chess(), pgn;

(async() => {
  await run(() => {
    console.log('>> START GAME');
    console.log(game.fen());
    board.position(game.fen(), true);
  });
  await run(() => {
    console.log('WHITE PAWN TO E4');
    game.move("e4");
    board.position(game.fen(), true);
    console.log(game.fen());
  });
  await run(() => {
    console.log('>> SAVE GAME');
    pgn = game.pgn();
    console.log(...game.history());
    console.log(game.fen());
    console.log(pgn);
  });
  await run(() => {
    console.log('>> NEW GAME');
    game = new Chess();
    board.position(game.fen(), true);
    console.log(game.fen());
  });
  await run(() => {
    console.log('>> LOAD GAME');
    game.load_pgn(pgn);
    console.log(game.fen());
    board.position(game.fen(), true);
  });
  await run(() => {
    console.log('BLACK PAWN TO E5');
    game.move("e5"); 
    board.position(game.fen(), true);
    console.log(game.fen());
  });
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.3/chess.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chessboard-js/1.0.0/chessboard-1.0.0.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/chessboard-js/1.0.0/chessboard-1.0.0.min.css" rel="stylesheet"/>
<div id="board" style="width: 180px"></div>

Random chess

Here is a chess game randomizer that will replay the game.

const sleep = async(ms) => new Promise((res) => setTimeout(res, ms));
const run = async(fn) => { fn(); return sleep(500); };

const board = Chessboard('board', {
  position: 'start',
  pieceTheme: symbol_piece_theme,
  boardTheme: symbol_board_theme /* not supported, use CSS instead */
});

const generateRandomPgn = () => {
  const chess = new Chess();
  while (!chess.game_over()) {
    const moves = chess.moves();
    chess.move(moves[Math.floor(Math.random() * moves.length)]);
  }
  return chess.pgn() + ' 1/2-1/2'; // Usually a stalemate
};

const replay = (pgn) => {
  const chess = new Chess();
  const moves = pgnParser.parse(pgn)[0].moves.map(({ move }) => move);
  let moveIndex = 0;
  (async() => {
    while (moveIndex < moves.length) {
      await run(() => {
        chess.move(moves[moveIndex++])
        board.position(chess.fen());
      });
    }
  })();
};

replay(generateRandomPgn());
[class^="square"].white-1e1d7 { background-color: #FFFFFF; color: #58AC8A; }
[class^="square"].black-3c85d { background-color: #58AC8A; color: #FFFFFF; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/chessboard-js/1.0.0/chessboard-1.0.0.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/kevinludwig/pgn-parser/dist/pgn-parser.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.3/chess.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chessboard-js/1.0.0/chessboard-1.0.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/jbkunst/chessboardjs-themes/chessboardjs-themes.js"></script>
<div id="board" style="width: 180px"></div>