}
static get CanAnalyze() {
- return true; //false;
+ return false;
}
static get ShowMoves() {
// 4) Check whiteMove
if (
(
- fenParsed.turn == "w" &&
+ fenParsed.turn == "b" &&
// NOTE: do not check really JSON stringified move...
(!fenParsed.whiteMove || fenParsed.whiteMove == "-")
)
||
- (fenParsed.turn == "b" && fenParsed.whiteMove != "-")
+ (fenParsed.turn == "w" && fenParsed.whiteMove != "-")
) {
return false;
}
start: this.whiteMove.start,
end: this.whiteMove.end,
appear: this.whiteMove.appear,
- vanish: this.whiteMove.vanish
+ vanish: this.whiteMove.vanish,
+ illegal: this.whiteMove.illegal
});
}
return (
(
m.vanish[0].p == V.KNIGHT &&
- (m.vanish.length == 1 || m.vanish[1].c != m.vanish[0].c)
- )
- ||
- (
- // Promotion attempt
- m.end.x == (m.vanish[0].c == "w" ? 0 : V.size.x - 1) &&
- other.vanish.length == 2 &&
- other.vanish[1].p == V.KNIGHT &&
- other.vanish[1].c == m.vanish[0].c
- )
- ||
- (
- // Moving attempt
- !movingLikeCapture(m) &&
- other.start.x == m.end.x &&
- other.start.y == m.end.y
+ (
+ m.vanish.length == 1 ||
+ m.vanish[1].c != m.vanish[0].c ||
+ // Self-capture attempt
+ (
+ !other.illegal &&
+ other.end.x == m.end.x &&
+ other.end.y == m.end.y
+ )
+ )
)
||
(
- // Capture attempt
- movingLikeCapture(m) &&
- other.end.x == m.end.x &&
- other.end.y == m.end.y
+ m.vanish[0].p == V.PAWN &&
+ !other.illegal &&
+ (
+ (
+ // Promotion attempt
+ m.end.x == (m.vanish[0].c == "w" ? 0 : V.size.x - 1) &&
+ other.vanish.length == 2 &&
+ other.vanish[1].p == V.KNIGHT &&
+ other.vanish[1].c == m.vanish[0].c
+ )
+ ||
+ (
+ // Moving attempt
+ !movingLikeCapture(m) &&
+ other.start.x == m.end.x &&
+ other.start.y == m.end.y
+ )
+ ||
+ (
+ // Capture attempt
+ movingLikeCapture(m) &&
+ other.end.x == m.end.x &&
+ other.end.y == m.end.y
+ )
+ )
)
);
};
vanish: []
};
if (!m1 && !m2) return smove;
- // Both move are now legal:
+ // Both moves are now legal or at least possible:
smove.vanish.push(m1.vanish[0]);
smove.vanish.push(m2.vanish[0]);
if ((m1.end.x != m2.end.x) || (m1.end.y != m2.end.y)) {
}
play(move) {
- if (!this.states) this.states = [];
- const stateFen = this.getFen();
- this.states.push(stateFen);
-
// Do not play on board (would reveal the move...)
move.flags = JSON.stringify(this.aggregateFlags());
this.turn = V.GetOppCol(this.turn);
this.turn = V.GetOppCol(this.turn);
this.movesCount--;
this.postUndo(move);
-
- const stateFen = this.getFen();
- if (stateFen != this.states[this.states.length-1]) debugger;
- this.states.pop();
}
postUndo(move) {
// TODO: this situation should not happen
return null;
- if (Math.random() < 0.5)
- // Return a random move
- return moves[randInt(moves.length)];
-
// Rank moves at depth 1:
- // try to capture something (not re-capturing)
+ let validMoves = [];
+ let illegalMoves = [];
moves.forEach(m => {
- V.PlayOnBoard(this.board, m);
- m.eval = this.evalPosition();
- V.UndoOnBoard(this.board, m);
+ // Warning: m might be illegal!
+ if (!m.illegal) {
+ V.PlayOnBoard(this.board, m);
+ m.eval = this.evalPosition();
+ V.UndoOnBoard(this.board, m);
+ validMoves.push(m);
+ } else illegalMoves.push(m);
});
- moves.sort((a, b) => {
+
+ const illegalRatio = illegalMoves.length / moves.length;
+ if (Math.random() < illegalRatio)
+ // Return a random illegal move
+ return illegalMoves[randInt(illegalMoves.length)];
+
+ validMoves.sort((a, b) => {
return (color == "w" ? 1 : -1) * (b.eval - a.eval);
});
let candidates = [0];
- for (let i = 1; i < moves.length && moves[i].eval == moves[0].eval; i++)
+ for (
+ let i = 1;
+ i < validMoves.length && validMoves[i].eval == moves[0].eval;
+ i++
+ ) {
candidates.push(i);
- return moves[candidates[randInt(candidates.length)]];
+ }
+ return validMoves[candidates[randInt(candidates.length)]];
}
getNotation(move) {
// Basic system: piece + init + dest square
return (
- move.vanish[0].p.toUpperCase() +
+ (move.vanish[0].p == V.KNIGHT ? "N" : "") +
V.CoordsToSquare(move.start) +
V.CoordsToSquare(move.end)
);