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() {
16 return (b
[1] == 'p' ? "Berolina/" : "") + b
;
19 static GenRandInitFen(options
) {
20 if (options
.randomness
== 0)
21 return "krbp4/rqnp4/nbpp4/pppp4/4PPPP/4PPBN/4PNQR/4PBRK w 0";
22 let pieces
= { w: new Array(8), b: new Array(8) };
23 for (let c
of ["w", "b"]) {
24 if (c
== 'b' && options
.randomness
== 1) {
25 pieces
['b'] = pieces
['w'];
28 // Get random squares for every piece, totally freely
29 let positions
= shuffle(ArrayFun
.range(8));
30 const composition
= ['b', 'b', 'r', 'r', 'n', 'n', 'k', 'q'];
31 const rem2
= positions
[0] % 2;
32 if (rem2
== positions
[1] % 2) {
33 // Fix bishops (on different colors)
34 for (let i
=2; i
<8; i
++) {
35 if (positions
[i
] % 2 != rem2
) {
36 [positions
[1], positions
[i
]] = [positions
[i
], positions
[1]];
41 for (let i
= 0; i
< 8; i
++) pieces
[c
][positions
[i
]] = composition
[i
];
44 pieces
["b"].slice(0, 3).join("") + "p4/" +
45 pieces
["b"].slice(3, 6).join("") + "p4/" +
46 pieces
["b"].slice(6, 8).join("") + "pp4/" +
48 "4PP" + pieces
["w"].slice(6, 8).reverse().join("").toUpperCase() + "/" +
49 "4P" + pieces
["w"].slice(3, 6).reverse().join("").toUpperCase() + "/" +
50 "4P" + pieces
["w"].slice(0, 3).reverse().join("").toUpperCase() +
55 // Special pawns movements
56 getPotentialPawnMoves([x
, y
]) {
57 const color
= this.turn
;
59 const [sizeX
, sizeY
] = [V
.size
.x
, V
.size
.y
];
60 const shift
= (color
== "w" ? -1 : 1);
61 const lastRank
= (color
== "w" ? 0 : 7);
63 // One square forward (diagonally along h1-a8)
64 if (this.board
[x
+ shift
][y
+ shift
] == V
.EMPTY
) {
66 [x
+ shift
, y
+ shift
].includes(lastRank
)
67 ? [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]
69 for (let piece
of finalPieces
) {
72 [x
, y
], [x
+ shift
, y
+ shift
], { c: color
, p: piece
})
77 for (let pShift
of [[0, shift
], [shift
, 0]]) {
79 this.board
[x
+ pShift
[0]][y
+ pShift
[1]] != V
.EMPTY
&&
80 this.canTake([x
, y
], [x
+ pShift
[0], y
+ pShift
[1]])
83 [x
+ pShift
[0], y
+ pShift
[1]].includes(lastRank
)
84 ? [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]
86 for (let piece
of finalPieces
) {
90 [x
+ pShift
[0], y
+ pShift
[1]],
104 isAttackedByPawn([x
, y
], color
) {
105 let pawnShift
= (color
== "w" ? 1 : -1);
108 x
+ pawnShift
>= 0 && x
+ pawnShift
< V
.size
.x
&&
109 this.getPiece(x
+ pawnShift
, y
) == V
.PAWN
&&
110 this.getColor(x
+ pawnShift
, y
) == color
114 y
+ pawnShift
>= 0 && y
+ pawnShift
< V
.size
.y
&&
115 this.getPiece(x
, y
+ pawnShift
) == V
.PAWN
&&
116 this.getColor(x
, y
+ pawnShift
) == color
121 static get SEARCH_DEPTH() {
126 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
127 if (piece
== V
.PAWN
) {
129 const finalSquare
= V
.CoordsToSquare(move.end
);
131 if (move.vanish
.length
== 2)
133 notation
= "Px" + finalSquare
;
135 // No capture: indicate the initial square for potential ambiguity
136 const startSquare
= V
.CoordsToSquare(move.start
);
137 notation
= startSquare
+ finalSquare
;
139 if (move.appear
[0].p
!= V
.PAWN
)
141 notation
+= "=" + move.appear
[0].p
.toUpperCase();
144 return super.getNotation(move); //all other pieces are orthodox