From c322a84434326dff1291a57e82dbd995817a5423 Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Wed, 26 Feb 2020 11:29:55 +0100 Subject: [PATCH] TODO: debug Knightrelay, use generators + yield for moves generation --- client/src/base_rules.js | 15 ++++++- client/src/variants/Check3.js | 20 +++++++++ client/src/variants/Knightrelay.js | 68 ++++++++++++++++++++++++++++++ client/src/variants/Rifle.js | 49 +++++++++++++++++++++ client/src/variants/Wormhole.js | 2 +- 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 client/src/variants/Check3.js create mode 100644 client/src/variants/Knightrelay.js create mode 100644 client/src/variants/Rifle.js diff --git a/client/src/base_rules.js b/client/src/base_rules.js index 4f1478e1..ef07742c 100644 --- a/client/src/base_rules.js +++ b/client/src/base_rules.js @@ -1121,6 +1121,7 @@ export const ChessRules = class ChessRules { // 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"); + if (moves1.length == 0) //TODO: this situation should not happen return null; @@ -1209,7 +1210,7 @@ export const ChessRules = class ChessRules { return (color == "w" ? 1 : -1) * (b.eval - a.eval); }); } else return currentBest; - // console.log(moves1.map(m => { return [this.getNotation(m), m.eval]; })); + console.log(moves1.map(m => { return [this.getNotation(m), m.eval]; })); candidates = [0]; for (let j = 1; j < moves1.length && moves1[j].eval == moves1[0].eval; j++) @@ -1254,6 +1255,18 @@ export const ChessRules = class ChessRules { for (let j = 0; j < V.size.y; j++) { if (this.board[i][j] != V.EMPTY) { const sign = this.getColor(i, j) == "w" ? 1 : -1; + + +//TODO: debug in KnightRelay +if (isNaN(V.VALUES[this.getPiece(i, j)])) { + console.log(i + " " + j); + console.log(this.getPiece(i, j)); + console.log(this.board); + console.log("ajout " + sign + " * "+ V.VALUES[this.getPiece(i, j)]); + debugger; +} + + evaluation += sign * V.VALUES[this.getPiece(i, j)]; } } diff --git a/client/src/variants/Check3.js b/client/src/variants/Check3.js new file mode 100644 index 00000000..63d5ae56 --- /dev/null +++ b/client/src/variants/Check3.js @@ -0,0 +1,20 @@ +import { ChessRules } from "@/base_rules"; + +export const VariantRules = class AntimatterRules extends ChessRules { + getPotentialMovesFrom([x, y]) { + let moves = super.getPotentialMovesFrom([x, y]); + + // Handle "matter collisions" + moves.forEach(m => { + if ( + m.vanish.length > 1 && + m.appear.length <= 1 && + m.vanish[0].p == m.vanish[1].p + ) { + m.appear.pop(); + } + }); + + return moves; + } +}; diff --git a/client/src/variants/Knightrelay.js b/client/src/variants/Knightrelay.js new file mode 100644 index 00000000..79688e2a --- /dev/null +++ b/client/src/variants/Knightrelay.js @@ -0,0 +1,68 @@ +import { ChessRules } from "@/base_rules"; + +export const VariantRules = class KnightrelayRules extends ChessRules { + getPotentialMovesFrom([x, y]) { + let moves = super.getPotentialMovesFrom([x, y]); + + // Expand possible moves if guarded by a knight: + if (this.getPiece(x,y) != V.KNIGHT) { + const color = this.turn; + let guardedByKnight = false; + for (const step of V.steps[V.KNIGHT]) { + if ( + V.OnBoard(x+step[0],y+step[1]) && + this.getPiece(x+step[0],y+step[1]) == V.KNIGHT && + this.getColor(x+step[0],y+step[1]) == color + ) { + guardedByKnight = true; + break; + } + } + if (guardedByKnight) { + for (const step of V.steps[V.KNIGHT]) { + if ( + V.OnBoard(x+step[0],y+step[1]) && + this.getColor(x+step[0],y+step[1]) != color + ) { + let m = this.getBasicMove([x,y], [x+step[0],y+step[1]]); + if (!m.appear[0].c || !m.vanish[0].c) + debugger; + moves.push(m); + //moves.push(this.getBasicMove([x,y], [x+step[0],y+step[1]])); + } + } + } + } + + return moves; + } + + getNotation(move) { + if (move.appear.length == 2 && move.appear[0].p == V.KING) + // Castle + return move.end.y < move.start.y ? "0-0-0" : "0-0"; + + // Translate final and initial square + const initSquare = V.CoordsToSquare(move.start); + const finalSquare = V.CoordsToSquare(move.end); + const piece = this.getPiece(move.start.x, move.start.y); + + // Since pieces and pawns could move like knight, indicate start and end squares + let notation = + piece.toUpperCase() + + initSquare + + (move.vanish.length > move.appear.length ? "x" : "") + + finalSquare + + if ( + piece == V.PAWN && + move.appear.length > 0 && + move.appear[0].p != V.PAWN + ) { + // Promotion + notation += "=" + move.appear[0].p.toUpperCase(); + } + + return notation; + } +}; diff --git a/client/src/variants/Rifle.js b/client/src/variants/Rifle.js new file mode 100644 index 00000000..61c2c352 --- /dev/null +++ b/client/src/variants/Rifle.js @@ -0,0 +1,49 @@ +import { ChessRules, PiPo, Move } from "@/base_rules"; + +export const VariantRules = class RifleRules extends ChessRules { + static get HasEnpassant() { + // Due to the capturing mode, en passant is disabled + return false; + } + + getBasicMove([sx, sy], [ex, ey], tr) { + let mv = new Move({ + appear: [], + vanish: [], + start: {x:sx, y:sy}, + end: {x:ex, y:ey} + }); + if (this.board[ex][ey] != V.EMPTY) { + // No movement: just vanishing enemy piece + mv.vanish = [ + new PiPo({ + x: ex, + y: ey, + c: this.getColor(ex, ey), + p: this.getPiece(ex, ey) + }) + ]; + } + else { + // Normal move + mv.appear = [ + new PiPo({ + x: ex, + y: ey, + c: tr ? tr.c : this.getColor(sx, sy), + p: tr ? tr.p : this.getPiece(sx, sy) + }) + ]; + mv.vanish = [ + new PiPo({ + x: sx, + y: sy, + c: this.getColor(sx, sy), + p: this.getPiece(sx, sy) + }) + ]; + } + + return mv; + } +}; diff --git a/client/src/variants/Wormhole.js b/client/src/variants/Wormhole.js index 964c5e40..a6be9f2b 100644 --- a/client/src/variants/Wormhole.js +++ b/client/src/variants/Wormhole.js @@ -4,7 +4,7 @@ import { randInt } from "@/utils/alea"; // TODO: -export const VariantRules = class HiddenRules extends ChessRules { +export const VariantRules = class WormholeRules extends ChessRules { static get HasFlags() { return false; } -- 2.44.0