X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=base_rules.js;h=0c316ebddadbe3516c19601b70e47ac450bcb687;hb=de1421be3ee53cb4ea8f112834d3de7a863fdd40;hp=a8dad15c575141e666b5326289ca7d36fee37a1d;hpb=b57b726c569a1a0f21b7f3ca00956bc2f26a6f3e;p=xogo.git diff --git a/base_rules.js b/base_rules.js index a8dad15..0c316eb 100644 --- a/base_rules.js +++ b/base_rules.js @@ -1321,6 +1321,11 @@ export default class ChessRules { return this.getColor(x1, y1) !== this.getColor(x2, y2); } + // Teleport & Recycle. Assumption: color(x1,y1) == color(x2,y2) + canSelfTake([x1, y1], [x2, y2]) { + return !this.isKing(x2, y2); + } + canStepOver(i, j, p) { // In some variants, objects on boards don't stop movement (Chakart) return this.board[i][j] == ""; @@ -1483,6 +1488,7 @@ export default class ChessRules { } // All possible moves from selected square + // TODO: generalize usage if arg "color" (e.g. Checkered) getPotentialMovesFrom([x, y], color) { if (this.subTurnTeleport == 2) return []; @@ -1717,14 +1723,18 @@ export default class ChessRules { segments: this.options["cylinder"], stepSpec: stepSpec }, - ([i1, j1], [i2, j2]) => - this.getColor(i2, j2) == color && !this.isKing(i2, j2) + ([i1, j1], [i2, j2]) => { + return ( + this.getColor(i2, j2) == color && + this.canSelfTake([i1, j1], [i2, j2]) + ); + } ); Array.prototype.push.apply(squares, selfCaptures); } return squares.map(s => { let mv = this.getBasicMove([x, y], s.sq); - if (this.options["cylinder"] && s.segments.length >= 2) + if (this.options["cylinder"] && !!s.segments && s.segments.length >= 2) mv.segments = s.segments; return mv; }); @@ -1742,7 +1752,7 @@ export default class ChessRules { const addSquare = ([i, j]) => { let elt = {sq: [i, j]}; if (o.segments) - elt.segments = this.getSegments(segments, segStart, end); + elt.segments = this.getSegments(segments, segStart, [i, j]); res.push(elt); }; const exploreSteps = (stepArray, mode) => { @@ -2159,6 +2169,31 @@ export default class ChessRules { return res; } + // cb: callback returning a boolean (false if king missing) + trackKingWrap(move, kingPos, cb) { + let newKingPP = null, + sqIdx = 0, + res = true; //a priori valid + const oldKingPP = + move.vanish.find(v => this.isKing(0, 0, v.p) && v.c == color); + if (oldKingPP) { + // Search king in appear array: + newKingPP = + move.appear.find(a => this.isKing(0, 0, a.p) && a.c == color); + if (newKingPP) { + sqIdx = kingPos.findIndex(kp => + kp[0] == oldKingPP.x && kp[1] == oldKingPP.y); + kingPos[sqIdx] = [newKingPP.x, newKingPP.y]; + } + else + res = false; //king vanished + } + res &&= cb(kingPos); + if (oldKingPP && newKingPP) + kingPos[sqIdx] = [oldKingPP.x, oldKingPP.y]; + return res; + } + // 'color' arg because some variants (e.g. Refusal) check opponent moves filterValid(moves, color) { if (!color) @@ -2167,26 +2202,9 @@ export default class ChessRules { let kingPos = this.searchKingPos(color); return moves.filter(m => { this.playOnBoard(m); - let newKingPP = null, - sqIdx = 0, - res = true; //a priori valid - const oldKingPP = - m.vanish.find(v => this.isKing(0, 0, v.p) && v.c == color); - if (oldKingPP) { - // Search king in appear array: - newKingPP = - m.appear.find(a => this.isKing(0, 0, a.p) && a.c == color); - if (newKingPP) { - sqIdx = kingPos.findIndex(kp => - kp[0] == oldKingPP.x && kp[1] == oldKingPP.y); - kingPos[sqIdx] = [newKingPP.x, newKingPP.y]; - } - else - res = false; //king vanished - } - res &&= !this.underCheck(kingPos, oppCols); - if (oldKingPP && newKingPP) - kingPos[sqIdx] = [oldKingPP.x, oldKingPP.y]; + const res = this.trackKingWrap(m, kingPos, (kp) => { + return !this.underCheck(kp, oppCols); + }); this.undoOnBoard(m); return res; }); @@ -2320,7 +2338,7 @@ export default class ChessRules { tryChangeTurn(move) { if (this.isLastMove(move)) { - this.turn = (this.turn == 'w' ? 'b' : 'w'); + this.turn = C.GetOppTurn(this.turn); this.movesCount++; this.subTurn = 1; } @@ -2362,7 +2380,7 @@ export default class ChessRules { if (this.board[i][j] != "" && this.getColor(i, j) == color) { // NOTE: in fact searching for all potential moves from i,j. // I don't believe this is an issue, for now at least. - const moves = this.getPotentialMovesFrom([i, j]); + const moves = this.getPotentialMovesFrom([i, j], color); if (moves.some(m => this.filterValid([m]).length >= 1)) return true; } @@ -2406,7 +2424,8 @@ export default class ChessRules { playVisual(move, r) { move.vanish.forEach(v => { - this.g_pieces[v.x][v.y].remove(); + if (this.g_pieces[v.x][v.y]) //can be null (e.g. Apocalypse) + this.g_pieces[v.x][v.y].remove(); this.g_pieces[v.x][v.y] = null; }); let chessboard = @@ -2475,6 +2494,10 @@ export default class ChessRules { animateMoving(start, end, drag, segments, cb) { let initPiece = this.getDomPiece(start.x, start.y); + if (!initPiece) { //TODO: shouldn't occur! + cb(); + return; + } // NOTE: cloning often not required, but light enough, and simpler let movingPiece = initPiece.cloneNode(); initPiece.style.opacity = "0";