/////////////
// FEN UTILS
- // Setup the initial random (assymetric) position
- static GenRandInitFen() {
+ // Setup the initial random (asymmetric) position
+ static GenRandInitFen(randomness) {
+ if (!randomness) randomness = 2;
+ if (randomness == 0)
+ // Deterministic:
+ return "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w 0 1111 -";
+
let pieces = { w: new Array(8), b: new Array(8) };
- // Shuffle pieces on first and last rank
+ // Shuffle pieces on first (and last rank if randomness == 2)
for (let c of ["w", "b"]) {
+ if (c == 'b' && randomness == 1) {
+ pieces['b'] = pieces['w'];
+ break;
+ }
+
let positions = ArrayFun.range(8);
// Get random squares for bishops
//////////////////
// INITIALIZATION
- constructor(fen) {
- // In printDiagram() fen isn't supply because only getPpath() is used
- if (fen)
- this.re_init(fen);
- }
-
// Fen string fully describes the game state
- re_init(fen) {
+ constructor(fen) {
+ if (!fen)
+ // In printDiagram() fen isn't supply because only getPpath() is used
+ // TODO: find a better solution!
+ return;
const fenParsed = V.ParseFen(fen);
this.board = V.GetBoard(fenParsed.position);
this.turn = fenParsed.turn[0]; //[0] to work with MarseilleRules
return 3;
}
- // NOTE: works also for extinction chess because depth is 3...
getComputerMove() {
const maxeval = V.INFINITY;
const color = this.turn;
// Some variants may show a bigger moves list to the human (Switching),
// thus the argument "computer" below (which is generally ignored)
- let moves1 = this.getAllValidMoves("computer");
+ let moves1 = this.getAllValidMoves();
if (moves1.length == 0)
// TODO: this situation should not happen
return null;
- // Can I mate in 1 ? (for Magnetic & Extinction)
- for (let i of shuffle(ArrayFun.range(moves1.length))) {
- this.play(moves1[i]);
- let finish = Math.abs(this.evalPosition()) >= V.THRESHOLD_MATE;
- if (!finish) {
- const score = this.getCurrentScore();
- if (["1-0", "0-1"].includes(score)) finish = true;
- }
- 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++) {
// Initial self evaluation is very low: "I'm checkmated"
// Initial enemy evaluation is very low too, for him
eval2 = (color == "w" ? 1 : -1) * maxeval;
// Second half-move:
- let moves2 = this.getAllValidMoves("computer");
+ let moves2 = this.getAllValidMoves();
for (let j = 0; j < moves2.length; j++) {
this.play(moves2[j]);
const score2 = this.getCurrentScore();
moves1.sort((a, b) => {
return (color == "w" ? 1 : -1) * (b.eval - a.eval);
});
+// console.log(moves1.map(m => { return [this.getNotation(m), m.eval]; }));
let candidates = [0]; //indices of candidates moves
for (let j = 1; j < moves1.length && moves1[j].eval == moves1[0].eval; j++)
if (score != "*")
return score == "1/2" ? 0 : (score == "1-0" ? 1 : -1) * maxeval;
if (depth == 0) return this.evalPosition();
- const moves = this.getAllValidMoves("computer");
+ const moves = this.getAllValidMoves();
let v = color == "w" ? -maxeval : maxeval;
if (color == "w") {
for (let i = 0; i < moves.length; i++) {