cf5ae1682b74f56431b25632926c3b4b8bfaf421
[xogo.git] / variants / Suction / class.js
1 import ChessRules from "/base_rules.js";
2 import GiveawayRules from "/variants/Giveaway/class.js";
3 import PiPo from "/utils/PiPo.js";
4 import Move from "/utils/Move.js";
5
6 export default class SuctionRules extends ChessRules {
7
8 static get Options() {
9 return {
10 select: C.Options.select,
11 styles: [
12 "balance",
13 "capture",
14 "cylinder",
15 "dark",
16 "doublemove",
17 "madrasi",
18 "progressive",
19 "teleport"
20 ]
21 };
22 }
23
24 get pawnPromotions() {
25 return ['p']; //no promotions
26 }
27
28 get hasFlags() {
29 return false;
30 }
31
32 setOtherVariables(fenParsed) {
33 super.setOtherVariables(fenParsed);
34 this.cmove = null;
35 const cmove_str = fenParsed.cmove;
36 if (cmove_str != "-") {
37 this.cmove = {
38 start: C.SquareToCoords(cmove_str.substr(0, 2)),
39 end: C.SquareToCoords(cmove_str.substr(2))
40 };
41 }
42 }
43
44 genRandInitFen(seed) {
45 const options = Object.assign({mode: "suicide"}, this.options);
46 const gr = new GiveawayRules({options: options, genFenOnly: true});
47 const baseFen = gr.genRandInitFen(seed);
48 // Add empty cmove:
49 const fenParts = baseFen.split(" ");
50 let others = JSON.parse(fenParts[3]);
51 others["cmove"] = "-";
52 return fenParts.slice(0, 3).join(" ") + " " + JSON.stringify(others);
53 }
54
55 getFen() {
56 const cmoveFen = !this.cmove
57 ? "-"
58 : C.CoordsToSquare(this.cmove.start) + C.CoordsToSquare(this.cmove.end);
59 return super.getFen().slice(0, -1) + ',"cmove":"' + cmoveFen + '"}';
60 }
61
62 getBasicMove([sx, sy], [ex, ey]) {
63 let move = super.getBasicMove([sx, sy], [ex, ey]);
64 if (move.vanish.length == 2) {
65 move.appear.push(
66 new PiPo({
67 x: sx,
68 y: sy,
69 c: move.vanish[1].c,
70 p: move.vanish[1].p
71 })
72 );
73 }
74 return move;
75 }
76
77 canIplay(x, y) {
78 return this.getPiece(x, y) != 'k' && super.canIplay(x, y);
79 }
80
81 // Does m2 un-do m1 ? (to disallow undoing captures)
82 oppositeMoves(m1, m2) {
83 return (
84 !!m1 &&
85 m2.vanish.length == 2 &&
86 m1.start.x == m2.start.x &&
87 m1.end.x == m2.end.x &&
88 m1.start.y == m2.start.y &&
89 m1.end.y == m2.end.y
90 );
91 }
92
93 filterValid(moves) {
94 return moves.filter(m => !this.oppositeMoves(this.cmove, m));
95 }
96
97 postPlay(move) {
98 super.postPlay(move);
99 this.cmove =
100 (move.vanish.length == 2 ? {start: move.start, end: move.end} : null);
101 }
102
103 atLeastOneMove() {
104 return true;
105 }
106
107 getCurrentScore() {
108 const color = this.turn;
109 const kingPos = super.searchKingPos(color);
110 if (color == "w" && kingPos[0][0] == 0) return "0-1";
111 if (color == "b" && kingPos[0][0] == this.size.x - 1) return "1-0";
112 // King is not on the opposite edge: game not over
113 return "*";
114 }
115
116 // Better animation for swaps
117 customAnimate(move, segments, cb) {
118 if (move.vanish.length < 2)
119 return 0;
120 super.animateMoving(move.end, move.start, null,
121 segments.reverse().map(s => s.reverse()), cb);
122 return 1;
123 }
124
125 };