static get Options() {
return {
- // TODO: Zen too?
+ select: C.Options.select,
+ input: C.Options.input,
styles: [
"atomic", "cannibal", "capture", "cylinder",
"dark", "madrasi", "rifle", "teleport"
pieces(color, x, y) {
return Object.assign(
- {
- 'u': {
- "class": "undefined",
- moves: []
- }
- },
+ { 'u': {"class": "undefined"} },
super.pieces(color, x, y)
);
}
case 0:
if (typeof x == "string")
moves = this.getDropMovesFrom([x, y]);
+ // Empty move: just start + end
+ moves.forEach(m => {m.vanish.pop(); m.appear.pop();});
break;
case 1:
// Both normal move (from defined piece) and definition allowed
filterValid(moves) {
if (this.movesCount <= 1 || this.subTurn == 0)
return moves;
+ let filterLater = [];
if (this.subTurn == 1) {
- // Remove defining moves with un-movable def piece
+ // Remove defining moves with un-movable def piece,
+ // and separate compatible definitions.
moves = moves.filter(m => {
if (m.vanish.length >= 2 || m.vanish[0].p != 'u')
return true;
const canMove = super.filterValid(
super.getPotentialMovesFrom([m.end.x, m.end.y])).length >= 1;
this.undoOnBoard(m);
- return canMove;
+ if (canMove)
+ filterLater.push(m);
+ return false;
});
}
- return super.filterValid(moves);
+ return super.filterValid(moves).concat(filterLater);
}
atLeastOneMove(color) {
return super.atLeastOneMove(color);
}
- // TODO: this method fails to detect undefined checks
underCheck(square_s, oppCol) {
if (super.underCheck(square_s, oppCol))
return true;
// Check potential specializations of undefined using reserve:
+ const inReserve = Object.keys(this.reserve[oppCol])
+ .filter(k => this.reserve[oppCol][k] >= 1);
const allAttacks = Array.prototype.concat.apply(
- ['r', 'n', 'b', 'q'].map(p => this.pieces()[p].moves[0]));
- const [x, y] = [square_s[0], square_s[1]];
+ inReserve.map(p => this.pieces()[p].both[0]));
+ const [x, y] = square_s[0];
for (let i=0; i<this.size.x; i++) {
for (let j=0; j<this.size.y; j++) {
if (
return false;
}
- // TODO: missing "undefined reset" check (is everything defined? If yes, reset if enough variety)
postPlay(move) {
const color = this.turn;
- const toNextPlayer = () => {
- this.turn = C.GetOppCol(color);
- this.movesCount++;
- };
- if (this.movesCount <= 1) {
- toNextPlayer();
+ if (this.movesCount <= 1 || move.reset || move.next) {
+ if (!move.next)
+ this.tryChangeTurn();
return;
}
+ if (this.subTurn == 0)
+ this.captureUndef = null; //already used
const captureUndef = (
- move.vanish.length == 2 &&
+ move.vanish.length == 2 && //exclude subTurn == 0
move.vanish[1].c != color &&
move.vanish[1].p == 'u'
);
// Normal move (including Teleport)
super.postPlay(move);
else if (typeof move.start.x == "string") {
- this.reserve[color][move.appear[0].p]--;
+ super.updateReserve(
+ color, move.start.y, this.reserve[color][move.start.y] - 1);
if (move.vanish.length == 1 && move.vanish[0].p == 'u')
this.definition = move.end;
this.subTurn++;
else {
this.subTurn = 0;
this.captureUndef = move.end;
- toNextPlayer();
+ this.tryChangeTurn(null, captureUndef);
+ }
+ }
+
+ // NOTE: not "trying", the turn always change here (TODO?)
+ tryChangeTurn(move, captureUndef) {
+ this.definition = null;
+ this.subTurn = captureUndef ? 0 : 1;
+ this.turn = C.GetOppTurn(this.turn);
+ this.movesCount++;
+ }
+
+ computeNextMove(move) {
+ if (
+ !this.definition || this.playerColor != this.turn ||
+ this.board.some(row => row.some(cell =>
+ cell.charAt(0) == this.turn && cell.charAt(1) == 'u'))
+ ) {
+ return;
+ }
+ const variety = (c) => {
+ return (
+ [...new Set(
+ Array.prototype.concat.apply([],
+ this.board.map(row =>
+ row.filter(cell =>
+ cell.charAt(0) == c && !['p', 'k'].includes(cell.charAt(1))
+ ).map(cell => cell.charAt(1))
+ )
+ )
+ )].length >= 2
+ );
+ };
+ let next = {start: move.end, end: move.end, vanish: [], appear: []};
+ this.playOnBoard(move);
+ const twoOrMorePieces = {w: variety('w'), b: variety('b')};
+ const resetCols =
+ Object.keys(twoOrMorePieces).filter(k => twoOrMorePieces[k]);
+ if (resetCols.length >= 1) {
+ for (let i=0; i<this.size.x; i++) {
+ for (let j=0; j<this.size.y; j++) {
+ const colIJ = this.getColor(i, j);
+ const pieceIJ = this.getPiece(i, j);
+ if (
+ resetCols.includes(colIJ) &&
+ this.board[i][j] != "" &&
+ !['p', 'k', 'u'].includes(pieceIJ)
+ ) {
+ // NOTE: could also use a "flip" strategy similar to Benedict
+ next.vanish.push(new PiPo({c: colIJ, p: pieceIJ, x: i, y: j}));
+ next.appear.push(new PiPo({c: colIJ, p: 'u', x: i, y: j}));
+ this.reserve[colIJ][pieceIJ]++;
+ }
+ }
+ }
+ super.re_drawReserve(resetCols);
+ }
+ this.undoOnBoard(move);
+ if (next.vanish.length >= 1) {
+ next.reset = true;
+ move.next = next;
}
}