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 */
|
||||
const PLAYING = 'playing';
|
||||
const ENDED = 'ended';
|
||||
const RESIGNED = 'resigned';
|
||||
const CHECKMATE = 'checkmate';
|
||||
|
||||
/* Sides */
|
||||
const LIGHT = 'light';
|
||||
|
|
@ -393,7 +394,7 @@ function addHistory(game) {
|
|||
result += '(' + move.promotion.toUpperCase() + ')';
|
||||
}
|
||||
|
||||
if (move.took === KING) {
|
||||
if (game.status === CHECKMATE) {
|
||||
result += '#';
|
||||
} else if (game.isInCheck()) {
|
||||
result += '+';
|
||||
|
|
@ -936,7 +937,31 @@ class Game {
|
|||
this._redo = [];
|
||||
|
||||
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);
|
||||
|
|
@ -960,7 +985,7 @@ class Game {
|
|||
this._checkCache = {};
|
||||
this._moves.push(move);
|
||||
this._redo = [];
|
||||
this._status = ENDED;
|
||||
this._status = RESIGNED;
|
||||
|
||||
addHistory(this);
|
||||
}
|
||||
|
|
@ -974,11 +999,10 @@ class Game {
|
|||
}
|
||||
|
||||
get winner() {
|
||||
const move = this.lastMove;
|
||||
if (move && move.resign) {
|
||||
if (this._status === RESIGNED) {
|
||||
return otherSide(this.lastMove.side);
|
||||
} else if (move && move.took === KING) {
|
||||
return move.side;
|
||||
} else if (this._status === CHECKMATE) {
|
||||
return this.lastMove.side;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1063,7 +1087,7 @@ export default {
|
|||
Board, Game,
|
||||
|
||||
/* Game States */
|
||||
PLAYING, ENDED,
|
||||
PLAYING, RESIGNED, CHECKMATE,
|
||||
|
||||
/* Sides */
|
||||
LIGHT, DARK,
|
||||
|
|
|
|||
|
|
@ -369,7 +369,9 @@ $(function (){
|
|||
}
|
||||
|
||||
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 += (winner === PS.LIGHT ? 'Light' : 'Dark') + ' player won!';
|
||||
|
|
@ -486,7 +488,11 @@ $(function (){
|
|||
const winner = currentGame.winner;
|
||||
const lastMove = currentGame.lastMove || {};
|
||||
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 = {
|
||||
lightName,
|
||||
|
|
|
|||
Loading…
Reference in New Issue