Skip to content

Commit

Permalink
Implement basic algebraic moves parsing
Browse files Browse the repository at this point in the history
Moves, captures, castlings
  • Loading branch information
everyonesdesign committed Jul 27, 2018
1 parent bc4a6ed commit 8c321e9
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 0 deletions.
51 changes: 51 additions & 0 deletions app/src/chess.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,61 @@ function makeMove(fromField, toField) {
}
}

/**
* Extract all possible information from algebraic notation
* @param {String} move
* @return {Boolean}
*/
function parseAlgebraic(move) {
// ignore from-to notation
if (/[a-h][1-8][a-h][1-8]/.test(move)) {
return;
}

const trimmedMove = move.replace(/( |-)+/g, '');

if (/[o0][o0][o0]/i.test(trimmedMove)) {
return {
piece: 'k',
moveType: 'long-castling',
};
} else if (/[o0][o0]/i.test(trimmedMove)) {
return {
piece: 'k',
moveType: 'short-castling',
};
}

const regex = /^([RQKNB])?([a-h])?([1-8])?(x)?([a-h])([1-8])(e\.?p\.?)?[+#]?$/;
const result = trimmedMove.match(regex);

if (!result) {
return null;
}

const [
_, // eslint-disable-line no-unused-vars
piece,
fromHor,
fromVer,
isCapture,
toHor,
toVer,
] = result;

return {
piece: (piece || 'p').toLowerCase(),
moveType: isCapture ? 'capture' : 'move',
from: `${fromHor || '.'}${fromVer || '.'}`,
to: `${toHor || '.'}${toVer || '.'}`,
};
}

module.exports = {
validateSquareName,
parseMoveText,
getBoard,
go,
makeMove,
parseAlgebraic,
};
124 changes: 124 additions & 0 deletions app/test/test-chess.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const assert = require('assert');

const {
getBoard,
parseAlgebraic,
} = require('../src/chess');

describe('getBoard', function() {
Expand Down Expand Up @@ -57,3 +58,126 @@ describe('getBoard', function() {
});
});

describe('parseAlgebraic', function() {
it('parses short algebraic moves', function() {
assert.deepEqual(parseAlgebraic('Rd2'), {
piece: 'r',
from: '..',
to: 'd2',
moveType: 'move',
});
});

it('parses pawn moves', function() {
assert.deepEqual(parseAlgebraic('d2'), {
piece: 'p',
from: '..',
to: 'd2',
moveType: 'move',
});
});

it('parses full moves', function() {
assert.deepEqual(parseAlgebraic('Re2d2'), {
piece: 'r',
from: 'e2',
to: 'd2',
moveType: 'move',
});
});

it('parses pawn captures', function() {
assert.deepEqual(parseAlgebraic('exd3'), {
piece: 'p',
from: 'e.',
to: 'd3',
moveType: 'capture',
});

// en passant
assert.deepEqual(parseAlgebraic('exd3e.p.'), {
piece: 'p',
from: 'e.',
to: 'd3',
moveType: 'capture',
});
});

it('parses piece captures', function() {
assert.deepEqual(parseAlgebraic('Rxd2'), {
piece: 'r',
from: '..',
to: 'd2',
moveType: 'capture',
});
});

it('parses full piece captures', function() {
assert.deepEqual(parseAlgebraic('Re2xd2'), {
piece: 'r',
from: 'e2',
to: 'd2',
moveType: 'capture',
});
});

it('parses partial disambiguation', function() {
assert.deepEqual(parseAlgebraic('R2xd2'), {
piece: 'r',
from: '.2',
to: 'd2',
moveType: 'capture',
});

assert.deepEqual(parseAlgebraic('Rexd2'), {
piece: 'r',
from: 'e.',
to: 'd2',
moveType: 'capture',
});
});

it('allows to mark a check', function() {
assert.deepEqual(parseAlgebraic('Rd2+'), {
piece: 'r',
from: '..',
to: 'd2',
moveType: 'move',
});
});

it('allows to mark a mate', function() {
assert.deepEqual(parseAlgebraic('Rd2#'), {
piece: 'r',
from: '..',
to: 'd2',
moveType: 'move',
});
});

it('parses castling', function() {
assert.deepEqual(parseAlgebraic('o-o'), {
piece: 'k',
moveType: 'short-castling',
});

assert.deepEqual(parseAlgebraic('0-0'), {
piece: 'k',
moveType: 'short-castling',
});

assert.deepEqual(parseAlgebraic('ooo'), {
piece: 'k',
moveType: 'long-castling',
});

assert.deepEqual(parseAlgebraic('0-0-0'), {
piece: 'k',
moveType: 'long-castling',
});
});

it('ignores not-existing pieces and squares', function() {
assert.strictEqual(parseAlgebraic('Xd2'), null);
});
});

0 comments on commit 8c321e9

Please sign in to comment.