Finish code refactoring to generate initial positions (untested)
[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'], {diffCol: ['b']});
38 if (this.options["randomness"] <= 1) {
39 // Fix immobilizers/rooks pattern
40 const toExchange1 = s.w.indexOf('r'),
41 toExchange2 = s.w.indexOf('i');
42 s.w[toExchange1] = 'i';
43 s.w[toExchange2] = 'r';
44 }
45 return {
46 fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
47 s.w.join("").toUpperCase(),
48 o: {}
49 };
50 }
51
52 pieces() {
53 return Object.assign({},
54 super.pieces(),
55 {
56 'p': {
57 "class": "pawn", //pincer
58 moves: [
59 {steps: [[0, 1], [0, -1], [1, 0], [-1, 0]]}
60 ]
61 },
62 'r': {
63 "class": "rook", //coordinator
64 moves: [
65 {
66 steps: [
67 [1, 0], [0, 1], [-1, 0], [0, -1],
68 [1, 1], [1, -1], [-1, 1], [-1, -1]
69 ]
70 }
71 ]
72 },
73 'n': {
74 "class": "knight", //long-leaper
75 moveas: 'r'
76 },
77 'b': {
78 "class": "bishop", //chameleon
79 moveas: 'r'
80 },
81 'q': {
82 "class": "queen", //withdrawer
83 moveas: 'r'
84 },
85 'i': {
86 "class": "immobilizer",
87 moveas: 'r'
88 }
89 }
90 );
91 }
92
93 // Is piece on square (x,y) immobilized?
94 isImmobilized([x, y]) {
95 const piece = this.getPiece(x, y);
96 const color = this.getColor(x, y);
97 const oppCol = C.GetOppCol(color);
98 const adjacentSteps = this.pieces()['k'].moves[0].steps;
99 for (let step of adjacentSteps) {
100 const [i, j] = [x + step[0], this.getY(y + step[1])];
101 if (
102 this.onBoard(i, j) &&
103 this.board[i][j] != "" &&
104 this.getColor(i, j) == oppCol
105 ) {
106 const oppPiece = this.getPiece(i, j);
107 if (oppPiece == 'i') {
108 // Moving is possible only if this immobilizer is neutralized
109 for (let step2 of adjacentSteps) {
110 const [i2, j2] = [i + step2[0], this.getY(j + step2[1])];
111 if (i2 == x && j2 == y)
112 continue; //skip initial piece!
113 if (
114 this.onBoard(i2, j2) &&
115 this.board[i2][j2] != "" &&
116 this.getColor(i2, j2) == color
117 ) {
118 if (['b', 'i'].includes(this.getPiece(i2, j2)))
119 return false;
120 }
121 }
122 return true; //immobilizer isn't neutralized
123 }
124 // Chameleons can't be immobilized twice,
125 // because there is only one immobilizer
126 if (oppPiece == 'b' && piece == 'i')
127 return true;
128 }
129 }
130 return false;
131 }
132
133 canTake([x1, y1], [x2, y2]) {
134 // Deactivate standard captures, except for king:
135 return (
136 this.getPiece(x1, y1) == 'k' &&
137 this.getColor(x1, y1) != this.getColor(x2, y2)
138 );
139 }
140
141 postProcessPotentialMoves(moves) {
142 if (moves.length == 0)
143 return [];
144 switch (moves[0].vanish[0].p) {
145 case 'p':
146 this.addPincerCaptures(moves);
147 break;
148 case 'r':
149 this.addCoordinatorCaptures(moves);
150 break;
151 case 'n':
152 const [x, y] = [moves[0].start.x, moves[0].start.y];
153 moves = moves.concat(this.getLeaperCaptures([x, y]));
154 break;
155 case 'b':
156 moves = this.getChameleonCaptures(moves, "pull");
157 break;
158 case 'q':
159 this.addPushmePullyouCaptures(moves, false, "pull");
160 break;
161 }
162 return moves;
163 }
164
165 };