3812d4cc62e475f499e3b06003e03d0bc5eabd8e
[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 get hasFlags() {
8 return false;
9 }
10
11 canTake([x1, y1], [x2, y2]) {
12 return (this.getPiece(x2, y2) == 'k' || super.canTake([x1, y1], [x2, y2]));
13 }
14
15 genRandInitBaseFen() {
16 if (this.options["randomness"] == 0)
17 return { fen: "rqbnkbnr/pppppppp/8/8/8/8/PPPPPPPP/RQBNKBNR", o: {} };
18
19 // Place pieces at random but the king cannot be next to a rook or queen.
20 // => One bishop and one knight should surround the king.
21 let pieces = {w: new Array(8), b: new Array(8)};
22 let flags = "";
23 for (let c of ["w", "b"]) {
24 if (c == 'b' && this.options["randomness"] == 1) {
25 pieces['b'] = pieces['w'];
26 break;
27 }
28 let positions = ArrayFun.range(8);
29 const kingPos = randInt(8);
30 let toRemove = [kingPos];
31 let knight1Pos = undefined;
32 let bishop1Pos = undefined;
33 if (kingPos == 0) {
34 if (Random.randBool())
35 knight1Pos = 1;
36 else
37 bishop1Pos = 1;
38 toRemove.push(1);
39 }
40 else if (kingPos == V.size.y - 1) {
41 if (Random.randBool())
42 knight1Pos = V.size.y - 2;
43 else
44 bishop1Pos = V.size.y - 2;
45 toRemove.push(V.size.y - 2);
46 }
47 else {
48 knight1Pos = kingPos + (Random.randBool() ? 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 let randIndex = undefined;
58 if (bishop1Pos === undefined) {
59 const posWithIdx = positions.map((e,i) => { return {e: e, i: i}; });
60 let availableSquares = posWithIdx.filter(p => p.e % 2 == 0);
61 randIndex = randInt(availableSquares.length);
62 bishop1Pos = availableSquares[randIndex].e;
63 positions.splice(availableSquares[randIndex].i, 1);
64 }
65 const posWithIdx = positions.map((e,i) => { return {e: e, i: i}; });
66 const rem1B = bishop1Pos % 2;
67 let availableSquares = posWithIdx.filter(p => p.e % 2 == 1 - rem1B);
68 randIndex = randInt(availableSquares.length);
69 const bishop2Pos = availableSquares[randIndex].e;
70 positions.splice(availableSquares[randIndex].i, 1);
71 if (knight1Pos === undefined) {
72 randIndex = randInt(5);
73 knight1Pos = positions[randIndex];
74 positions.splice(randIndex, 1);
75 }
76 randIndex = randInt(4);
77 const knight2Pos = positions[randIndex];
78 positions.splice(randIndex, 1);
79 randIndex = randInt(3);
80 const queenPos = positions[randIndex];
81 positions.splice(randIndex, 1);
82 const rook1Pos = positions[0];
83 const rook2Pos = positions[1];
84 pieces[c][rook1Pos] = "r";
85 pieces[c][knight1Pos] = "n";
86 pieces[c][bishop1Pos] = "b";
87 pieces[c][queenPos] = "q";
88 pieces[c][kingPos] = "k";
89 pieces[c][bishop2Pos] = "b";
90 pieces[c][knight2Pos] = "n";
91 pieces[c][rook2Pos] = "r";
92 }
93
94 return {
95 fen: (
96 pieces["b"].join("") +
97 "/pppppppp/8/8/8/8/PPPPPPPP/" +
98 pieces["w"].join("").toUpperCase()
99 ),
100 o: {}
101 };
102 }
103
104 underCheck(square_s) {
105 return (
106 this.underAttack(square_s[0], 'w') ||
107 this.underAttack(square_s[0], 'b')
108 );
109 }
110
111 };