Skip to content

Commit

Permalink
add makeMove() method
Browse files Browse the repository at this point in the history
  • Loading branch information
Luca Hendrik Helms committed Oct 24, 2022
1 parent 3b128bc commit 8215b15
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = {
'func-style': [2, 'declaration'],
'no-duplicate-imports': 'error',
'no-debugger': 'error',
'no-console': 1,
'no-console': ['error', { allow: ['warn', 'error'] }],
'prettier/prettier': [
'warn',
{
Expand Down
25 changes: 20 additions & 5 deletions src/classes/BoardApi.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { read } from 'chessground/fen';
import { possibleMoves, shortToLongColor, getThreats } from '@/helper/Board';
import type { ChessInstance } from 'chess.js';
import type { ChessInstance, Square } from 'chess.js';
import type { Api } from 'chessground/api';
import type { BoardState } from '@/typings/BoardState';
import type { LichessOpening } from '@/typings/BoardAPI';
import type { LichessOpening, BoardAPI } from '@/typings/BoardAPI';

/**
* class for modifying and reading data from the board, \
* extends the lichess chessground api & chess.js api \
* lichess documentation: https://github.com/lichess-org/chessground/blob/master/src/api.ts \
* chess.js documentation: https://github.com/jhlywa/chess.js/blob/master/README.md
*/
export class BoardApi {
export class BoardApi implements BoardAPI {
constructor(
public game: ChessInstance,
public board: Api,
Expand Down Expand Up @@ -136,7 +136,7 @@ export class BoardApi {
const data: LichessOpening = await res.json();

return data.opening?.name ?? null;
} catch (_) {
} catch {
return null;
}
}
Expand Down Expand Up @@ -164,10 +164,25 @@ export class BoardApi {
return data.query.pages[0].extract;
}
return null;
} catch (_) {
} catch {
return null;
}
}

makeMove(from: Square, to: Square) {
const move = this.game.move({ from, to });
if (move == null) return;
this.board.move(from, to);
this.board.state.movable.dests = possibleMoves(this.game);
this.board.state.turnColor = shortToLongColor(this.game.turn());
this.board.state.movable.color = this.board.state.turnColor;
this.board.state.lastMove = [from, to];

if (this.boardState.showThreats) {
// redraw threats in new position if enabled
this.board.setShapes(getThreats(this.game.moves({ verbose: true })));
}
}
}

export default BoardApi;
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ import '@/assets/board.css';
export { default as TheChessboard } from './components/TheChessboard.vue';
export { default as ChessboardAPI } from './classes/BoardApi';
export type { default as BoardConfig } from './typings/BoardConfig';
export type { BoardAPI } from './typings/BoardAPI';
26 changes: 26 additions & 0 deletions src/tests/BoardAPI.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import { mountComponent } from './helper/Helper';
import { initialPos, initialPosChessJS } from '@/helper/DefaultConfig';
import type { BoardApi } from '@/classes/BoardApi';
import { read } from 'chessground/fen';
import { randomMoveFirstMove } from '@/tests/helper/Functions';

describe.concurrent('Test the board API', () => {
const wrapper = mountComponent();

const event = wrapper.emitted<BoardApi[]>('boardCreated');
const boardApi = event?.[0][0];

if (typeof boardApi === 'undefined') {
throw new Error('boardApi is undefined');
}

// get current state
const initialBoardConf = boardApi?.boardState.boardConfig;

Expand Down Expand Up @@ -66,6 +71,27 @@ describe.concurrent('Test the board API', () => {
boardApi?.board.state.turnColor
);
});

it('makes a move', () => {
boardApi.resetBoard();
randomMoveFirstMove(boardApi);

expect(boardApi?.game.history().length).toBe(1);
expect(boardApi?.game.validate_fen(boardApi?.game.fen()).valid).toBe(true);
expect(boardApi?.game.in_check()).toBe(false);
expect(boardApi?.game.in_checkmate()).toBe(false);
expect(boardApi?.game.in_draw()).toBe(false);
expect(boardApi?.game.in_stalemate()).toBe(false);
expect(boardApi?.game.in_threefold_repetition()).toBe(false);
expect(boardApi?.game.insufficient_material()).toBe(false);
expect(boardApi?.game.game_over()).toBe(false);
expect(boardApi.board.state.turnColor).not.toBe(
boardApi.boardState.boardConfig.turnColor
);
expect(boardApi.board.state.movable.color).not.toBe(
boardApi.boardState.boardConfig.turnColor
);
});
});

export {};
14 changes: 14 additions & 0 deletions src/tests/helper/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Move } from 'chess.js';
import type { SquareKey } from '@/typings/Chessboard';

export const moves: Move[] = [
{
Expand Down Expand Up @@ -437,3 +438,16 @@ export const possibleFirstThreatsWhite = [
{ orig: 'f3', brush: 'yellow' },
{ orig: 'h3', brush: 'yellow' },
];

export const moveableSquaresWhite: SquareKey[] = [
'b1',
'g1',
'a2',
'b2',
'c2',
'd2',
'e2',
'f2',
'g2',
'h2',
];
19 changes: 19 additions & 0 deletions src/tests/helper/Functions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { possibleMoves } from '@/helper/Board';
import { moveableSquaresWhite } from './Constants';
import type { BoardAPI } from '@/typings/BoardAPI';
import type { SquareKey } from '@/typings/Chessboard';

export function randomMoveFirstMove(boardApi: BoardAPI) {
const moves = possibleMoves(boardApi.game);
const randomSquare =
moveableSquaresWhite[
Math.floor(Math.random() * moveableSquaresWhite.length)
];
const random = Math.floor(Math.random() * 2);
const move = moves.get(randomSquare)?.[random] as SquareKey;
if (!move) {
console.warn('Random move is undefined');
return;
}
boardApi?.makeMove(randomSquare, move);
}
25 changes: 25 additions & 0 deletions src/typings/BoardAPI.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
import type { ChessInstance, Square } from 'chess.js';
import type { Api } from 'chessground/api';
import type { BoardState } from './BoardState';

export interface BoardAPI {
game: ChessInstance;
board: Api;
boardState: BoardState;

resetBoard: () => void;
undoLastMove: () => void;
getMaterialCount: () => {
materialWhite: number;
materialBlack: number;
materialDiff: number;
};
showThreats: () => void;
toggleThreats: () => void;
getOpeningName: () => Promise<string | null>;
getOpeningDescription: (
maxDescriptionLength: number
) => Promise<string | null>;
makeMove: (from: Square, to: Square) => void;
}

export interface LichessOpening {
white: number;
black: number;
Expand Down

0 comments on commit 8215b15

Please sign in to comment.