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