1 import { ChessRules
} from "@/base_rules";
3 export class MonochromeRules
extends ChessRules
{
5 static get HasEnpassant() {
6 // Pawns would be on the same side
10 static get HasFlags() {
15 return [ [[4, 0], [4, 8]] ];
22 static IsGoodPosition(position
) {
23 if (position
.length
== 0) return false;
24 const rows
= position
.split("/");
25 if (rows
.length
!= V
.size
.x
) return false;
26 for (let row
of rows
) {
28 for (let i
= 0; i
< row
.length
; i
++) {
29 if (V
.PIECES
.includes(row
[i
])) sumElts
++;
31 const num
= parseInt(row
[i
], 10);
32 if (isNaN(num
)) return false;
36 if (sumElts
!= V
.size
.y
) return false;
42 return (b
[1] == V
.KNIGHT
? "Enpassant/" : "") + b
;
45 canIplay(side
, [x
, y
]) {
46 const xBounds
= side
== 'w' ? [4,7] : [0,3];
47 return this.turn
== side
&& x
>= xBounds
[0] && x
<= xBounds
[1];
50 canTake([x1
, y1
], [x2
, y2
]) {
51 // Capture in other half-board
52 return ((x1
<= 3 && x2
>= 4) || (x1
>= 4 && x2
<= 3));
55 // Trim all non-capturing moves
56 static KeepCaptures(moves
) {
57 return moves
.filter(m
=> m
.vanish
.length
== 2);
60 getPotentialKnightMoves(sq
) {
61 // Knight becomes knightrider:
62 return this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
]);
65 getPotentialKingMoves(sq
) {
68 this.getSlideNJumpMoves(sq
, V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]))
72 getAllPotentialMoves() {
73 const xBounds
= this.turn
== 'w' ? [4,7] : [0,3];
74 let potentialMoves
= [];
75 for (let i
= xBounds
[0]; i
<= xBounds
[1]; i
++) {
76 for (let j
= 0; j
< V
.size
.y
; j
++) {
77 if (this.board
[i
][j
] != V
.EMPTY
) {
78 Array
.prototype.push
.apply(
80 this.getPotentialMovesFrom([i
, j
])
85 if (potentialMoves
.some(m
=> m
.vanish
.length
== 2 && m
.appear
.length
== 1))
86 return V
.KeepCaptures(potentialMoves
);
87 return potentialMoves
;
91 const xBounds
= this.turn
== 'w' ? [4,7] : [0,3];
92 for (let i
= xBounds
[0]; i
<= xBounds
[1]; i
++) {
93 for (let j
= 0; j
< V
.size
.y
; j
++) {
95 this.board
[i
][j
] != V
.EMPTY
&&
96 this.getPotentialMovesFrom([i
, j
]).length
> 0
105 // Stop at the first capture found (if any)
106 atLeastOneCapture() {
107 const xBounds
= this.turn
== 'w' ? [4,7] : [0,3];
108 for (let i
= xBounds
[0]; i
<= xBounds
[1]; i
++) {
109 for (let j
= 0; j
< V
.size
.y
; j
++) {
111 this.board
[i
][j
] != V
.EMPTY
&&
112 this.getPotentialMovesFrom([i
, j
]).some(m
=> m
.vanish
.length
== 2)
121 getPossibleMovesFrom(sq
) {
122 let moves
= this.getPotentialMovesFrom(sq
);
123 const captureMoves
= V
.KeepCaptures(moves
);
124 if (captureMoves
.length
> 0) return captureMoves
;
125 if (this.atLeastOneCapture()) return [];
142 // Is there anything in opponent's half board?
143 const color
= V
.GetOppCol(this.turn
);
144 const xBounds
= color
== 'w' ? [4,7] : [0,3];
145 let nothingHere
= true;
146 outerLoop: for (let i
= xBounds
[0]; i
<= xBounds
[1]; i
++) {
147 for (let j
= 0; j
< V
.size
.y
; j
++) {
148 if (this.board
[i
][j
] != V
.EMPTY
) {
154 if (nothingHere
) return color
== 'w' ? "0-1" : "1-0";
155 if (this.atLeastOneMove()) return '*';
159 static GenRandInitFen(randomness
) {
160 // Remove the en-passant + castle part of the FEN
161 let fen
= ChessRules
.GenRandInitFen(randomness
).slice(0, -6);
162 // Replace kings with queens
163 fen
= fen
.replace("k", "q").replace("K", "Q");
165 fen
= fen
.replace("pppppppp/8","8/pppppppp")
166 .replace("8/PPPPPPPP","PPPPPPPP/8");
167 const firstSpace
= fen
.indexOf(' ');
170 fen
.substr(0, firstSpace
).replace(/[A-Z]/g, (c
) => c
.toLowerCase()) +
171 fen
.substr(firstSpace
);
175 static get SEARCH_DEPTH() {
181 for (let i
= 0; i
< 8; i
++) {
182 for (let j
= 0; j
< V
.size
.y
; j
++) {
183 if (this.board
[i
][j
] != V
.EMPTY
) {
184 const sign
= (i
<= 3 ? -1 : 1);
185 // I don't think taking pieces' values into account would help
186 evaluation
+= sign
; //* V.VALUES[this.getPiece(i, j)];
194 // Translate initial square (because pieces may fly unusually!)
195 const initialSquare
= V
.CoordsToSquare(move.start
);
197 // Translate final square
198 const finalSquare
= V
.CoordsToSquare(move.end
);
201 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
202 if (piece
== V
.PAWN
) {
203 // pawn move (TODO: enPassant indication)
204 if (move.vanish
.length
== 2) {
206 notation
= initialSquare
+ "x" + finalSquare
;
208 else notation
= finalSquare
;
209 if (piece
!= move.appear
[0].p
)
211 notation
+= "=" + move.appear
[0].p
.toUpperCase();
215 notation
= piece
.toUpperCase();
216 if (move.vanish
.length
> 1) notation
+= initialSquare
+ "x";
217 notation
+= finalSquare
;