add the ability to detect checkmate without taking the king
This commit is contained in:
parent
db5f56735b
commit
204d7acddc
|
|
@ -4,7 +4,8 @@ import {Iterator} from './iterator.js';
|
||||||
|
|
||||||
/* Game states */
|
/* Game states */
|
||||||
const PLAYING = 'playing';
|
const PLAYING = 'playing';
|
||||||
const ENDED = 'ended';
|
const RESIGNED = 'resigned';
|
||||||
|
const CHECKMATE = 'checkmate';
|
||||||
|
|
||||||
/* Sides */
|
/* Sides */
|
||||||
const LIGHT = 'light';
|
const LIGHT = 'light';
|
||||||
|
|
@ -393,7 +394,7 @@ function addHistory(game) {
|
||||||
result += '(' + move.promotion.toUpperCase() + ')';
|
result += '(' + move.promotion.toUpperCase() + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (move.took === KING) {
|
if (game.status === CHECKMATE) {
|
||||||
result += '#';
|
result += '#';
|
||||||
} else if (game.isInCheck()) {
|
} else if (game.isInCheck()) {
|
||||||
result += '+';
|
result += '+';
|
||||||
|
|
@ -936,7 +937,31 @@ class Game {
|
||||||
this._redo = [];
|
this._redo = [];
|
||||||
|
|
||||||
if (took === KING) {
|
if (took === KING) {
|
||||||
this._status = ENDED;
|
this._status = CHECKMATE;
|
||||||
|
} else if (this._history && this.isInCheck(this._player)) {
|
||||||
|
/*
|
||||||
|
* NOTE: Preemptive checkmate detection is not performed on
|
||||||
|
* simulated games (without history) to prevent recursion.
|
||||||
|
*/
|
||||||
|
|
||||||
|
let canEscape = false;
|
||||||
|
|
||||||
|
for (const tryFrom of this._board.findPieces(this._player, true)) {
|
||||||
|
for (const tryTo of this.legalMoves(this._player, tryFrom)) {
|
||||||
|
if (!this.isDeadEnd(tryFrom, tryTo)) {
|
||||||
|
canEscape = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canEscape) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canEscape) {
|
||||||
|
this._status = CHECKMATE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addHistory(this);
|
addHistory(this);
|
||||||
|
|
@ -960,7 +985,7 @@ class Game {
|
||||||
this._checkCache = {};
|
this._checkCache = {};
|
||||||
this._moves.push(move);
|
this._moves.push(move);
|
||||||
this._redo = [];
|
this._redo = [];
|
||||||
this._status = ENDED;
|
this._status = RESIGNED;
|
||||||
|
|
||||||
addHistory(this);
|
addHistory(this);
|
||||||
}
|
}
|
||||||
|
|
@ -974,11 +999,10 @@ class Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
get winner() {
|
get winner() {
|
||||||
const move = this.lastMove;
|
if (this._status === RESIGNED) {
|
||||||
if (move && move.resign) {
|
|
||||||
return otherSide(this.lastMove.side);
|
return otherSide(this.lastMove.side);
|
||||||
} else if (move && move.took === KING) {
|
} else if (this._status === CHECKMATE) {
|
||||||
return move.side;
|
return this.lastMove.side;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -1063,7 +1087,7 @@ export default {
|
||||||
Board, Game,
|
Board, Game,
|
||||||
|
|
||||||
/* Game States */
|
/* Game States */
|
||||||
PLAYING, ENDED,
|
PLAYING, RESIGNED, CHECKMATE,
|
||||||
|
|
||||||
/* Sides */
|
/* Sides */
|
||||||
LIGHT, DARK,
|
LIGHT, DARK,
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,9 @@ $(function (){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (winner) {
|
if (winner) {
|
||||||
if (lastMove && lastMove.resign) {
|
if (game.status === PS.CHECKMATE) {
|
||||||
|
msg += 'Checkmate! ';
|
||||||
|
} else if (lastMove && lastMove.resign) {
|
||||||
msg += (lastMove.side === PS.LIGHT ? 'Light' : 'Dark') + ' player resigned. ';
|
msg += (lastMove.side === PS.LIGHT ? 'Light' : 'Dark') + ' player resigned. ';
|
||||||
}
|
}
|
||||||
msg += (winner === PS.LIGHT ? 'Light' : 'Dark') + ' player won!';
|
msg += (winner === PS.LIGHT ? 'Light' : 'Dark') + ' player won!';
|
||||||
|
|
@ -486,7 +488,11 @@ $(function (){
|
||||||
const winner = currentGame.winner;
|
const winner = currentGame.winner;
|
||||||
const lastMove = currentGame.lastMove || {};
|
const lastMove = currentGame.lastMove || {};
|
||||||
const lastMeta = lastMove.meta || {};
|
const lastMeta = lastMove.meta || {};
|
||||||
const status = !winner ? null : (lastMove.took === PS.KING) ? 'mate' : 'ended';
|
const status =
|
||||||
|
(currentGame.status === PS.PLAYING) ? null :
|
||||||
|
(currentGame.status === PS.CHECKMATE) ? 'checkmate' :
|
||||||
|
(currentGame.status === PS.RESIGNED) ? 'resigned' :
|
||||||
|
'ended';
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
lightName,
|
lightName,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue