Save current state (unfinished, untested)
[vchess.git] / public / javascripts / variants / Loser.js
CommitLineData
a6abf094
BA
1class LoserRules extends ChessRules
2{
3 initVariables(fen)
4 {
a6abf094
BA
5 const epSq = this.moves.length > 0 ? this.getEpSquare(this.lastMove) : undefined;
6 this.epSquares = [ epSq ];
7 }
8
7931e479
BA
9 static IsGoodFlags(flags)
10 {
11 return true; //anything is good: no flags
12 }
13
c794dbb8 14 setFlags(fenflags)
1970e049
BA
15 {
16 // No castling, hence no flags; but flags defined for compatibility
77e1ec78 17 this.castleFlags = { "w":[false,false], "b":[false,false] };
1970e049 18 }
a6abf094
BA
19
20 getPotentialPawnMoves([x,y])
21 {
22 let moves = super.getPotentialPawnMoves([x,y]);
23
24 // Complete with promotion(s) into king, if possible
25 const color = this.turn;
a6abf094 26 const shift = (color == "w" ? -1 : 1);
0b7d99ec 27 const lastRank = (color == "w" ? 0 : V.size.x-1);
a6abf094
BA
28 if (x+shift == lastRank)
29 {
a6abf094
BA
30 // Normal move
31 if (this.board[x+shift][y] == V.EMPTY)
92342261 32 moves.push(this.getBasicMove([x,y], [x+shift,y], {c:color,p:V.KING}));
a6abf094 33 // Captures
92342261
BA
34 if (y>0 && this.canTake([x,y], [x+shift,y-1])
35 && this.board[x+shift][y-1] != V.EMPTY)
36 {
37 moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:color,p:V.KING}));
38 }
0b7d99ec 39 if (y<V.size.y-1 && this.canTake([x,y], [x+shift,y+1])
92342261
BA
40 && this.board[x+shift][y+1] != V.EMPTY)
41 {
42 moves.push(this.getBasicMove([x,y], [x+shift,y+1], {c:color,p:V.KING}));
43 }
a6abf094
BA
44 }
45
46 return moves;
47 }
48
49 getPotentialKingMoves(sq)
50 {
a6abf094
BA
51 return this.getSlideNJumpMoves(sq,
52 V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
53 }
54
55 // Stop at the first capture found (if any)
56 atLeastOneCapture()
57 {
58 const color = this.turn;
59 const oppCol = this.getOppCol(color);
0b7d99ec 60 for (let i=0; i<V.size.x; i++)
a6abf094 61 {
0b7d99ec 62 for (let j=0; j<V.size.y; j++)
a6abf094 63 {
0b7d99ec 64 if (this.board[i][j] != V.EMPTY && this.getColor(i,j) != oppCol)
a6abf094
BA
65 {
66 const moves = this.getPotentialMovesFrom([i,j]);
67 if (moves.length > 0)
68 {
69 for (let k=0; k<moves.length; k++)
70 {
71 if (moves[k].vanish.length==2 && this.filterValid([moves[k]]).length > 0)
72 return true;
73 }
74 }
75 }
76 }
77 }
78 return false;
79 }
80
81 // Trim all non-capturing moves
82 static KeepCaptures(moves)
83 {
84 return moves.filter(m => { return m.vanish.length == 2; });
85 }
86
87 getPossibleMovesFrom(sq)
88 {
89 let moves = this.filterValid( this.getPotentialMovesFrom(sq) );
90 // This is called from interface: we need to know if a capture is possible
91 if (this.atLeastOneCapture())
0b7d99ec 92 moves = V.KeepCaptures(moves);
a6abf094
BA
93 return moves;
94 }
95
96 getAllValidMoves()
97 {
98 let moves = super.getAllValidMoves();
99 if (moves.some(m => { return m.vanish.length == 2; }))
0b7d99ec 100 moves = V.KeepCaptures(moves);
a6abf094
BA
101 return moves;
102 }
103
104 underCheck(move)
105 {
106 return false; //No notion of check
107 }
108
109 getCheckSquares(move)
110 {
111 return [];
112 }
113
6752407b
BA
114 // Unused:
115 updateVariables(move) { }
116 unupdateVariables(move) { }
a6abf094 117
77e1ec78
BA
118 getFlagsFen()
119 {
92342261 120 return "-";
77e1ec78
BA
121 }
122
a6abf094
BA
123 checkGameEnd()
124 {
125 // No valid move: you win!
126 return this.turn == "w" ? "1-0" : "0-1";
127 }
128
129 static get VALUES() { //experimental...
130 return {
131 'p': 1,
132 'r': 7,
133 'n': 3,
134 'b': 3,
135 'q': 5,
136 'k': 5
137 };
138 }
139
140 static get SEARCH_DEPTH() { return 4; }
141
142 evalPosition()
143 {
144 return - super.evalPosition(); //better with less material
145 }
2eef6db6
BA
146
147 static GenRandInitFen()
148 {
149 let pieces = { "w": new Array(8), "b": new Array(8) };
150 // Shuffle pieces on first and last rank
151 for (let c of ["w","b"])
152 {
153 let positions = _.range(8);
154
155 // Get random squares for bishops
156 let randIndex = 2 * _.random(3);
157 let bishop1Pos = positions[randIndex];
158 // The second bishop must be on a square of different color
159 let randIndex_tmp = 2 * _.random(3) + 1;
160 let bishop2Pos = positions[randIndex_tmp];
161 // Remove chosen squares
162 positions.splice(Math.max(randIndex,randIndex_tmp), 1);
163 positions.splice(Math.min(randIndex,randIndex_tmp), 1);
164
165 // Get random squares for knights
166 randIndex = _.random(5);
167 let knight1Pos = positions[randIndex];
168 positions.splice(randIndex, 1);
169 randIndex = _.random(4);
170 let knight2Pos = positions[randIndex];
171 positions.splice(randIndex, 1);
172
173 // Get random square for queen
174 randIndex = _.random(3);
175 let queenPos = positions[randIndex];
176 positions.splice(randIndex, 1);
177
178 // Random square for king (no castle)
179 randIndex = _.random(2);
180 let kingPos = positions[randIndex];
181 positions.splice(randIndex, 1);
182
183 // Rooks positions are now fixed
184 let rook1Pos = positions[0];
185 let rook2Pos = positions[1];
186
187 // Finally put the shuffled pieces in the board array
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 return pieces["b"].join("") +
198 "/pppppppp/8/8/8/8/PPPPPPPP/" +
199 pieces["w"].join("").toUpperCase() +
c794dbb8 200 " 0000 w"; //add flags (TODO?!)
2eef6db6 201 }
a6abf094 202}