ff307d4a3d4cde9e5d76255b5e36f7d27c30d63e
[xogo.git] / variants / Suction / class.js
1 import ChessRules from "/base_rules.js";
2 import {FenUtil} from "/utils/setupPieces.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 s = FenUtil.setupPieces(
46 ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'],
47 {
48 randomness: this.options["randomness"],
49 diffCol: ['b']
50 }
51 );
52 return {
53 fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
54 s.w.join("").toUpperCase(),
55 o: {}
56 };
57 }
58
59 getPartFen(o) {
60 let parts = super.getPartFen(o);
61 const cmoveFen = o.init || !this.cmove
62 ? "-"
63 : C.CoordsToSquare(this.cmove.start) + C.CoordsToSquare(this.cmove.end);
64 parts["cmove"] = cmoveFen;
65 return parts;
66 }
67
68 getBasicMove([sx, sy], [ex, ey]) {
69 let move = super.getBasicMove([sx, sy], [ex, ey]);
70 if (move.vanish.length == 2) {
71 move.appear.push(
72 new PiPo({
73 x: sx,
74 y: sy,
75 c: move.vanish[1].c,
76 p: move.vanish[1].p
77 })
78 );
79 }
80 return move;
81 }
82
83 canIplay(x, y) {
84 return this.getPiece(x, y) != 'k' && super.canIplay(x, y);
85 }
86
87 // Does m2 un-do m1 ? (to disallow undoing captures)
88 oppositeMoves(m1, m2) {
89 return (
90 !!m1 &&
91 m2.vanish.length == 2 &&
92 m1.start.x == m2.start.x &&
93 m1.end.x == m2.end.x &&
94 m1.start.y == m2.start.y &&
95 m1.end.y == m2.end.y
96 );
97 }
98
99 filterValid(moves) {
100 return moves.filter(m => !this.oppositeMoves(this.cmove, m));
101 }
102
103 postPlay(move) {
104 super.postPlay(move);
105 this.cmove =
106 (move.vanish.length == 2 ? {start: move.start, end: move.end} : null);
107 }
108
109 atLeastOneMove() {
110 return true;
111 }
112
113 getCurrentScore() {
114 const color = this.turn;
115 const kingPos = super.searchKingPos(color);
116 if (color == "w" && kingPos[0][0] == 0) return "0-1";
117 if (color == "b" && kingPos[0][0] == this.size.x - 1) return "1-0";
118 // King is not on the opposite edge: game not over
119 return "*";
120 }
121
122 // Better animation for swaps
123 customAnimate(move, segments, cb) {
124 if (move.vanish.length < 2)
125 return 0;
126 super.animateMoving(move.end, move.start, null,
127 segments.reverse().map(s => s.reverse()), cb);
128 return 1;
129 }
130
131 };