Add TODOs
[vchess.git] / public / javascripts / variants / Loser.js
1 class LoserRules extends ChessRules
2 {
3 initVariables(fen)
4 {
5 // No castling, hence no flags
6 const epSq = this.moves.length > 0 ? this.getEpSquare(this.lastMove) : undefined;
7 this.epSquares = [ epSq ];
8 }
9
10 setFlags(fen) { }
11
12 getPotentialPawnMoves([x,y])
13 {
14 let moves = super.getPotentialPawnMoves([x,y]);
15
16 // Complete with promotion(s) into king, if possible
17 const color = this.turn;
18 const V = VariantRules;
19 const [sizeX,sizeY] = VariantRules.size;
20 const shift = (color == "w" ? -1 : 1);
21 const lastRank = (color == "w" ? 0 : sizeX-1);
22 if (x+shift == lastRank)
23 {
24 let p = V.KING;
25 // Normal move
26 if (this.board[x+shift][y] == V.EMPTY)
27 moves.push(this.getBasicMove([x,y], [x+shift,y], {c:color,p:p}));
28 // Captures
29 if (y>0 && this.canTake([x,y], [x+shift,y-1]) && this.board[x+shift][y-1] != V.EMPTY)
30 moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:color,p:p}));
31 if (y<sizeY-1 && this.canTake([x,y], [x+shift,y+1]) && this.board[x+shift][y+1] != V.EMPTY)
32 moves.push(this.getBasicMove([x,y], [x+shift,y+1], {c:color,p:p}));
33 }
34
35 return moves;
36 }
37
38 getPotentialKingMoves(sq)
39 {
40 const V = VariantRules;
41 return this.getSlideNJumpMoves(sq,
42 V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
43 }
44
45 // Stop at the first capture found (if any)
46 atLeastOneCapture()
47 {
48 const color = this.turn;
49 const oppCol = this.getOppCol(color);
50 const [sizeX,sizeY] = VariantRules.size;
51 for (let i=0; i<sizeX; i++)
52 {
53 for (let j=0; j<sizeY; j++)
54 {
55 if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) != oppCol)
56 {
57 const moves = this.getPotentialMovesFrom([i,j]);
58 if (moves.length > 0)
59 {
60 for (let k=0; k<moves.length; k++)
61 {
62 if (moves[k].vanish.length==2 && this.filterValid([moves[k]]).length > 0)
63 return true;
64 }
65 }
66 }
67 }
68 }
69 return false;
70 }
71
72 // Trim all non-capturing moves
73 static KeepCaptures(moves)
74 {
75 return moves.filter(m => { return m.vanish.length == 2; });
76 }
77
78 getPossibleMovesFrom(sq)
79 {
80 let moves = this.filterValid( this.getPotentialMovesFrom(sq) );
81 // This is called from interface: we need to know if a capture is possible
82 if (this.atLeastOneCapture())
83 moves = VariantRules.KeepCaptures(moves);
84 return moves;
85 }
86
87 getAllValidMoves()
88 {
89 let moves = super.getAllValidMoves();
90 if (moves.some(m => { return m.vanish.length == 2; }))
91 moves = VariantRules.KeepCaptures(moves);
92 return moves;
93 }
94
95 underCheck(move)
96 {
97 return false; //No notion of check
98 }
99
100 getCheckSquares(move)
101 {
102 return [];
103 }
104
105 play(move, ingame)
106 {
107 if (!!ingame)
108 move.notation = this.getNotation(move);
109 this.moves.push(move);
110 this.epSquares.push( this.getEpSquare(move) );
111 VariantRules.PlayOnBoard(this.board, move);
112 }
113
114 undo(move)
115 {
116 VariantRules.UndoOnBoard(this.board, move);
117 this.epSquares.pop();
118 this.moves.pop();
119 }
120
121 checkGameEnd()
122 {
123 // No valid move: you win!
124 return this.turn == "w" ? "1-0" : "0-1";
125 }
126
127 static get VALUES() { //experimental...
128 return {
129 'p': 1,
130 'r': 7,
131 'n': 3,
132 'b': 3,
133 'q': 5,
134 'k': 5
135 };
136 }
137
138 static get SEARCH_DEPTH() { return 4; }
139
140 evalPosition()
141 {
142 return - super.evalPosition(); //better with less material
143 }
144 }