From e28ea59095088cadc6bee17f613cad121928b1a5 Mon Sep 17 00:00:00 2001 From: Jesse McDonald Date: Sun, 5 Apr 2020 05:24:26 -0500 Subject: [PATCH] block castling out of check --- js/pacosako.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/js/pacosako.js b/js/pacosako.js index 1cf091f..cb70079 100644 --- a/js/pacosako.js +++ b/js/pacosako.js @@ -504,17 +504,29 @@ class Game { if (from === (side === DARK ? 'e8' : 'e1')) { const row = from[1]; + /* memoize isInCheck(); may not need it and don't want to look twice */ + /* with any other piece this would be recursive, but kings can't capture */ + let inCheck = () => { + const check = this.isInCheck(side); + inCheck = () => check; + return check; + }; + if (this._castling[side].king && board.isEmpty('f' + row) && board.isEmpty('g' + row)) { - yield 'g' + row; + if (!inCheck()) { + yield 'g' + row; + } } if (this._castling[side].queen && board.isEmpty('d' + row) && board.isEmpty('c' + row) && board.isEmpty('b' + row)) { - yield 'c' + row; + if (!inCheck()) { + yield 'c' + row; + } } } } else if (type === QUEEN) { @@ -609,12 +621,16 @@ class Game { /* start with the opponent's unpaired pieces, the ones that can capture */ let queue = []; for (const from of sim._board.findPieces(other, true, false)) { - if (sim.isLegalMove(other, from, king, true)) { - /* this piece can directly capture the king */ - return true; - } + /* this next condition is needed to avoid recursion through legalMoves() */ + /* kings can't capture anything anyway, so they can be skipped */ + if (sim._board.getPiece(other, from) !== KING) { + if (sim.isLegalMove(other, from, king, true)) { + /* this piece can directly capture the king */ + return true; + } - queue.push({ game: sim, from }); + queue.push({ game: sim, from }); + } } /* arbitrary limit, but a human player would probably miss a 7-move chain too */