Skip to content

Commit 0f25d22

Browse files
committed
Added isComplete, isCheck, isCheckmate, isDraw methods
1 parent ea27f93 commit 0f25d22

File tree

3 files changed

+66
-23
lines changed

3 files changed

+66
-23
lines changed

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "es6-chess",
33
"version": "1.0.0",
44
"description": "",
5-
"main": "index.js",
5+
"main": "dist/chess.bundle.js",
66
"scripts": {
77
"start": "npm run webpack",
88
"webpack": "webpack",

Diff for: src/chess.js

+58-20
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
CASTLE_QUEENSIDE,
66
CASTLE_KINGSIDE,
77
PAWN,
8-
BLACK
8+
BLACK,
9+
GAME_COMPLETE
910
} from './constants';
1011
import FenParser from './fen-parser';
1112
import Board from './board/board';
@@ -75,7 +76,13 @@ class Chess {
7576
return fenParser.stringify();
7677
}
7778

79+
/**
80+
* Gets an array of legal moves for current player
81+
* @param {String} piece - Filter moves by piece
82+
* @return {Array} moves - Array of moves
83+
*/
7884
moves(piece = null) {
85+
// If no piece, return all legal moves for current player
7986
if (piece === null) {
8087
return this.board.getAllLegalMoves(
8188
this.board.getBoard(),
@@ -85,6 +92,7 @@ class Chess {
8592
);
8693
}
8794

95+
// If piece color is not current player, return empty array
8896
if (getPieceColor(piece) !== this.activeColor) {
8997
return [];
9098
}
@@ -97,10 +105,15 @@ class Chess {
97105
);
98106
}
99107

108+
/**
109+
* Make a chess move
110+
* @param {String} piece - Piece to move
111+
* @param {String} to - Board position
112+
*/
100113
move(piece, to) {
101114
const color = getPieceColor(piece);
102115
if (color !== this.activeColor) {
103-
throw new Error(`Not ${color} turn`);
116+
throw new Error(`Wait for your turn`);
104117
}
105118

106119
const board = this.getBoard();
@@ -109,7 +122,7 @@ class Chess {
109122
.find(move => move.to === to);
110123

111124
if (!legalMove) {
112-
throw new Error('Move not legal');
125+
throw new Error(`You can't move ${piece} to ${to}`);
113126
}
114127

115128
// Move the piece
@@ -122,17 +135,18 @@ class Chess {
122135
this.deadPieces.push(legalMove.capturedPiece);
123136
}
124137

125-
// Move castling rook
138+
// Move the rook if castling
126139
if (legalMove.castle) {
127140
const castleRookY = color === WHITE ? 7 : 0;
128-
129141
if (legalMove.castle === CASTLE_QUEENSIDE) {
142+
// Queen side castling
130143
const castleRookX = 0;
131144
const castleRook = getBoardPieceAt(board, castleRookX, castleRookY);
132145
const newRookPosition = stringifyBoardPosition(castleRookX + 3, castleRookY);
133146
board[castleRookY][castleRookX] = null;
134147
board[castleRookY][castleRookX + 3] = updatePiecePosition(castleRook, newRookPosition);
135148
} else if (legalMove.castle === CASTLE_KINGSIDE) {
149+
// King side castling
136150
const castleRookX = 7;
137151
const castleRook = getBoardPieceAt(board, 7, castleRookY);
138152
const newRookPosition = stringifyBoardPosition(castleRookX - 2, castleRookY);
@@ -141,38 +155,62 @@ class Chess {
141155
}
142156
}
143157

144-
// En passant target (if a pawn does a 2 step move)
158+
// Set new en passant target (if a pawn does a 2 step move)
145159
if (legalMove.piece === PAWN && Math.abs(fromPos.y - toPos.y) === 2) {
146160
const enPassantTargetY = color === WHITE ? fromPos.y - 1 : fromPos.y + 1;
147161
this.enPassantTarget = stringifyBoardPosition(fromPos.x, enPassantTargetY);
148162
} else {
149163
this.enPassantTarget = null;
150164
}
151165

166+
// Update game state
152167
this.board = new Board(board);
153168
this.fullMoves += 1;
154169
this.halfMoves = Math.floor((this.fullMoves + 1) / 2);
155170
this.activeColor = color === WHITE ? BLACK : WHITE;
171+
this.status =
172+
this.board.getAllLegalMoves(board, this.enPassantTarget, this.castling).length !== 0
173+
? GAME_ONGOING
174+
: GAME_COMPLETE;
156175
}
157176

158-
isCheck() {}
177+
/**
178+
* Is game complete
179+
* @return {Boolean} isComplete
180+
*/
181+
isComplete() {
182+
return this.status === GAME_COMPLETE;
183+
}
159184

160-
isCheckmate() {}
185+
/**
186+
* Is check
187+
* @param {String} color - player color
188+
* @return {Boolean} isCheck
189+
*/
190+
isCheck(color = null) {
191+
const board = this.board.getBoard();
192+
return this.board.isCheck(color === null ? this.activeColor : color, board);
193+
}
161194

162-
isDone() {
163-
const board = this.getBoard();
164-
const legalMoves = this.board.getAllLegalMoves(
165-
board,
166-
this.activeColor,
167-
this.enPassantTarget,
168-
this.castling
169-
);
170-
if (legalMoves.length === 0) {
171-
return true;
172-
}
173-
return false;
195+
/**
196+
* Is checkmate
197+
* @return {Boolean} isCheckmate
198+
*/
199+
isCheckmate() {
200+
return this.isCheck() && this.moves().length === 0;
174201
}
175202

203+
/**
204+
* Is draw
205+
* @return {Boolean} isDraw
206+
*/
207+
isDraw() {
208+
return !this.isCheck() && this.moves().length === 0;
209+
}
210+
211+
/**
212+
* Get board matrix
213+
*/
176214
getBoard() {
177215
return this.board.getBoard();
178216
}

Diff for: src/chess.test.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Chess from './chess';
2+
import { WHITE } from './constants';
23

34
let chess;
45
beforeEach(() => {
@@ -17,7 +18,7 @@ describe('Chess class instance', () => {
1718
});
1819
it('should allow white to make only 1 move', () => {
1920
expect(() => chess.move('P@D2', 'D4')).not.toThrowError();
20-
expect(() => chess.move('P@E2', 'E3')).toThrowError('Not w turn');
21+
expect(() => chess.move('P@E2', 'E3')).toThrowError();
2122
});
2223
it('should record en passant target when 2 step pawn move', () => {
2324
chess.move('P@D2', 'D4');
@@ -81,7 +82,11 @@ describe('Chess class instance', () => {
8182
chess.move('Q@D1', 'F3');
8283
chess.move('n@B8', 'C6');
8384
chess.move('Q@F3', 'F7');
84-
expect(chess.isDone()).toBe(true);
85+
expect(chess.isComplete()).toBe(true);
86+
expect(chess.isCheck()).toBe(true);
87+
expect(chess.isCheckmate()).toBe(true);
88+
expect(chess.isCheck(WHITE)).toBe(false);
89+
expect(chess.isDraw()).toBe(false);
8590
});
8691
});
8792
});

0 commit comments

Comments
 (0)