Using Chessboard.js to load in pgn and allow users to play through the game with arrow key presses

996 views Asked by At

I am trying to program a straightforward feature in which I retrieve a .pgn from a sqlite database and load in a chessboard from the chessboard.js which allows users to play through that game hitting the arrow keys (left to take back and right to go to the next move).

I was able to set up a board that allows only legal moves.

var board = null
var game = new Chess()
var $status = $('#status')
var $fen = $('#fen')
var $pgn = $('#pgn')

function onDragStart (source, piece, position, orientation) {
  // do not pick up pieces if the game is over
  if (game.game_over()) return false

  // only pick up pieces for the side to move
  if ((game.turn() === 'w' && piece.search(/^b/) !== -1) ||
      (game.turn() === 'b' && piece.search(/^w/) !== -1)) {
    return false
  }
}

function onDrop (source, target) {
  // see if the move is legal
  var move = game.move({
    from: source,
    to: target,
    promotion: 'q' // NOTE: always promote to a queen for example simplicity
  })

  // illegal move
  if (move === null) return 'snapback'

  updateStatus()
}

// update the board position after the piece snap
// for castling, en passant, pawn promotion
function onSnapEnd () {
  board.position(game.fen())
}

function takeBack () {
  board.position(game.undo())
}

function updateStatus () {
  var status = ''

  var moveColor = 'White'
  if (game.turn() === 'b') {
    moveColor = 'Black'
  }

  // checkmate?
  if (game.in_checkmate()) {
    status = 'Game over, ' + moveColor + ' is in checkmate.'
  }

  // draw?
  else if (game.in_draw()) {
    status = 'Game over, drawn position'
  }

  // game still on
  else {
    status = moveColor + ' to move'

    // check?
    if (game.in_check()) {
      status += ', ' + moveColor + ' is in check'
    }
  }

  $status.html(status)
  $fen.html(game.fen())
  $pgn.html(game.pgn())
}

var config = {
  draggable: true,
  position: 'start',
  onDragStart: onDragStart,
  onDrop: onDrop,
  onSnapEnd: onSnapEnd
}
board = Chessboard('legalBoard', config)



updateStatus()

Followed by the following html code.

<div id="legalBoard" style="width: 400px"></div>
<span>Status</span>
<div id="status"></div>
<span>PGN</span>
<div id="pgn"></div>
<span>FEN</span>
<div id="fen"></div>

Which creates the following chessboard that indeed allows users to pick up pieces and make legal moves:

legal board

How do I need to adapt this code to load in a game, and allow users to hit their arrow keys and play through that game?

1

There are 1 answers

1
Ray Hulha On
  1. Use @mliebelt/pgn-parser to parse the pgn
    1.1 import { parse } from '@mliebelt/pgn-parser'
    1.2 let moves = parse(my_pgn_string, {startRule: "game"}).moves;
  2. Loop over the moves
  3. Use the Chess object to convert the PGN notation to start and end moves:
    3.1 let move_obj = game.move(moves[i].notation.notation);
  4. Use Chessboard move to display move:
    4.1 chessboard.move(move_obj.from +'-'+ move_obj.to);