Pandemonium 1 & 2, Stealthbomb 1 & 2
[vchess.git] / client / src / variants / Diamond.js
1 import { ChessRules } from "@/base_rules";
2 import { ArrayFun } from "@/utils/array";
3 import { shuffle } from "@/utils/alea";
4
5 export class DiamondRules extends ChessRules {
6
7 static get HasFlags() {
8 return false;
9 }
10
11 static get HasEnpassant() {
12 return false;
13 }
14
15 static GenRandInitFen(randomness) {
16 if (randomness == 0)
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'];
22 break;
23 }
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]];
33 break;
34 }
35 }
36 }
37 for (let i = 0; i < 8; i++) pieces[c][positions[i]] = composition[i];
38 }
39 return (
40 pieces["b"].slice(0, 3).join("") + "p4/" +
41 pieces["b"].slice(3, 6).join("") + "p4/" +
42 pieces["b"].slice(6, 8).join("") + "pp4/" +
43 "pppp4/4PPPP/" +
44 "4PP" + pieces["w"].slice(6, 8).reverse().join("").toUpperCase() + "/" +
45 "4P" + pieces["w"].slice(3, 6).reverse().join("").toUpperCase() + "/" +
46 "4P" + pieces["w"].slice(0, 3).reverse().join("").toUpperCase() +
47 " w 0"
48 );
49 }
50
51 // Special pawns movements
52 getPotentialPawnMoves([x, y]) {
53 const color = this.turn;
54 let moves = [];
55 const [sizeX, sizeY] = [V.size.x, V.size.y];
56 const shift = (color == "w" ? -1 : 1);
57 const lastRank = (color == "w" ? 0 : 7);
58
59 // One square forward (diagonally along h1-a8)
60 if (this.board[x + shift][y + shift] == V.EMPTY) {
61 const finalPieces =
62 [x + shift, y + shift].includes(lastRank)
63 ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]
64 : [V.PAWN];
65 for (let piece of finalPieces) {
66 moves.push(
67 this.getBasicMove(
68 [x, y], [x + shift, y + shift], { c: color, p: piece })
69 );
70 }
71 }
72 // Capture
73 for (let pShift of [[0, shift], [shift, 0]]) {
74 if (
75 this.board[x + pShift[0]][y + pShift[1]] != V.EMPTY &&
76 this.canTake([x, y], [x + pShift[0], y + pShift[1]])
77 ) {
78 const finalPieces =
79 [x + pShift[0], y + pShift[1]].includes(lastRank)
80 ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]
81 : [V.PAWN];
82 for (let piece of finalPieces) {
83 moves.push(
84 this.getBasicMove(
85 [x, y],
86 [x + pShift[0], y + pShift[1]],
87 {
88 c: color,
89 p: piece
90 }
91 )
92 );
93 }
94 }
95 }
96
97 return moves;
98 }
99
100 isAttackedByPawn([x, y], color) {
101 let pawnShift = (color == "w" ? 1 : -1);
102 return (
103 (
104 x + pawnShift >= 0 && x + pawnShift < V.size.x &&
105 this.getPiece(x + pawnShift, y) == V.PAWN &&
106 this.getColor(x + pawnShift, y) == color
107 )
108 ||
109 (
110 y + pawnShift >= 0 && y + pawnShift < V.size.y &&
111 this.getPiece(x, y + pawnShift) == V.PAWN &&
112 this.getColor(x, y + pawnShift) == color
113 )
114 );
115 }
116
117 static get SEARCH_DEPTH() {
118 return 2;
119 }
120
121 getNotation(move) {
122 const piece = this.getPiece(move.start.x, move.start.y);
123 if (piece == V.PAWN) {
124 // Pawn move
125 const finalSquare = V.CoordsToSquare(move.end);
126 let notation = "";
127 if (move.vanish.length == 2)
128 // Capture
129 notation = "Px" + finalSquare;
130 else {
131 // No capture: indicate the initial square for potential ambiguity
132 const startSquare = V.CoordsToSquare(move.start);
133 notation = startSquare + finalSquare;
134 }
135 if (move.appear[0].p != V.PAWN)
136 // Promotion
137 notation += "=" + move.appear[0].p.toUpperCase();
138 return notation;
139 }
140 return super.getNotation(move); //all other pieces are orthodox
141 }
142
143 };