| 1 | import ChessRules from "/base_rules.js"; |
| 2 | import PiPo from "/utils/PiPo.js"; |
| 3 | import Move from "/utils/Move.js"; |
| 4 | |
| 5 | export default class ChainingRules extends ChessRules { |
| 6 | |
| 7 | static get Options() { |
| 8 | return { |
| 9 | select: C.Options.select, |
| 10 | input: C.Options.input, |
| 11 | styles: ["atomic", "capture", "crazyhouse", "cylinder", "dark", "zen"] |
| 12 | }; |
| 13 | } |
| 14 | |
| 15 | get hasSelfCaptures() { |
| 16 | return true; |
| 17 | } |
| 18 | |
| 19 | canSelfTake() { |
| 20 | return true; //self captures induce chaining |
| 21 | } |
| 22 | |
| 23 | setOtherVariables(fenParsed) { |
| 24 | super.setOtherVariables(fenParsed); |
| 25 | // Stack of "last move" only for intermediate chaining |
| 26 | this.lastMoveEnd = []; |
| 27 | } |
| 28 | |
| 29 | getBasicMove([sx, sy], [ex, ey], tr) { |
| 30 | const L = this.lastMoveEnd.length; |
| 31 | const piece = (L >= 1 ? this.lastMoveEnd[L-1].p : null); |
| 32 | if ( |
| 33 | this.board[ex][ey] == "" || |
| 34 | this.getColor(ex, ey) == C.GetOppTurn(this.turn) |
| 35 | ) { |
| 36 | if (piece && !tr) |
| 37 | tr = {c: this.turn, p: piece}; |
| 38 | let mv = super.getBasicMove([sx, sy], [ex, ey], tr); |
| 39 | if (piece) |
| 40 | mv.vanish.pop(); //end of a chain: initial piece remains |
| 41 | return mv; |
| 42 | } |
| 43 | // (Self)Capture: initial, or inside a chain |
| 44 | const initPiece = (piece || this.getPiece(sx, sy)), |
| 45 | destPiece = this.getPiece(ex, ey); |
| 46 | let mv = new Move({ |
| 47 | start: {x: sx, y: sy}, |
| 48 | end: {x: ex, y: ey}, |
| 49 | appear: [ |
| 50 | new PiPo({ |
| 51 | x: ex, |
| 52 | y: ey, |
| 53 | c: this.turn, |
| 54 | p: (!!tr ? tr.p : initPiece) |
| 55 | }) |
| 56 | ], |
| 57 | vanish: [ |
| 58 | new PiPo({ |
| 59 | x: ex, |
| 60 | y: ey, |
| 61 | c: this.turn, |
| 62 | p: destPiece |
| 63 | }) |
| 64 | ] |
| 65 | }); |
| 66 | if (!piece) { |
| 67 | // Initial capture |
| 68 | mv.vanish.unshift( |
| 69 | new PiPo({ |
| 70 | x: sx, |
| 71 | y: sy, |
| 72 | c: this.turn, |
| 73 | p: initPiece |
| 74 | }) |
| 75 | ); |
| 76 | } |
| 77 | mv.chained = destPiece; //easier (no need to detect it) |
| 78 | // mv.drag = {c: this.turn, p: initPiece}; //TODO: doesn't work |
| 79 | return mv; |
| 80 | } |
| 81 | |
| 82 | getPiece(x, y) { |
| 83 | const L = this.lastMoveEnd.length; |
| 84 | if (L >= 1 && this.lastMoveEnd[L-1].x == x && this.lastMoveEnd[L-1].y == y) |
| 85 | return this.lastMoveEnd[L-1].p; |
| 86 | return super.getPiece(x, y); |
| 87 | } |
| 88 | |
| 89 | getPotentialMovesFrom([x, y], color) { |
| 90 | const L = this.lastMoveEnd.length; |
| 91 | if ( |
| 92 | L >= 1 && |
| 93 | (x != this.lastMoveEnd[L-1].x || y != this.lastMoveEnd[L-1].y) |
| 94 | ) { |
| 95 | // A self-capture was played: wrong square |
| 96 | return []; |
| 97 | } |
| 98 | return super.getPotentialMovesFrom([x, y], color); |
| 99 | } |
| 100 | |
| 101 | isLastMove(move) { |
| 102 | return !move.chained; |
| 103 | } |
| 104 | |
| 105 | postPlay(move) { |
| 106 | super.postPlay(move); |
| 107 | if (!!move.chained) { |
| 108 | this.lastMoveEnd.push({ |
| 109 | x: move.end.x, |
| 110 | y: move.end.y, |
| 111 | p: move.chained |
| 112 | }); |
| 113 | } |
| 114 | else |
| 115 | this.lastMoveEnd = []; |
| 116 | } |
| 117 | |
| 118 | }; |