diff --git a/src/english/engine.test.ts b/src/english/engine.test.ts index e1cbbfa..3368659 100644 --- a/src/english/engine.test.ts +++ b/src/english/engine.test.ts @@ -5,7 +5,24 @@ import { EnglishDraughtsEngineFactory as EngineFactory, EnglishDraughtsEngine, } from './engine'; -import { S } from './utils'; +import { EnglishDraughtsBitSquare as S } from './utils'; + +/* We use the following bitboard layout for English Draughts + * + * 11 05 31 25 + * 10 04 30 24 + * 03 29 23 17 + * 02 28 22 16 + * 27 21 15 09 + * 26 20 14 08 + * 19 13 07 01 + * 18 12 06 00 + * + * Access the uint32 value of a square with S[n] + * + * A move forward to the left is a rotate left 7 bits. + * A move forward to the right is a rotate left 1 bit. + */ describe('possible openings', () => { let engine: EnglishDraughtsEngine; @@ -17,18 +34,50 @@ describe('possible openings', () => { test('correct dark moves', () => { assert.equal(engine.data.player, DraughtsPlayer.DARK); assert.sameDeepMembers(engine.moves, [ - { origin: S[3], destination: S[2], captures: 0 }, - { origin: S[3], destination: S[28], captures: 0 }, - { origin: S[29], destination: S[28], captures: 0 }, - { origin: S[29], destination: S[22], captures: 0 }, - { origin: S[23], destination: S[22], captures: 0 }, - { origin: S[23], destination: S[16], captures: 0 }, - { origin: S[17], destination: S[16], captures: 0 }, + { + origin: S[3], + destination: S[2], + captures: 0, + }, + { + origin: S[3], + destination: S[28], + captures: 0, + }, + { + origin: S[29], + destination: S[28], + captures: 0, + }, + { + origin: S[29], + destination: S[22], + captures: 0, + }, + { + origin: S[23], + destination: S[22], + captures: 0, + }, + { + origin: S[23], + destination: S[16], + captures: 0, + }, + { + origin: S[17], + destination: S[16], + captures: 0, + }, ]); }); test('correct board after move', () => { - engine.move({ origin: S[3], destination: S[2], captures: 0 }); + engine.move({ + origin: S[3], + destination: S[2], + captures: 0, + }); assert.equal(engine.data.player, DraughtsPlayer.LIGHT); assert.equal( engine.data.board.dark, @@ -49,16 +98,48 @@ describe('possible openings', () => { }); test('correct light moves', () => { - engine.move({ origin: S[3], destination: S[2], captures: 0 }); + engine.move({ + origin: S[3], + destination: S[2], + captures: 0, + }); assert.equal(engine.data.player, DraughtsPlayer.LIGHT); assert.sameDeepMembers(engine.moves, [ - { origin: S[26], destination: S[27], captures: 0 }, - { origin: S[20], destination: S[27], captures: 0 }, - { origin: S[20], destination: S[21], captures: 0 }, - { origin: S[14], destination: S[21], captures: 0 }, - { origin: S[14], destination: S[15], captures: 0 }, - { origin: S[8], destination: S[15], captures: 0 }, - { origin: S[8], destination: S[9], captures: 0 }, + { + origin: S[26], + destination: S[27], + captures: 0, + }, + { + origin: S[20], + destination: S[27], + captures: 0, + }, + { + origin: S[20], + destination: S[21], + captures: 0, + }, + { + origin: S[14], + destination: S[21], + captures: 0, + }, + { + origin: S[14], + destination: S[15], + captures: 0, + }, + { + origin: S[8], + destination: S[15], + captures: 0, + }, + { + origin: S[8], + destination: S[9], + captures: 0, + }, ]); }); }); @@ -68,19 +149,35 @@ describe('simple move', () => { beforeEach(() => { engine = EngineFactory.setup({ - board: { light: S[21] | S[0], dark: S[24], king: 0 }, + board: { + light: S[21] | S[0], + dark: S[24], + king: 0, + }, }); }); test('correct moves', () => { assert.sameDeepMembers(engine.moves, [ - { origin: S[24], destination: S[23], captures: 0 }, - { origin: S[24], destination: S[17], captures: 0 }, + { + origin: S[24], + destination: S[23], + captures: 0, + }, + { + origin: S[24], + destination: S[17], + captures: 0, + }, ]); }); test('correct board after move', () => { - engine.move({ origin: S[24], destination: S[23], captures: 0 }); + engine.move({ + origin: S[24], + destination: S[23], + captures: 0, + }); assert.equal(engine.data.board.light, S[21] | S[0]); assert.equal(engine.data.board.dark, S[23]); assert.equal(engine.data.board.king, 0); @@ -92,15 +189,27 @@ describe('tricky move', () => { beforeEach(() => { engine = EngineFactory.setup({ - board: { light: S[30], dark: S[21], king: 0 }, + board: { + light: S[30], + dark: S[21], + king: 0, + }, player: DraughtsPlayer.LIGHT, }); }); test('correct moves', () => { assert.sameDeepMembers(engine.moves, [ - { origin: S[30], destination: S[31], captures: 0 }, - { origin: S[30], destination: S[5], captures: 0 }, + { + origin: S[30], + destination: S[31], + captures: 0, + }, + { + origin: S[30], + destination: S[5], + captures: 0, + }, ]); }); }); @@ -110,13 +219,21 @@ describe('simple jump', () => { beforeEach(() => { engine = EngineFactory.setup({ - board: { light: S[21] | S[0], dark: S[22], king: 0 }, + board: { + light: S[21] | S[0], + dark: S[22], + king: 0, + }, }); }); test('correct moves', () => { assert.sameDeepMembers(engine.moves, [ - { origin: S[22], destination: S[20], captures: S[21] }, + { + origin: S[22], + destination: S[20], + captures: S[21], + }, ]); }); }); @@ -126,14 +243,22 @@ describe('jump and become king', () => { beforeEach(() => { engine = EngineFactory.setup({ - board: { light: S[17], dark: S[24] | S[14], king: 0 }, + board: { + light: S[17], + dark: S[24] | S[14], + king: 0, + }, player: DraughtsPlayer.LIGHT, }); }); test('correct moves', () => { assert.sameDeepMembers(engine.moves, [ - { origin: S[17], destination: S[31], captures: S[24] }, + { + origin: S[17], + destination: S[31], + captures: S[24], + }, ]); }); }); diff --git a/src/english/game.ts b/src/english/game.ts index 80c211d..0abe537 100644 --- a/src/english/game.ts +++ b/src/english/game.ts @@ -16,7 +16,7 @@ import { EnglishDraughtsEngineStore, } from './engine'; -import { S, decomposeBits } from './utils'; +import { EnglishDraughtsBitSquare as S, decomposeBits } from './utils'; const ENGLISH_DRAUGHTS_LAYOUT = [ S[11], diff --git a/src/english/index.ts b/src/english/index.ts index a61dc5d..2437a34 100644 --- a/src/english/index.ts +++ b/src/english/index.ts @@ -1,5 +1,5 @@ export { EnglishDraughts, type EnglishDraughtsGame } from './game'; -export { S } from './utils'; +export { EnglishDraughtsBitSquare } from './utils'; export { EnglishDraughtsComputerFactory, type EnglishDraughtsComputer, diff --git a/src/english/mask.ts b/src/english/mask.ts index 4a4046a..1fc11e2 100644 --- a/src/english/mask.ts +++ b/src/english/mask.ts @@ -1,4 +1,4 @@ -import { S } from './utils'; +import { EnglishDraughtsBitSquare as S } from './utils'; /* We use the following bitboard layout for English Draughts * @@ -11,7 +11,7 @@ import { S } from './utils'; * 19 13 07 01 * 18 12 06 00 * - * Access the value of a square with S[n] + * Access the uint32 value of a square with S[n] * * A move forward to the left is a rotate left 7 bits. * A move forward to the right is a rotate left 1 bit. diff --git a/src/english/utils.ts b/src/english/utils.ts index 7f64028..10e44d2 100644 --- a/src/english/utils.ts +++ b/src/english/utils.ts @@ -1,11 +1,11 @@ const BITS = 32; -const S: Record = []; -S[0] = 1; +const EnglishDraughtsBitSquare: Record = []; +EnglishDraughtsBitSquare[0] = 1; for (let index = 1; index < BITS; index++) { - S[index] = S[index - 1] * 2; + EnglishDraughtsBitSquare[index] = EnglishDraughtsBitSquare[index - 1] * 2; } -export { S }; +export { EnglishDraughtsBitSquare }; const BIT_MASK = 0xff_ff_ff_ff;