Implemented and tested DarkChess. Berolina, Upsidedown should be OK. Marseille: TODO
[vchess.git] / public / javascripts / variants / Antiking.js
CommitLineData
204e289b 1class AntikingRules extends ChessRules
7d6b0773 2{
7d6b0773
BA
3 static getPpath(b)
4 {
5 return b[1]=='a' ? "Antiking/"+b : b;
6 }
7
8 static get ANTIKING() { return 'a'; }
7931e479 9
2d7194bd
BA
10 static get PIECES()
11 {
7931e479
BA
12 return ChessRules.PIECES.concat([V.ANTIKING]);
13 }
14
2d7194bd 15 setOtherVariables(fen)
46302e64 16 {
2d7194bd 17 super.setOtherVariables(fen);
204e289b 18 this.antikingPos = {'w':[-1,-1], 'b':[-1,-1]};
2d7194bd
BA
19 const rows = V.ParseFen(fen).position.split("/");
20 for (let i=0; i<rows.length; i++)
204e289b 21 {
6037f1d8 22 let k = 0;
2d7194bd 23 for (let j=0; j<rows[i].length; j++)
204e289b 24 {
2d7194bd 25 switch (rows[i].charAt(j))
204e289b
BA
26 {
27 case 'a':
6037f1d8 28 this.antikingPos['b'] = [i,k];
204e289b
BA
29 break;
30 case 'A':
6037f1d8 31 this.antikingPos['w'] = [i,k];
204e289b
BA
32 break;
33 default:
2d7194bd 34 const num = parseInt(rows[i].charAt(j));
204e289b 35 if (!isNaN(num))
6037f1d8 36 k += (num-1);
204e289b 37 }
6037f1d8 38 k++;
204e289b
BA
39 }
40 }
46302e64 41 }
7d6b0773 42
204e289b 43 canTake([x1,y1], [x2,y2])
7d6b0773 44 {
204e289b
BA
45 const piece1 = this.getPiece(x1,y1);
46 const piece2 = this.getPiece(x2,y2);
47 const color1 = this.getColor(x1,y1);
48 const color2 = this.getColor(x2,y2);
a6abf094 49 return piece2 != "a" &&
204e289b 50 ((piece1 != "a" && color1 != color2) || (piece1 == "a" && color1 == color2));
7d6b0773
BA
51 }
52
53 getPotentialMovesFrom([x,y])
54 {
7d6b0773
BA
55 switch (this.getPiece(x,y))
56 {
0b7d99ec 57 case V.ANTIKING:
204e289b 58 return this.getPotentialAntikingMoves([x,y]);
7d6b0773 59 default:
204e289b 60 return super.getPotentialMovesFrom([x,y]);
7d6b0773
BA
61 }
62 }
63
204e289b 64 getPotentialAntikingMoves(sq)
7d6b0773 65 {
a37076f1
BA
66 return this.getSlideNJumpMoves(sq,
67 V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
7d6b0773
BA
68 }
69
46302e64 70 isAttacked(sq, colors)
7d6b0773 71 {
46302e64 72 return (super.isAttacked(sq, colors) || this.isAttackedByAntiking(sq, colors));
7d6b0773
BA
73 }
74
6037f1d8
BA
75 isAttackedByKing([x,y], colors)
76 {
a37076f1 77 if (this.getPiece(x,y) == V.ANTIKING)
6037f1d8 78 return false; //antiking is not attacked by king
a37076f1
BA
79 return this.isAttackedBySlideNJump([x,y], colors, V.KING,
80 V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
6037f1d8
BA
81 }
82
204e289b 83 isAttackedByAntiking([x,y], colors)
7d6b0773 84 {
a734a1a0
BA
85 if ([V.KING,V.ANTIKING].includes(this.getPiece(x,y)))
86 return false; //(anti)king is not attacked by antiking
a37076f1
BA
87 return this.isAttackedBySlideNJump([x,y], colors, V.ANTIKING,
88 V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
7d6b0773
BA
89 }
90
46302e64 91 underCheck(move)
7d6b0773 92 {
46302e64 93 const c = this.turn;
204e289b
BA
94 const oppCol = this.getOppCol(c);
95 this.play(move)
cf130369
BA
96 let res = this.isAttacked(this.kingPos[c], [oppCol])
97 || !this.isAttacked(this.antikingPos[c], [oppCol]);
7d6b0773
BA
98 this.undo(move);
99 return res;
100 }
101
46302e64 102 getCheckSquares(move)
7d6b0773 103 {
204e289b 104 let res = super.getCheckSquares(move);
7d6b0773 105 this.play(move);
46302e64 106 const c = this.turn;
cf130369 107 if (!this.isAttacked(this.antikingPos[c], [this.getOppCol(c)]))
204e289b 108 res.push(JSON.parse(JSON.stringify(this.antikingPos[c])));
7d6b0773
BA
109 this.undo(move);
110 return res;
111 }
112
7d6b0773
BA
113 updateVariables(move)
114 {
204e289b 115 super.updateVariables(move);
388e4c40
BA
116 const piece = move.vanish[0].p;
117 const c = move.vanish[0].c;
204e289b 118 // Update antiking position
0b7d99ec 119 if (piece == V.ANTIKING)
204e289b
BA
120 {
121 this.antikingPos[c][0] = move.appear[0].x;
122 this.antikingPos[c][1] = move.appear[0].y;
123 }
7d6b0773
BA
124 }
125
126 unupdateVariables(move)
127 {
204e289b 128 super.unupdateVariables(move);
388e4c40
BA
129 const c = move.vanish[0].c;
130 if (move.vanish[0].p == V.ANTIKING)
204e289b 131 this.antikingPos[c] = [move.start.x, move.start.y];
7d6b0773
BA
132 }
133
204e289b 134 checkGameEnd()
7d6b0773 135 {
204e289b
BA
136 const color = this.turn;
137 const oppCol = this.getOppCol(color);
cf130369
BA
138 if (!this.isAttacked(this.kingPos[color], [oppCol])
139 && this.isAttacked(this.antikingPos[color], [oppCol]))
204e289b 140 {
7d6b0773 141 return "1/2";
204e289b 142 }
7d6b0773
BA
143 return color == "w" ? "0-1" : "1-0";
144 }
145
7d6b0773 146 static get VALUES() {
92342261
BA
147 return Object.assign(
148 ChessRules.VALUES,
149 { 'a': 1000 }
150 );
7d6b0773
BA
151 }
152
153 static GenRandInitFen()
154 {
7364deaa
BA
155 let pieces = { "w": new Array(8), "b": new Array(8) };
156 let antikingPos = { "w": -1, "b": -1 };
157 for (let c of ["w","b"])
158 {
159 let positions = _.range(8);
160
161 // Get random squares for bishops, but avoid corners; because,
162 // if an antiking blocks a cornered bishop, it can never be checkmated
163 let randIndex = 2 * _.random(1,3);
164 const bishop1Pos = positions[randIndex];
165 let randIndex_tmp = 2 * _.random(2) + 1;
166 const bishop2Pos = positions[randIndex_tmp];
167 positions.splice(Math.max(randIndex,randIndex_tmp), 1);
168 positions.splice(Math.min(randIndex,randIndex_tmp), 1);
169
170 randIndex = _.random(5);
171 const knight1Pos = positions[randIndex];
172 positions.splice(randIndex, 1);
173 randIndex = _.random(4);
174 const knight2Pos = positions[randIndex];
175 positions.splice(randIndex, 1);
176
177 randIndex = _.random(3);
178 const queenPos = positions[randIndex];
179 positions.splice(randIndex, 1);
180
181 const rook1Pos = positions[0];
182 const kingPos = positions[1];
183 const rook2Pos = positions[2];
184
185 // Random squares for antikings
186 antikingPos[c] = _.random(7);
187
188 pieces[c][rook1Pos] = 'r';
189 pieces[c][knight1Pos] = 'n';
190 pieces[c][bishop1Pos] = 'b';
191 pieces[c][queenPos] = 'q';
192 pieces[c][kingPos] = 'k';
193 pieces[c][bishop2Pos] = 'b';
194 pieces[c][knight2Pos] = 'n';
195 pieces[c][rook2Pos] = 'r';
196 }
197 const ranks23_black = "pppppppp/" + (antikingPos["w"]>0?antikingPos["w"]:"")
198 + "A" + (antikingPos["w"]<7?7-antikingPos["w"]:"");
199 const ranks23_white = (antikingPos["b"]>0?antikingPos["b"]:"") + "a"
200 + (antikingPos["b"]<7?7-antikingPos["b"]:"") + "/PPPPPPPP";
c794dbb8 201 return pieces["b"].join("") + "/" + ranks23_black +
7364deaa
BA
202 "/8/8/" +
203 ranks23_white + "/" + pieces["w"].join("").toUpperCase() +
fb6ceeff 204 " w 1111 -";
7d6b0773
BA
205 }
206}
643479f8
BA
207
208const VariantRules = AntikingRules;