}
// Arguments x, y are useful for Eightpieces (maybe others?)
- get pawnPromotions(x, y) {
+ pawnPromotions(x, y) {
return ['q', 'r', 'n', 'b'];
}
this[arrName][i][j].style.height = pieceWidth + "px";
let [ip, jp] = this.getPixelPosition(i, j, r);
// Translate coordinates to use chessboard as reference:
- this[arrName][i][j].style.transform =
- `translate(${ip - r.x}px,${jp - r.y}px)`;
+ this[arrName][i][j].style.translate = `${ip - r.x}px ${jp - r.y}px`;
chessboard.appendChild(this[arrName][i][j]);
};
const conditionalReset = (arrName) => {
this.g_pieces[i][j].style.height = pieceWidth + "px";
const [ip, jp] = this.getPixelPosition(i, j, newR);
// Translate coordinates to use chessboard as reference:
- this.g_pieces[i][j].style.transform =
- `translate(${ip - newX}px,${jp - newY}px)`;
+ this.g_pieces[i][j].style.translate =
+ `${ip - newX}px ${jp - newY}px`;
}
}
}
finalPieces = [this.getPieceType(x2, y2)];
}
else
- finalPieces = this.pawnPromotions;
+ finalPieces = this.pawnPromotions(x2, y2);
m.appear[0].p = finalPieces[0];
if (initPiece == "!") //cannibal king-pawn
m.appear[0].p = C.CannibalKingCode[finalPieces[0]];
m.appear[0].x == m.start.x &&
m.appear[0].y == m.start.y
) {
- m.appear[0].p = this.pawnPromotions[0];
- for (let i=1; i<this.pawnPromotions.length; i++) {
+ const promotions = this.pawnPromotions(m.start.x, m.start.y);
+ m.appear[0].p = promotions[0];
+ for (let i = 1; i < promotions.length; i++)
+ {
let newMv = JSON.parse(JSON.stringify(m));
- newMv.appear[0].p = this.pawnPromotions[i];
+ newMv.appear[0].p = promotions[i];
newMoves.push(newMv);
}
}
if (this.canStepOver(x, y, apparentPiece))
continue;
const stepSpec = this.getStepSpec(colIJ, i, j);
+ if (stepSpec.indirectAttack) //e.g. 8-pieces (only?)
+ continue;
const attacks = stepSpec.attack.concat(stepSpec.both);
for (let a of attacks) {
for (let s of a.steps) {
this.g_pieces[a.x][a.y].style.height = pieceWidth + "px";
const [ip, jp] = this.getPixelPosition(a.x, a.y, r);
// Translate coordinates to use chessboard as reference:
- this.g_pieces[a.x][a.y].style.transform =
- `translate(${ip - r.x}px,${jp - r.y}px)`;
+ this.g_pieces[a.x][a.y].style.translate = `${ip - r.x}px ${jp - r.y}px`;
if (this.enlightened && !this.enlightened[a.x][a.y])
this.g_pieces[a.x][a.y].classList.add("hidden");
chessboard.appendChild(this.g_pieces[a.x][a.y]);
const dep = this.getPixelPosition(i1, j1, r);
const arr = this.getPixelPosition(i2, j2, r);
movingPiece.style.transitionDuration = "0s";
- movingPiece.style.transform = `translate(${dep[0]}px, ${dep[1]}px)`;
+ movingPiece.style.translate = `${dep[0]}px ${dep[1]}px`;
const distance =
Math.sqrt((arr[0] - dep[0]) ** 2 + (arr[1] - dep[1]) ** 2);
const duration = 0.2 + (distance / maxDist) * 0.3;
setTimeout(() => {
movingPiece.style.transitionDuration = duration + "s";
// movingPiece is child of container: no need to adjust coordinates
- movingPiece.style.transform = `translate(${arr[0]}px, ${arr[1]}px)`;
+ movingPiece.style.translate = `${arr[0]}px ${arr[1]}px`;
setTimeout(cb, duration * 1000);
}, 50);
};
{name: 'Doublearmy', desc: '64 pieces on the board', disp: 'Double Army'},
{name: 'Doublemove', desc: 'Double moves'},
{name: 'Dynamo', desc: 'Push and pull'},
-// {name: 'Eightpieces', desc: 'Each piece is unique', disp: '8 Pieces'},
+ {name: 'Eightpieces', desc: 'Each piece is unique', disp: '8 Pieces'},
// {name: 'Emergo', desc: 'Stacking Checkers variant'},
// {name: 'Empire', desc: 'Empire versus Kingdom'},
// {name: 'Enpassant', desc: 'Capture en passant', disp: 'En-passant'},
return true;
}
- get pawnPromotions() {
+ pawnPromotions() {
return ['n', 'p'];
}
return null;
}
let moves = [];
- this.pawnPromotions.forEach(pr => {
+ this.pawnPromotions().forEach(pr => {
moves.push(
new Move({
vanish: [new PiPo({x: coords.x, y: coords.y, c: this.turn, p: 'p'})],
export default class BalaklavaRules extends ChessRules {
- get pawnPromotions() {
+ pawnPromotions() {
return ['r', 'm', 'b', 'q'];
}
export default class CapablancaRules extends ChessRules {
- get pawnPromotions() {
+ pawnPromotions() {
return ['q', 'e', 's', 'r', 'n', 'b'];
}
};
}
- get pawnPromotions() {
+ pawnPromotions() {
return ['q', 'r', 'n', 'b', 'k'];
}
this.reserve = { w: {}, b: {} };
// Randomly select a piece in pawnPromotions
if (!move.toadette)
- move.toadette = Random.sample(this.pawnPromotions);
+ move.toadette = Random.sample( this.pawnPromotions() );
this.reserve[color][move.toadette] = 1;
this.re_drawReserve([color]);
}
);
}
- get pawnPromotions() {
+ pawnPromotions() {
// Can promote in anything from the two current armies
let promotions = [];
for (let army of ["army1", "army2"]) {
return {}; //nothing would make sense
}
- get pawnPromotions() {
+ pawnPromotions() {
return ['p'];
}
super(o);
}
- get pawnPromotions() {
+ pawnPromotions() {
return ['h'];
}
while (this.onBoard(i, j) && this.board[i][j] == "") {
if (i == lastRank && piece == 'p') {
// Promotion by push or pull (if suicide)
- this.pawnPromotions.forEach(p => {
+ this.pawnPromotions().forEach(p => {
let move = super.getBasicMove([x, y], [i, j], { c: color, p: p });
moves.push(move);
});
import {FenUtil} from "/utils/setupPieces.js";
+import ChessRules from "/base_rules.js";
import PiPo from "/utils/PiPo.js";
import Move from "/utils/Move.js";
};
}
- get pawnPromotions(x, y) {
+ pawnPromotions(x, y) {
const base_pieces = ['q', 'r', 'n', 'b', 'j', 's'];
let lancers = [];
if (y > 0)
if (y < this.size.y)
lancers.push('f');
}
- else { //x == this.size.x (8)
+ else { //x == this.size.x-1 (7)
lancers.push('c');
if (y > 0)
lancers.push('o');
if (y < this.size.y)
lancers.push('d');
}
- return ['q', 'r', 'n', 'b', 'j', 's', 'l'];
+ return base_pieces.concat(lancers);
}
genRandInitBaseFen() {
- const s = FenUtil.setupPieces(
+ let s = FenUtil.setupPieces(
['j', 'l', 's', 'q', 'k', 'b', 'n', 'r'],
{
randomness: this.options["randomness"],
flags: ['r', 'j']
}
);
+ const random = (this.options["randomness"] > 0);
+ const fen = s.b.join("").replace('l', random ? 'g' : 'f') +
+ "/pppppppp/8/8/8/8/PPPPPPPP/" +
+ s.w.join("").replace('l', random > 0 ? 'c' : 'd').toUpperCase();
return {
- fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
- s.w.join("").toUpperCase(),
+ fen: fen,
o: {flags: s.flags}
};
}
setOtherVariables(fenParsed) {
super.setOtherVariables(fenParsed);
- // TODO: state variables (sentry pushes, lancers?)
+ //this.pushFrom =
+ //this.afterPush =
}
+ // TODO: FEN utils pushFrom et afterPush
+
pieces(color, x, y) {
- const base_pieces = super.pieces(color, x, y);
- return {
+ return Object.assign({
'j': {
"class": "jailer",
moves: [
},
's': {
"class": "sentry",
+ indirectAttack: true,
both: [
{steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]]}
]
{steps: [[-1, -1]]}
]
},
- };
+ }, super.pieces(color, x, y));
}
isImmobilized([x, y]) {
const color = this.getColor(x, y);
- const oppCol = C.getOppTurn(color);
+ const oppCol = C.GetOppTurn(color);
const stepSpec = this.getStepSpec(color, x, y, 'j');
- for (let step of stepSpec.both[0].steps) {
+ for (let step of stepSpec.moves[0].steps) {
let [i, j] = this.increment([x, y], step);
if (
this.onBoard(i, j) &&
return false;
}
+ getPotentialMovesFrom([x, y], color) {
+ if (!this.pushFrom)
+ return super.getPotentialMovesFrom([x, y], color);
+ if (x != this.pushFrom.x || y != this.pushFrom.y)
+ return [];
+ // After sentry "attack": move enemy as if it was ours
+ return []; //TODO
+ }
+
getSentryPushes(x, y) {
// TODO: return all squares piece on x, y can be pushed to
- // Simple
+ return [{x: x+1, y: y-1}];
}
// Post-process sentry pushes (if any)
return finalMoves;
}
-//idée exception globle dans base_rules.js d'une pièce marquée comme "indirect attack" ?!
- // TODO:::::: under sentry attack?!
- // Is piece (or square) at given position attacked by "oppCol(s)" ?
- underAttack([x, y], oppCols) {
- super.underAttack([x, y], oppCols)
- // An empty square is considered as king,
- // since it's used only in getCastleMoves (TODO?)
- const king = this.board[x][y] == "" || this.isKing(x, y);
- return (
- (
- (!this.options["zen"] || king) &&
- this.findCapturesOn(
- [x, y],
- {
- byCol: oppCols,
- one: true
- }
- )
- )
- ||
- (
- (!!this.options["zen"] && !king) &&
- this.findDestSquares(
- [x, y],
- {
- attackOnly: true,
- one: true
- },
- ([i1, j1], [i2, j2]) => oppCols.includes(this.getColor(i2, j2))
- )
- )
- );
- }
-
-
- // TODO::: sentry subturn ???
- // 'color' arg because some variants (e.g. Refusal) check opponent moves
+ // Lazy sentry attacks check: after push move
filterValid(moves, color) {
- color = color || this.turn;
- const oppCols = this.getOppCols(color);
- let kingPos = this.searchKingPos(color);
- return moves.filter(m => {
- this.playOnBoard(m);
- const res = this.trackKingWrap(m, kingPos, (kp) => {
- return !this.underCheck(kp, oppCols);
- });
- this.undoOnBoard(m);
- return res;
+ let sentryAttack = [];
+ moves = moves.filter(m => {
+ if (m.appear.length == 0) {
+ sentryAttack.push(m);
+ return false;
+ }
+ return true;
});
+ return super.filterValid(moves, color).concat(sentryAttack);
}
};
return this.options["mode"] == "losers";
}
- get pawnPromotions() {
+ pawnPromotions() {
let res = ['q', 'r', 'n', 'b'];
if (this.options["mode"] == "suicide")
res.push('k');
};
}
- get pawnPromotions() {
+ pawnPromotions() {
return ['p']; //no promotions
}