Advance on Checkered. TODO: fix checks detection by checkered pieces
[xogo.git] / variants / Baroque / class.js
1 import AbstractSpecialCaptureRules from "/variants/_SpecialCaptures.js";
2 import {FenUtil} from "/utils/setupPieces.js";
3 import {Random} from "/utils/alea.js";
4
5 export default class BaroqueRules extends AbstractSpecialCaptureRules {
6
7 static get Options() {
8 return {
9 select: C.Options.Select,
10 input: [
11 {
12 label: "Capture king",
13 variable: "taking",
14 type: "checkbox",
15 defaut: false
16 }
17 ],
18 styles: [
19 "balance",
20 "capture",
21 "crazyhouse",
22 "cylinder",
23 "doublemove",
24 "progressive",
25 "recycle",
26 "teleport"
27 ]
28 };
29 }
30
31 get hasFlags() {
32 return false;
33 }
34
35 genRandInitBaseFen() {
36 const s = FenUtil.setupPieces(
37 ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'i'],
38 {
39 randomness: this.options["randomness"],
40 diffCol: ['b']
41 }
42 );
43 if (this.options["randomness"] <= 1) {
44 // Fix immobilizers/rooks pattern
45 const toExchange1 = s.w.indexOf('r'),
46 toExchange2 = s.w.indexOf('i');
47 s.w[toExchange1] = 'i';
48 s.w[toExchange2] = 'r';
49 }
50 return {
51 fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
52 s.w.join("").toUpperCase(),
53 o: {}
54 };
55 }
56
57 pieces() {
58 return Object.assign({},
59 super.pieces(),
60 {
61 'p': {
62 "class": "pawn", //pincer
63 moves: [
64 {steps: [[0, 1], [0, -1], [1, 0], [-1, 0]]}
65 ]
66 },
67 'r': {
68 "class": "rook", //coordinator
69 moves: [
70 {
71 steps: [
72 [1, 0], [0, 1], [-1, 0], [0, -1],
73 [1, 1], [1, -1], [-1, 1], [-1, -1]
74 ]
75 }
76 ]
77 },
78 'n': {
79 "class": "knight", //long-leaper
80 moveas: 'r'
81 },
82 'b': {
83 "class": "bishop", //chameleon
84 moveas: 'r'
85 },
86 'q': {
87 "class": "queen", //withdrawer
88 moveas: 'r'
89 },
90 'i': {
91 "class": "immobilizer",
92 moveas: 'r'
93 }
94 }
95 );
96 }
97
98 // Is piece on square (x,y) immobilized?
99 isImmobilized([x, y]) {
100 const piece = this.getPiece(x, y);
101 const color = this.getColor(x, y);
102 const oppCol = C.GetOppTurn(color);
103 const adjacentSteps = this.pieces()['k'].moves[0].steps;
104 for (let step of adjacentSteps) {
105 const [i, j] = [x + step[0], this.getY(y + step[1])];
106 if (
107 this.onBoard(i, j) &&
108 this.board[i][j] != "" &&
109 this.getColor(i, j) == oppCol
110 ) {
111 const oppPiece = this.getPiece(i, j);
112 if (oppPiece == 'i') {
113 // Moving is possible only if this immobilizer is neutralized
114 for (let step2 of adjacentSteps) {
115 const [i2, j2] = [i + step2[0], this.getY(j + step2[1])];
116 if (i2 == x && j2 == y)
117 continue; //skip initial piece!
118 if (
119 this.onBoard(i2, j2) &&
120 this.board[i2][j2] != "" &&
121 this.getColor(i2, j2) == color
122 ) {
123 if (['b', 'i'].includes(this.getPiece(i2, j2)))
124 return false;
125 }
126 }
127 return true; //immobilizer isn't neutralized
128 }
129 // Chameleons can't be immobilized twice,
130 // because there is only one immobilizer
131 if (oppPiece == 'b' && piece == 'i')
132 return true;
133 }
134 }
135 return false;
136 }
137
138 canTake([x1, y1], [x2, y2]) {
139 // Deactivate standard captures, except for king:
140 return (
141 this.getPiece(x1, y1) == 'k' &&
142 this.getColor(x1, y1) != this.getColor(x2, y2)
143 );
144 }
145
146 postProcessPotentialMoves(moves) {
147 if (moves.length == 0)
148 return [];
149 switch (moves[0].vanish[0].p) {
150 case 'p':
151 this.addPincerCaptures(moves);
152 break;
153 case 'r':
154 this.addCoordinatorCaptures(moves);
155 break;
156 case 'n':
157 const [x, y] = [moves[0].start.x, moves[0].start.y];
158 moves = moves.concat(this.getLeaperCaptures([x, y]));
159 break;
160 case 'b':
161 moves = this.getChameleonCaptures(moves, "pull");
162 break;
163 case 'q':
164 this.addPushmePullyouCaptures(moves, false, "pull");
165 break;
166 }
167 return moves;
168 }
169
170 };