1 import { ChessRules
} from "@/base_rules";
2 import { ArrayFun
} from "@/utils/array";
3 import { shuffle
} from "@/utils/alea";
5 export class DiamondRules
extends ChessRules
{
6 static get HasFlags() {
10 static get HasEnpassant() {
14 static GenRandInitFen(randomness
) {
16 return "krbp4/rqnp4/nbpp4/pppp4/4PPPP/4PPBN/4PNQR/4PBRK w 0";
17 let pieces
= { w: new Array(8), b: new Array(8) };
18 for (let c
of ["w", "b"]) {
19 if (c
== 'b' && randomness
== 1) {
20 pieces
['b'] = pieces
['w'];
23 // Get random squares for every piece, totally freely
24 let positions
= shuffle(ArrayFun
.range(8));
25 const composition
= ['b', 'b', 'r', 'r', 'n', 'n', 'k', 'q'];
26 const rem2
= positions
[0] % 2;
27 if (rem2
== positions
[1] % 2) {
28 // Fix bishops (on different colors)
29 for (let i
=2; i
<8; i
++) {
30 if (positions
[i
] % 2 != rem2
)
31 [positions
[1], positions
[i
]] = [positions
[i
], positions
[1]];
34 for (let i
= 0; i
< 8; i
++) pieces
[c
][positions
[i
]] = composition
[i
];
37 pieces
["b"].slice(0, 3).join("") + "p4/" +
38 pieces
["b"].slice(3, 6).join("") + "p4/" +
39 pieces
["b"].slice(6, 8).join("") + "pp4/" +
41 "4PP" + pieces
["w"].slice(6, 8).reverse().join("").toUpperCase() + "/" +
42 "4P" + pieces
["w"].slice(3, 6).reverse().join("").toUpperCase() + "/" +
43 "4P" + pieces
["w"].slice(0, 3).reverse().join("").toUpperCase() +
48 // Special pawns movements
49 getPotentialPawnMoves([x
, y
]) {
50 const color
= this.turn
;
52 const [sizeX
, sizeY
] = [V
.size
.x
, V
.size
.y
];
53 const shift
= (color
== "w" ? -1 : 1);
54 const lastRank
= (color
== "w" ? 0 : 7);
56 // One square forward (diagonally along h1-a8)
57 if (this.board
[x
+ shift
][y
+ shift
] == V
.EMPTY
) {
59 [x
+ shift
, y
+ shift
].includes(lastRank
)
60 ? [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]
62 for (let piece
of finalPieces
) {
65 [x
, y
], [x
+ shift
, y
+ shift
], { c: color
, p: piece
})
70 for (let pShift
of [[0, shift
], [shift
, 0]]) {
72 this.board
[x
+ pShift
[0]][y
+ pShift
[1]] != V
.EMPTY
&&
73 this.canTake([x
, y
], [x
+ pShift
[0], y
+ pShift
[1]])
76 [x
+ pShift
[0], y
+ pShift
[1]].includes(lastRank
)
77 ? [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]
79 for (let piece
of finalPieces
) {
83 [x
+ pShift
[0], y
+ pShift
[1]],
97 isAttackedByPawn([x
, y
], color
) {
98 let pawnShift
= (color
== "w" ? 1 : -1);
101 x
+ pawnShift
>= 0 && x
+ pawnShift
< V
.size
.x
&&
102 this.getPiece(x
+ pawnShift
, y
) == V
.PAWN
&&
103 this.getColor(x
+ pawnShift
, y
) == color
107 y
+ pawnShift
>= 0 && y
+ pawnShift
< V
.size
.y
&&
108 this.getPiece(x
, y
+ pawnShift
) == V
.PAWN
&&
109 this.getColor(x
, y
+ pawnShift
) == color
114 static get SEARCH_DEPTH() {
119 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
120 if (piece
== V
.PAWN
) {
122 const finalSquare
= V
.CoordsToSquare(move.end
);
124 if (move.vanish
.length
== 2)
126 notation
= "Px" + finalSquare
;
128 // No capture: indicate the initial square for potential ambiguity
129 const startSquare
= V
.CoordsToSquare(move.start
);
130 notation
= startSquare
+ finalSquare
;
132 if (move.appear
[0].p
!= V
.PAWN
)
134 notation
+= "=" + move.appear
[0].p
.toUpperCase();
137 return super.getNotation(move); //all other pieces are orthodox