'update'
[vchess.git] / client / src / variants / Extinction.js
CommitLineData
0c3fe8a6
BA
1import { ChessRules } from "@/base_rules";
2
32f6285e 3export class ExtinctionRules extends ChessRules {
7e8a7ea1 4
32f6285e
BA
5 static get PawnSpecs() {
6 return Object.assign(
7 {},
8 ChessRules.PawnSpecs,
9 { promotions: ChessRules.PawnSpecs.promotions.concat([V.KING]) }
10 );
11 }
12
d7c00f6a 13 static IsGoodPosition(position) {
6f2f9437 14 if (!ChessRules.IsGoodPosition(position)) return false;
d7c00f6a
BA
15 // Also check that each piece type is present
16 const rows = position.split("/");
17 let pieces = {};
18 for (let row of rows) {
19 for (let i = 0; i < row.length; i++) {
e50a8025 20 if (isNaN(parseInt(row[i], 10)) && !pieces[row[i]])
d7c00f6a
BA
21 pieces[row[i]] = true;
22 }
23 }
6f2f9437 24 if (Object.keys(pieces).length != 12) return false;
d7c00f6a
BA
25 return true;
26 }
27
6808d7a1 28 setOtherVariables(fen) {
dac39588
BA
29 super.setOtherVariables(fen);
30 const pos = V.ParseFen(fen).position;
2c5d7b20 31 // NOTE: no need for safety "|| []", because each piece type is present
dac39588 32 // (otherwise game is already over!)
6808d7a1
BA
33 this.material = {
34 w: {
dac39588
BA
35 [V.KING]: pos.match(/K/g).length,
36 [V.QUEEN]: pos.match(/Q/g).length,
37 [V.ROOK]: pos.match(/R/g).length,
38 [V.KNIGHT]: pos.match(/N/g).length,
39 [V.BISHOP]: pos.match(/B/g).length,
40 [V.PAWN]: pos.match(/P/g).length
41 },
6808d7a1 42 b: {
dac39588
BA
43 [V.KING]: pos.match(/k/g).length,
44 [V.QUEEN]: pos.match(/q/g).length,
45 [V.ROOK]: pos.match(/r/g).length,
46 [V.KNIGHT]: pos.match(/n/g).length,
47 [V.BISHOP]: pos.match(/b/g).length,
48 [V.PAWN]: pos.match(/p/g).length
49 }
50 };
51 }
a6abf094 52
dac39588 53 // TODO: verify this assertion
6808d7a1 54 atLeastOneMove() {
dac39588
BA
55 return true; //always at least one possible move
56 }
a6abf094 57
6b7b2cf7
BA
58 filterValid(moves) {
59 return moves; //there is no check
dac39588 60 }
a6abf094 61
6808d7a1 62 getCheckSquares() {
dac39588
BA
63 return [];
64 }
a6abf094 65
3a2a7b5f
BA
66 postPlay(move) {
67 super.postPlay(move);
dac39588 68 // Treat the promotion case: (not the capture part)
6808d7a1 69 if (move.appear[0].p != move.vanish[0].p) {
dac39588
BA
70 this.material[move.appear[0].c][move.appear[0].p]++;
71 this.material[move.appear[0].c][V.PAWN]--;
72 }
6808d7a1
BA
73 if (move.vanish.length == 2 && move.appear.length == 1)
74 //capture
dac39588
BA
75 this.material[move.vanish[1].c][move.vanish[1].p]--;
76 }
a6abf094 77
3a2a7b5f
BA
78 postUndo(move) {
79 super.postUndo(move);
6808d7a1 80 if (move.appear[0].p != move.vanish[0].p) {
dac39588
BA
81 this.material[move.appear[0].c][move.appear[0].p]--;
82 this.material[move.appear[0].c][V.PAWN]++;
83 }
6808d7a1 84 if (move.vanish.length == 2 && move.appear.length == 1)
dac39588
BA
85 this.material[move.vanish[1].c][move.vanish[1].p]++;
86 }
a6abf094 87
6808d7a1
BA
88 getCurrentScore() {
89 if (this.atLeastOneMove()) {
6b7b2cf7 90 // Game not over?
dac39588 91 const color = this.turn;
6808d7a1
BA
92 if (
93 Object.keys(this.material[color]).some(p => {
94 return this.material[color][p] == 0;
95 })
96 ) {
97 return this.turn == "w" ? "0-1" : "1-0";
dac39588
BA
98 }
99 return "*";
100 }
6808d7a1 101 return this.turn == "w" ? "0-1" : "1-0"; //NOTE: currently unreachable...
dac39588 102 }
a6abf094 103
6808d7a1 104 evalPosition() {
dac39588 105 const color = this.turn;
6808d7a1
BA
106 if (
107 Object.keys(this.material[color]).some(p => {
108 return this.material[color][p] == 0;
109 })
110 ) {
2c5d7b20
BA
111 // Very negative (resp. positive)
112 // if white (reps. black) pieces set is incomplete
6808d7a1 113 return (color == "w" ? -1 : 1) * V.INFINITY;
dac39588
BA
114 }
115 return super.evalPosition();
116 }
7e8a7ea1 117
6808d7a1 118};