-class AntikingRules
+class AntikingRules extends ChessRules
{
// Path to pieces
static getPpath(b)
initVariables(fen)
{
super.initVariables(fen);
- // TODO: initialize this.antikingPos[...]
+ this.antikingPos = {'w':[-1,-1], 'b':[-1,-1]};
+ const position = fen.split(" ")[0].split("/");
+ for (let i=0; i<position.length; i++)
+ {
+ let j = 0;
+ while (j < position[i].length)
+ {
+ switch (position[i].charAt(j))
+ {
+ case 'a':
+ this.antikingPos['b'] = [i,j];
+ break;
+ case 'A':
+ this.antikingPos['w'] = [i,j];
+ break;
+ default:
+ let num = parseInt(position[i].charAt(j));
+ if (!isNaN(num))
+ j += (num-1);
+ }
+ j++;
+ }
+ }
}
- canTake(color1, color2, [x,y])
+ canTake([x1,y1], [x2,y2])
{
- const piece = this.getPiece(x,y);
- return (piece != "a" && color1 != color2) || (piece == "a" && color1 == color2);
+ const piece1 = this.getPiece(x1,y1);
+ const piece2 = this.getPiece(x2,y2);
+ const color1 = this.getColor(x1,y1);
+ const color2 = this.getColor(x2,y2);
+ return !["a","A"].includes(piece2) &&
+ ((piece1 != "a" && color1 != color2) || (piece1 == "a" && color1 == color2));
}
getPotentialMovesFrom([x,y])
{
- let c = this.getColor(x,y);
switch (this.getPiece(x,y))
{
case VariantRules.ANTIKING:
- return this.getPotentialAntikingMoves(x,y,c);
+ return this.getPotentialAntikingMoves([x,y]);
default:
- return super.getPotentielMovesFrom([x,y]);
+ return super.getPotentialMovesFrom([x,y]);
}
}
- getPotentialAntikingMoves([x,y])
+ getPotentialAntikingMoves(sq)
{
- // TODO
+ return this.getSlideNJumpMoves(sq, VariantRules.steps[VariantRules.QUEEN], "oneStep");
}
isAttacked(sq, colors)
return (super.isAttacked(sq, colors) || this.isAttackedByAntiking(sq, colors));
}
- isAttackedByAntiking(sq, color)
+ isAttackedByAntiking([x,y], colors)
{
- // TODO
+ console.log(x + " " + y); //TODO: debug -1, -1 (wrong undo ?!)
+ if (this.getPiece(x,y) == VariantRules.KING)
+ return false; //king is not attacked by antiking
+ return super.isAttackedBySlideNJump([x,y], colors,
+ VariantRules.ANTIKING, VariantRules.steps[VariantRules.QUEEN], "oneStep");
}
underCheck(move)
{
const c = this.turn;
- this.play(move);
- let res = this.isAttacked(this.kingPos[c], this.getOppCol(c));
- // TODO: also check that antiking is still in check
+ const oppCol = this.getOppCol(c);
+ this.play(move)
+ let res = this.isAttacked(this.kingPos[c], oppCol)
+ || !this.isAttacked(this.antikingPos[c], oppCol);
this.undo(move);
return res;
}
getCheckSquares(move)
{
+ let res = super.getCheckSquares(move);
this.play(move);
const c = this.turn;
- // TODO
- let res = this.isAttacked(this.kingPos[c], this.getOppCol(c))
- ? [ JSON.parse(JSON.stringify(this.kingPos[c])) ]
- : [ ];
+ if (!this.isAttacked(this.antikingPos[c], this.getOppCol(c)))
+ res.push(JSON.parse(JSON.stringify(this.antikingPos[c])));
this.undo(move);
return res;
}
- // TODO: need antikingPos as well
updateVariables(move)
{
- // ...
+ super.updateVariables(move);
+ const piece = this.getPiece(move.start.x,move.start.y);
+ const c = this.getColor(move.start.x,move.start.y);
+ // Update antiking position
+ if (piece == VariantRules.ANTIKING)
+ {
+ this.antikingPos[c][0] = move.appear[0].x;
+ this.antikingPos[c][1] = move.appear[0].y;
+ }
}
unupdateVariables(move)
{
- // TODO
+ super.unupdateVariables(move);
+ const c = this.getColor(move.start.x,move.start.y);
+ if (this.getPiece(move.start.x,move.start.y) == VariantRules.ANTIKING)
+ this.antikingPos[c] = [move.start.x, move.start.y];
}
- checkGameEnd(color)
+ checkGameEnd()
{
- // TODO
- if (!this.isAttacked(this.kingPos[color], this.getOppCol(color)))
+ const color = this.turn;
+ const oppCol = this.getOppCol(color);
+ if (!this.isAttacked(this.kingPos[color], oppCol)
+ && this.isAttacked(this.antikingPos[color], oppCol))
+ {
return "1/2";
+ }
return color == "w" ? "0-1" : "1-0";
}
static GenRandInitFen()
{
let randFen = ChessRules.GenRandInitFen();
- // TODO: just add an antiking at random on 3rd ranks
+ // Black side
+ let antikingPos = _.random(7);
+ let ranks23 = "pppppppp/" + (antikingPos>0?antikingPos:"") + "A" + (antikingPos<7?7-antikingPos:"");
+ randFen = randFen.replace("pppppppp/8", ranks23);
+ // White side
+ antikingPos = _.random(7);
+ ranks23 = (antikingPos>0?antikingPos:"") + "a" + (antikingPos<7?7-antikingPos:"") + "/PPPPPPPP";
+ randFen = randFen.replace("8/PPPPPPPP", ranks23);
return randFen;
}
}
--- /dev/null
+p.boxed
+ | You have a king and an antiking. King must stay away from checks, but antiking must always stay in check.
+ | Antiking captures his own kind.
+
+h3 Specifications
+
+ul
+ li Chessboard: standard.
+ li Material: additional antiking.
+ li Non-capturing moves: standard.
+ li Special moves: standard.
+ li Captures: special case of antiking (see below).
+ li End of game: Checkmate or anti-checkmate.
+
+h3 Basics
+
+p
+ | The additional piece is a royal figure, thus cannot be captured.
+ | It captures the pieces of his color (to help checkmate opponent antiking, but by doing so it also make standard checkmate more difficult...).
+ | It should always remains under check (if it cannot, game is over).
+
+figure.diagram-container
+ .diagram
+ | fen:rnbqkbnr/pppppppp/3A4/8/8/3a4/PPPPPPPP/RNBQKBNR:
+ figcaption Initial position (non-random). 1.Ae5 is forbidden.
+
+h3 End of the game
+
+p There are two ways to win:
+ol
+ li Checkmate opponent king
+ li Anti-checkmate opponent antiking
+p ...Or maybe do both at the same time?
+
+p Note 1: athough antiking captures his color, it doesn't check his king.
+
+p Note 2: since it would allow a basic tactic (keep antiking touching opponent's king), kings do not attack antikings.
+
+h3 Credits
+
+p
+ a(href="https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html") Antiking chess
+ | on chessvariants.com.