Commit | Line | Data |
---|---|---|
0c3fe8a6 BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | ||
3 | export const VariantRules = class ExtinctionRules extends ChessRules | |
a6abf094 | 4 | { |
dac39588 BA |
5 | setOtherVariables(fen) |
6 | { | |
7 | super.setOtherVariables(fen); | |
8 | const pos = V.ParseFen(fen).position; | |
9 | // NOTE: no need for safety "|| []", because each piece type must be present | |
10 | // (otherwise game is already over!) | |
11 | this.material = | |
12 | { | |
13 | "w": | |
14 | { | |
15 | [V.KING]: pos.match(/K/g).length, | |
16 | [V.QUEEN]: pos.match(/Q/g).length, | |
17 | [V.ROOK]: pos.match(/R/g).length, | |
18 | [V.KNIGHT]: pos.match(/N/g).length, | |
19 | [V.BISHOP]: pos.match(/B/g).length, | |
20 | [V.PAWN]: pos.match(/P/g).length | |
21 | }, | |
22 | "b": | |
23 | { | |
24 | [V.KING]: pos.match(/k/g).length, | |
25 | [V.QUEEN]: pos.match(/q/g).length, | |
26 | [V.ROOK]: pos.match(/r/g).length, | |
27 | [V.KNIGHT]: pos.match(/n/g).length, | |
28 | [V.BISHOP]: pos.match(/b/g).length, | |
29 | [V.PAWN]: pos.match(/p/g).length | |
30 | } | |
31 | }; | |
32 | } | |
a6abf094 | 33 | |
dac39588 BA |
34 | getPotentialPawnMoves([x,y]) |
35 | { | |
36 | let moves = super.getPotentialPawnMoves([x,y]); | |
37 | // Add potential promotions into king | |
38 | const color = this.turn; | |
39 | const shift = (color == "w" ? -1 : 1); | |
40 | const lastRank = (color == "w" ? 0 : V.size.x-1); | |
1221ac47 | 41 | |
dac39588 BA |
42 | if (x+shift == lastRank) |
43 | { | |
44 | // Normal move | |
45 | if (this.board[x+shift][y] == V.EMPTY) | |
46 | moves.push(this.getBasicMove([x,y], [x+shift,y], {c:color,p:V.KING})); | |
47 | // Captures | |
48 | if (y>0 && this.board[x+shift][y-1] != V.EMPTY | |
49 | && this.canTake([x,y], [x+shift,y-1])) | |
50 | { | |
51 | moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:color,p:V.KING})); | |
52 | } | |
53 | if (y<V.size.y-1 && this.board[x+shift][y+1] != V.EMPTY | |
54 | && this.canTake([x,y], [x+shift,y+1])) | |
55 | { | |
56 | moves.push(this.getBasicMove([x,y], [x+shift,y+1], {c:color,p:V.KING})); | |
57 | } | |
58 | } | |
1221ac47 | 59 | |
dac39588 BA |
60 | return moves; |
61 | } | |
1221ac47 | 62 | |
dac39588 BA |
63 | // TODO: verify this assertion |
64 | atLeastOneMove() | |
65 | { | |
66 | return true; //always at least one possible move | |
67 | } | |
a6abf094 | 68 | |
dac39588 BA |
69 | underCheck(color) |
70 | { | |
71 | return false; //there is no check | |
72 | } | |
a6abf094 | 73 | |
dac39588 BA |
74 | getCheckSquares(color) |
75 | { | |
76 | return []; | |
77 | } | |
a6abf094 | 78 | |
dac39588 BA |
79 | updateVariables(move) |
80 | { | |
81 | super.updateVariables(move); | |
82 | // Treat the promotion case: (not the capture part) | |
83 | if (move.appear[0].p != move.vanish[0].p) | |
84 | { | |
85 | this.material[move.appear[0].c][move.appear[0].p]++; | |
86 | this.material[move.appear[0].c][V.PAWN]--; | |
87 | } | |
88 | if (move.vanish.length==2 && move.appear.length==1) //capture | |
89 | this.material[move.vanish[1].c][move.vanish[1].p]--; | |
90 | } | |
a6abf094 | 91 | |
dac39588 BA |
92 | unupdateVariables(move) |
93 | { | |
94 | super.unupdateVariables(move); | |
95 | if (move.appear[0].p != move.vanish[0].p) | |
96 | { | |
97 | this.material[move.appear[0].c][move.appear[0].p]--; | |
98 | this.material[move.appear[0].c][V.PAWN]++; | |
99 | } | |
100 | if (move.vanish.length==2 && move.appear.length==1) | |
101 | this.material[move.vanish[1].c][move.vanish[1].p]++; | |
102 | } | |
a6abf094 | 103 | |
dac39588 BA |
104 | getCurrentScore() |
105 | { | |
106 | if (this.atLeastOneMove()) // game not over? | |
107 | { | |
108 | const color = this.turn; | |
109 | if (Object.keys(this.material[color]).some( | |
110 | p => { return this.material[color][p] == 0; })) | |
111 | { | |
112 | return (this.turn == "w" ? "0-1" : "1-0"); | |
113 | } | |
114 | return "*"; | |
115 | } | |
a6abf094 | 116 | |
dac39588 BA |
117 | return (this.turn == "w" ? "0-1" : "1-0"); //NOTE: currently unreachable... |
118 | } | |
a6abf094 | 119 | |
dac39588 BA |
120 | evalPosition() |
121 | { | |
122 | const color = this.turn; | |
123 | if (Object.keys(this.material[color]).some( | |
124 | p => { return this.material[color][p] == 0; })) | |
125 | { | |
126 | // Very negative (resp. positive) if white (reps. black) pieces set is incomplete | |
127 | return (color=="w"?-1:1) * V.INFINITY; | |
128 | } | |
129 | return super.evalPosition(); | |
130 | } | |
a6abf094 | 131 | } |