5bd2ce00ecdef8e9e09de386ec552f3766de1446
[vchess.git] / client / src / variants / Monochrome.js
1 import { ChessRules } from "@/base_rules";
2
3 export class MonochromeRules extends ChessRules {
4 static get HasEnpassant() {
5 // Pawns would be on the same side
6 return false;
7 }
8
9 get showFirstTurn() {
10 return true;
11 }
12
13 static IsGoodPosition(position) {
14 if (position.length == 0) return false;
15 const rows = position.split("/");
16 if (rows.length != V.size.x) return false;
17 for (let row of rows) {
18 let sumElts = 0;
19 for (let i = 0; i < row.length; i++) {
20 if (V.PIECES.includes(row[i])) sumElts++;
21 else {
22 const num = parseInt(row[i]);
23 if (isNaN(num)) return false;
24 sumElts += num;
25 }
26 }
27 if (sumElts != V.size.y) return false;
28 }
29 return true;
30 }
31
32 canIplay(side, [x, y]) {
33 const xBounds = side == 'w' ? [4,7] : [0,3];
34 return this.turn == side && x >= xBounds[0] && x <= xBounds[1];
35 }
36
37 canTake([x1, y1], [x2, y2]) {
38 // Capture in other half-board
39 return ((x1 <= 3 && x2 >= 4) || (x1 >= 4 && x2 <= 3));
40 }
41
42 // Trim all non-capturing moves
43 static KeepCaptures(moves) {
44 return moves.filter(m => m.vanish.length == 2 && m.appear.length == 1);
45 }
46
47 getAllPotentialMoves() {
48 const xBounds = this.turn == 'w' ? [4,7] : [0,3];
49 let potentialMoves = [];
50 for (let i = xBounds[0]; i <= xBounds[1]; i++) {
51 for (let j = 0; j < V.size.y; j++) {
52 if (this.board[i][j] != V.EMPTY) {
53 Array.prototype.push.apply(
54 potentialMoves,
55 this.getPotentialMovesFrom([i, j])
56 );
57 }
58 }
59 }
60 if (potentialMoves.some(m => m.vanish.length == 2 && m.appear.length == 1))
61 return V.KeepCaptures(potentialMoves);
62 return potentialMoves;
63 }
64
65 atLeastOneMove() {
66 const xBounds = this.turn == 'w' ? [4,7] : [0,3];
67 for (let i = xBounds[0]; i <= xBounds[1]; i++) {
68 for (let j = 0; j < V.size.y; j++) {
69 if (
70 this.board[i][j] != V.EMPTY &&
71 this.getPotentialMovesFrom([i, j]).length > 0
72 ) {
73 return true;
74 }
75 }
76 }
77 return false;
78 }
79
80 // Stop at the first capture found (if any)
81 atLeastOneCapture() {
82 const xBounds = this.turn == 'w' ? [4,7] : [0,3];
83 for (let i = xBounds[0]; i <= xBounds[1]; i++) {
84 for (let j = 0; j < V.size.y; j++) {
85 if (
86 this.board[i][j] != V.EMPTY &&
87 this.getPotentialMovesFrom([i, j]).some(m =>
88 // Warning: discard castle moves
89 m.vanish.length == 2 && m.appear.length == 1)
90 ) {
91 return true;
92 }
93 }
94 }
95 return false;
96 }
97
98 getPossibleMovesFrom(sq) {
99 let moves = this.getPotentialMovesFrom(sq);
100 const captureMoves = V.KeepCaptures(moves);
101 if (captureMoves.length > 0) return captureMoves;
102 if (this.atLeastOneCapture()) return [];
103 return moves;
104 }
105
106 filterValid(moves) {
107 return moves;
108 }
109
110 isAttacked() {
111 return false;
112 }
113
114 getCheckSquares() {
115 return [];
116 }
117
118 getCurrentScore() {
119 // Is there anything in my half board?
120 const color = V.GetOppCol(this.turn);
121 const xBounds = color == 'w' ? [4,7] : [0,3];
122 let nothingHere = true;
123 outerLoop: for (let i = xBounds[0]; i <= xBounds[1]; i++) {
124 for (let j = 0; j < V.size.y; j++) {
125 if (this.board[i][j] != V.EMPTY) {
126 nothingHere = false;
127 break outerLoop;
128 }
129 }
130 }
131 if (nothingHere) return color == 'w' ? "0-1" : "1-0";
132 if (this.atLeastOneMove()) return '*';
133 return "1/2";
134 }
135
136 static GenRandInitFen(randomness) {
137 // Remove the en-passant part of the FEN
138 const fen = ChessRules.GenRandInitFen(randomness).slice(0, -2);
139 const firstSpace = fen.indexOf(' ');
140 return (
141 fen.substr(0, firstSpace).replace(/[A-Z]/g, (c) => c.toLowerCase()) +
142 fen.substr(firstSpace)
143 );
144 }
145
146 static get SEARCH_DEPTH() {
147 return 4;
148 }
149
150 evalPosition() {
151 let evaluation = 0;
152 for (let i = 0; i < 8; i++) {
153 for (let j = 0; j < V.size.y; j++) {
154 if (this.board[i][j] != V.EMPTY) {
155 const sign = (i <= 3 ? -1 : 1);
156 // I don't think taking pieces' values into account would help
157 evaluation += sign; //* V.VALUES[this.getPiece(i, j)];
158 }
159 }
160 }
161 return evaluation;
162 }
163 };