const V = VariantRules;
const [sizeX,sizeY] = VariantRules.size;
const shift = (color == "w" ? -1 : 1);
- const firstRank = (color == 'w' ? sizeY-1 : 0);
- const startRank = (color == "w" ? sizeY-2 : 1);
- const lastRank = (color == "w" ? 0 : sizeY-1);
+ const firstRank = (color == 'w' ? sizeX-1 : 0);
+ const startRank = (color == "w" ? sizeX-2 : 1);
+ const lastRank = (color == "w" ? 0 : sizeX-1);
if (x+shift >= 0 && x+shift < sizeX && x+shift != lastRank)
{
let step = finalSquares[castleSide][0] < y ? -1 : 1;
for (i=y; i!=finalSquares[castleSide][0]; i+=step)
{
- if (this.isAttacked([x,i], oppCol) || (this.board[x][i] != V.EMPTY &&
+ if (this.isAttacked([x,i], [oppCol]) || (this.board[x][i] != V.EMPTY &&
// NOTE: next check is enough, because of chessboard constraints
(this.getColor(x,i) != c || ![V.KING,V.ROOK].includes(this.getPiece(x,i)))))
{
const oppCol = this.getOppCol(color);
let potentialMoves = [];
const [sizeX,sizeY] = VariantRules.size;
- for (var i=0; i<sizeX; i++)
+ for (let i=0; i<sizeX; i++)
{
- for (var j=0; j<sizeY; j++)
+ for (let j=0; j<sizeY; j++)
{
// Next condition ... != oppCol is a little HACK to work with checkered variant
if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) != oppCol)
{
const color = this.turn;
this.play(move);
- let res = this.isAttacked(this.kingPos[color], this.getOppCol(color));
+ let res = this.isAttacked(this.kingPos[color], [this.getOppCol(color)]);
this.undo(move);
return res;
}
{
this.play(move);
const color = this.turn; //opponent
- let res = this.isAttacked(this.kingPos[color], this.getOppCol(color))
+ let res = this.isAttacked(this.kingPos[color], [this.getOppCol(color)])
? [ JSON.parse(JSON.stringify(this.kingPos[color])) ] //need to duplicate!
: [ ];
this.undo(move);
{
const color = this.turn;
// No valid move: stalemate or checkmate?
- if (!this.isAttacked(this.kingPos[color], this.getOppCol(color)))
+ if (!this.isAttacked(this.kingPos[color], [this.getOppCol(color)]))
return "1/2";
// OK, checkmate
return color == "w" ? "0-1" : "1-0";
}
// Assumption: at least one legal move
- getComputerMove(moves1) //moves1 might be precomputed (Magnetic chess)
+ // NOTE: works also for extinction chess because depth is 3...
+ getComputerMove()
{
this.shouldReturn = false;
const maxeval = VariantRules.INFINITY;
const color = this.turn;
- if (!moves1)
- moves1 = this.getAllValidMoves();
+ let moves1 = this.getAllValidMoves();
+
+ // Can I mate in 1 ? (for Magnetic & Extinction)
+ for (let i of _.shuffle(_.range(moves1.length)))
+ {
+ this.play(moves1[i]);
+ const finish = (Math.abs(this.evalPosition()) >= VariantRules.THRESHOLD_MATE);
+ this.undo(moves1[i]);
+ if (finish)
+ return moves1[i];
+ }
// Rank moves using a min-max at depth 2
for (let i=0; i<moves1.length; i++)
candidates.push(j);
let currentBest = moves1[_.sample(candidates, 1)];
- // Skip depth 3 if we found a checkmate (or if we are checkmated in 1...)
+ // Skip depth 3+ if we found a checkmate (or if we are checkmated in 1...)
if (VariantRules.SEARCH_DEPTH >= 3
&& Math.abs(moves1[0].eval) < VariantRules.THRESHOLD_MATE)
{
- // TODO: show current analyzed move for depth 3, allow stopping eval (return moves1[0])
for (let i=0; i<moves1.length; i++)
{
if (this.shouldReturn)
{
const [sizeX,sizeY] = VariantRules.size;
let evaluation = 0;
- //Just count material for now
+ // Just count material for now
for (let i=0; i<sizeX; i++)
{
for (let j=0; j<sizeY; j++)