Fix king tracking in Fusion variant
[vchess.git] / client / src / variants / Bicolour.js
CommitLineData
107dc1bd
BA
1import { ChessRules } from "@/base_rules";
2import { randInt } from "@/utils/alea";
3import { ArrayFun } from "@/utils/array";
4
5export class BicolourRules extends ChessRules {
7e8a7ea1 6
107dc1bd
BA
7 static get HasFlags() {
8 return false;
9 }
10
11 canTake([x1, y1], [x2, y2]) {
12 return (
13 this.getPiece(x1, y1) == V.KING || super.canTake([x1, y1], [x2, y2])
14 );
15 }
16
17 static GenRandInitFen(randomness) {
18 if (randomness == 0)
19 return "rqbnkbnr/pppppppp/8/8/8/8/PPPPPPPP/RQBNKBNR w 0 -";
20
21 // Place pieces at random but the king cannot be next to a rook or queen.
22 // => One bishop and one knight should surround the king.
23 let pieces = { w: new Array(8), b: new Array(8) };
24 let flags = "";
25 for (let c of ["w", "b"]) {
26 if (c == 'b' && randomness == 1) {
27 pieces['b'] = pieces['w'];
28 break;
29 }
30
31 let positions = ArrayFun.range(8);
32
33 const kingPos = randInt(8);
34 let toRemove = [kingPos];
35 let knight1Pos = undefined;
36 let bishop1Pos = undefined;
37 if (kingPos == 0) {
38 if (Math.random() < 0.5) knight1Pos = 1;
39 else bishop1Pos = 1;
40 toRemove.push(1);
41 }
42 else if (kingPos == V.size.y - 1) {
43 if (Math.random() < 0.5) knight1Pos = V.size.y - 2;
44 else bishop1Pos = V.size.y - 2;
45 toRemove.push(V.size.y - 2);
46 }
47 else {
48 knight1Pos = kingPos + (Math.random() < 0.5 ? 1 : -1);
49 bishop1Pos = kingPos + (knight1Pos < kingPos ? 1 : -1);
50 toRemove.push(knight1Pos, bishop1Pos);
51 }
52 const firstPieces = [kingPos, knight1Pos, bishop1Pos]
53 .filter(elt => elt !== undefined);
54 firstPieces
55 .sort((a, b) => b - a)
56 .forEach(elt => positions.splice(elt, 1));
57
58 let randIndex = undefined;
59 if (bishop1Pos === undefined) {
60 const posWithIdx = positions.map((e,i) => { return { e: e, i: i }; });
61 let availableSquares = posWithIdx.filter(p => p.e % 2 == 0);
62 randIndex = randInt(availableSquares.length);
63 bishop1Pos = availableSquares[randIndex].e;
64 positions.splice(availableSquares[randIndex].i, 1);
65 }
66 const posWithIdx = positions.map((e,i) => { return { e: e, i: i }; });
67 const rem1B = bishop1Pos % 2;
68 let availableSquares = posWithIdx.filter(p => p.e % 2 == 1 - rem1B);
69 randIndex = randInt(availableSquares.length);
70 const bishop2Pos = availableSquares[randIndex].e;
71 positions.splice(availableSquares[randIndex].i, 1);
72
73 if (knight1Pos === undefined) {
74 randIndex = randInt(5);
75 knight1Pos = positions[randIndex];
76 positions.splice(randIndex, 1);
77 }
78 randIndex = randInt(4);
79 const knight2Pos = positions[randIndex];
80 positions.splice(randIndex, 1);
81
82 randIndex = randInt(3);
83 const queenPos = positions[randIndex];
84 positions.splice(randIndex, 1);
85
86 const rook1Pos = positions[0];
87 const rook2Pos = positions[1];
88
89 pieces[c][rook1Pos] = "r";
90 pieces[c][knight1Pos] = "n";
91 pieces[c][bishop1Pos] = "b";
92 pieces[c][queenPos] = "q";
93 pieces[c][kingPos] = "k";
94 pieces[c][bishop2Pos] = "b";
95 pieces[c][knight2Pos] = "n";
96 pieces[c][rook2Pos] = "r";
97 }
98 return (
99 pieces["b"].join("") +
100 "/pppppppp/8/8/8/8/PPPPPPPP/" +
101 pieces["w"].join("").toUpperCase() +
102 " w 0 -"
103 );
104 }
105
106 underCheck(color) {
107 return (
108 this.isAttacked(this.kingPos[color], 'w') ||
109 this.isAttacked(this.kingPos[color], 'b')
110 );
111 }
7e8a7ea1 112
107dc1bd 113};