Cleaner fen generation + first draft of Apocalypse + a few fixes
[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 genRandInitBaseFen() {
45 const options = Object.assign({mode: "suicide"}, this.options);
46 const gr = new GiveawayRules({options: options, genFenOnly: true});
47 return gr.genRandInitBaseFen();
48 }
49
50 getPartFen(o) {
51 let parts = super.getPartFen(o);
52 const cmoveFen = o.init || !this.cmove
53 ? "-"
54 : C.CoordsToSquare(this.cmove.start) + C.CoordsToSquare(this.cmove.end);
55 parts["cmove"] = cmoveFen;
56 return parts;
57 }
58
59 getBasicMove([sx, sy], [ex, ey]) {
60 let move = super.getBasicMove([sx, sy], [ex, ey]);
61 if (move.vanish.length == 2) {
62 move.appear.push(
63 new PiPo({
64 x: sx,
65 y: sy,
66 c: move.vanish[1].c,
67 p: move.vanish[1].p
68 })
69 );
70 }
71 return move;
72 }
73
74 canIplay(x, y) {
75 return this.getPiece(x, y) != 'k' && super.canIplay(x, y);
76 }
77
78 // Does m2 un-do m1 ? (to disallow undoing captures)
79 oppositeMoves(m1, m2) {
80 return (
81 !!m1 &&
82 m2.vanish.length == 2 &&
83 m1.start.x == m2.start.x &&
84 m1.end.x == m2.end.x &&
85 m1.start.y == m2.start.y &&
86 m1.end.y == m2.end.y
87 );
88 }
89
90 filterValid(moves) {
91 return moves.filter(m => !this.oppositeMoves(this.cmove, m));
92 }
93
94 postPlay(move) {
95 super.postPlay(move);
96 this.cmove =
97 (move.vanish.length == 2 ? {start: move.start, end: move.end} : null);
98 }
99
100 atLeastOneMove() {
101 return true;
102 }
103
104 getCurrentScore() {
105 const color = this.turn;
106 const kingPos = super.searchKingPos(color);
107 if (color == "w" && kingPos[0][0] == 0) return "0-1";
108 if (color == "b" && kingPos[0][0] == this.size.x - 1) return "1-0";
109 // King is not on the opposite edge: game not over
110 return "*";
111 }
112
113 // Better animation for swaps
114 customAnimate(move, segments, cb) {
115 if (move.vanish.length < 2)
116 return 0;
117 super.animateMoving(move.end, move.start, null,
118 segments.reverse().map(s => s.reverse()), cb);
119 return 1;
120 }
121
122 };