1 import { ChessRules
} from "@/base_rules";
2 import { ArrayFun
} from "@/utils/array";
3 import { shuffle
} from "@/utils/alea";
5 export class DiamondRules
extends ChessRules
{
7 static get HasFlags() {
11 static get HasEnpassant() {
15 static GenRandInitFen(randomness
) {
17 return "krbp4/rqnp4/nbpp4/pppp4/4PPPP/4PPBN/4PNQR/4PBRK w 0";
18 let pieces
= { w: new Array(8), b: new Array(8) };
19 for (let c
of ["w", "b"]) {
20 if (c
== 'b' && randomness
== 1) {
21 pieces
['b'] = pieces
['w'];
24 // Get random squares for every piece, totally freely
25 let positions
= shuffle(ArrayFun
.range(8));
26 const composition
= ['b', 'b', 'r', 'r', 'n', 'n', 'k', 'q'];
27 const rem2
= positions
[0] % 2;
28 if (rem2
== positions
[1] % 2) {
29 // Fix bishops (on different colors)
30 for (let i
=2; i
<8; i
++) {
31 if (positions
[i
] % 2 != rem2
)
32 [positions
[1], positions
[i
]] = [positions
[i
], positions
[1]];
35 for (let i
= 0; i
< 8; i
++) pieces
[c
][positions
[i
]] = composition
[i
];
38 pieces
["b"].slice(0, 3).join("") + "p4/" +
39 pieces
["b"].slice(3, 6).join("") + "p4/" +
40 pieces
["b"].slice(6, 8).join("") + "pp4/" +
42 "4PP" + pieces
["w"].slice(6, 8).reverse().join("").toUpperCase() + "/" +
43 "4P" + pieces
["w"].slice(3, 6).reverse().join("").toUpperCase() + "/" +
44 "4P" + pieces
["w"].slice(0, 3).reverse().join("").toUpperCase() +
49 // Special pawns movements
50 getPotentialPawnMoves([x
, y
]) {
51 const color
= this.turn
;
53 const [sizeX
, sizeY
] = [V
.size
.x
, V
.size
.y
];
54 const shift
= (color
== "w" ? -1 : 1);
55 const lastRank
= (color
== "w" ? 0 : 7);
57 // One square forward (diagonally along h1-a8)
58 if (this.board
[x
+ shift
][y
+ shift
] == V
.EMPTY
) {
60 [x
+ shift
, y
+ shift
].includes(lastRank
)
61 ? [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]
63 for (let piece
of finalPieces
) {
66 [x
, y
], [x
+ shift
, y
+ shift
], { c: color
, p: piece
})
71 for (let pShift
of [[0, shift
], [shift
, 0]]) {
73 this.board
[x
+ pShift
[0]][y
+ pShift
[1]] != V
.EMPTY
&&
74 this.canTake([x
, y
], [x
+ pShift
[0], y
+ pShift
[1]])
77 [x
+ pShift
[0], y
+ pShift
[1]].includes(lastRank
)
78 ? [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]
80 for (let piece
of finalPieces
) {
84 [x
+ pShift
[0], y
+ pShift
[1]],
98 isAttackedByPawn([x
, y
], color
) {
99 let pawnShift
= (color
== "w" ? 1 : -1);
102 x
+ pawnShift
>= 0 && x
+ pawnShift
< V
.size
.x
&&
103 this.getPiece(x
+ pawnShift
, y
) == V
.PAWN
&&
104 this.getColor(x
+ pawnShift
, y
) == color
108 y
+ pawnShift
>= 0 && y
+ pawnShift
< V
.size
.y
&&
109 this.getPiece(x
, y
+ pawnShift
) == V
.PAWN
&&
110 this.getColor(x
, y
+ pawnShift
) == color
115 static get SEARCH_DEPTH() {
120 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
121 if (piece
== V
.PAWN
) {
123 const finalSquare
= V
.CoordsToSquare(move.end
);
125 if (move.vanish
.length
== 2)
127 notation
= "Px" + finalSquare
;
129 // No capture: indicate the initial square for potential ambiguity
130 const startSquare
= V
.CoordsToSquare(move.start
);
131 notation
= startSquare
+ finalSquare
;
133 if (move.appear
[0].p
!= V
.PAWN
)
135 notation
+= "=" + move.appear
[0].p
.toUpperCase();
138 return super.getNotation(move); //all other pieces are orthodox