Various bug fixes
[xogo.git] / variants / Bicolour / class.js
1 import ChessRules from "/base_rules.js";
2 import {Random} from "/utils/alea.js";
3 import {ArrayFun} from "/utils/array.js";
4
5 export default class BicolourRules extends ChessRules {
6
7 static get Options() {
8 return {
9 select: C.Options.select,
10 input: [
11 {
12 label: "King takes all",
13 variable: "takeboth",
14 type: "checkbox",
15 defaut: true
16 },
17 {
18 label: "Capture king",
19 variable: "taking",
20 type: "checkbox",
21 defaut: false
22 }
23 ],
24 styles: ["balance", "capture", "cylinder", "dark",
25 "doublemove", "madrasi", "progressive", "zen"]
26 };
27 }
28
29 get hasFlags() {
30 return false;
31 }
32
33 canTake([x1, y1], [x2, y2]) {
34 return (
35 this.getPiece(x2, y2) == 'k' ||
36 (this.getPiece(x1, y1) == 'k' && this.options["takeboth"]) ||
37 super.canTake([x1, y1], [x2, y2])
38 );
39 }
40
41 genRandInitBaseFen() {
42 if (this.options["randomness"] == 0)
43 return { fen: "rqbnkbnr/pppppppp/8/8/8/8/PPPPPPPP/RQBNKBNR", o: {} };
44
45 // Place pieces at random but the king cannot be next to a rook or queen.
46 // => One bishop and one knight should surround the king.
47 let pieces = {w: new Array(8), b: new Array(8)};
48 let flags = "";
49 for (let c of ["w", "b"]) {
50 if (c == 'b' && this.options["randomness"] == 1) {
51 pieces['b'] = pieces['w'];
52 break;
53 }
54 let positions = ArrayFun.range(8);
55 const kingPos = randInt(8);
56 let toRemove = [kingPos];
57 let knight1Pos = undefined;
58 let bishop1Pos = undefined;
59 if (kingPos == 0) {
60 if (Random.randBool())
61 knight1Pos = 1;
62 else
63 bishop1Pos = 1;
64 toRemove.push(1);
65 }
66 else if (kingPos == V.size.y - 1) {
67 if (Random.randBool())
68 knight1Pos = V.size.y - 2;
69 else
70 bishop1Pos = V.size.y - 2;
71 toRemove.push(V.size.y - 2);
72 }
73 else {
74 knight1Pos = kingPos + (Random.randBool() ? 1 : -1);
75 bishop1Pos = kingPos + (knight1Pos < kingPos ? 1 : -1);
76 toRemove.push(knight1Pos, bishop1Pos);
77 }
78 const firstPieces = [kingPos, knight1Pos, bishop1Pos]
79 .filter(elt => elt !== undefined);
80 firstPieces
81 .sort((a, b) => b - a)
82 .forEach(elt => positions.splice(elt, 1));
83 let randIndex = undefined;
84 if (bishop1Pos === undefined) {
85 const posWithIdx = positions.map((e,i) => { return {e: e, i: i}; });
86 let availableSquares = posWithIdx.filter(p => p.e % 2 == 0);
87 randIndex = randInt(availableSquares.length);
88 bishop1Pos = availableSquares[randIndex].e;
89 positions.splice(availableSquares[randIndex].i, 1);
90 }
91 const posWithIdx = positions.map((e,i) => { return {e: e, i: i}; });
92 const rem1B = bishop1Pos % 2;
93 let availableSquares = posWithIdx.filter(p => p.e % 2 == 1 - rem1B);
94 randIndex = randInt(availableSquares.length);
95 const bishop2Pos = availableSquares[randIndex].e;
96 positions.splice(availableSquares[randIndex].i, 1);
97 if (knight1Pos === undefined) {
98 randIndex = randInt(5);
99 knight1Pos = positions[randIndex];
100 positions.splice(randIndex, 1);
101 }
102 randIndex = randInt(4);
103 const knight2Pos = positions[randIndex];
104 positions.splice(randIndex, 1);
105 randIndex = randInt(3);
106 const queenPos = positions[randIndex];
107 positions.splice(randIndex, 1);
108 const rook1Pos = positions[0];
109 const rook2Pos = positions[1];
110 pieces[c][rook1Pos] = "r";
111 pieces[c][knight1Pos] = "n";
112 pieces[c][bishop1Pos] = "b";
113 pieces[c][queenPos] = "q";
114 pieces[c][kingPos] = "k";
115 pieces[c][bishop2Pos] = "b";
116 pieces[c][knight2Pos] = "n";
117 pieces[c][rook2Pos] = "r";
118 }
119
120 return {
121 fen: (
122 pieces["b"].join("") +
123 "/pppppppp/8/8/8/8/PPPPPPPP/" +
124 pieces["w"].join("").toUpperCase()
125 ),
126 o: {}
127 };
128 }
129
130 underCheck(square_s) {
131 return super.underCheck(square_s, ['w', 'b']);
132 }
133
134 };