Untested draft refactor both/moves/attack for pieces specs
[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 class BicolourRules extends ChessRules {
6
7 // TODO: Options
8
9 get hasFlags() {
10 return false;
11 }
12
13 canTake([x1, y1], [x2, y2]) {
14 return (this.getPiece(x2, y2) == 'k' || super.canTake([x1, y1], [x2, y2]));
15 }
16
17 genRandInitBaseFen() {
18 if (this.options["randomness"] == 0)
19 return { fen: "rqbnkbnr/pppppppp/8/8/8/8/PPPPPPPP/RQBNKBNR", o: {} };
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' && this.options["randomness"] == 1) {
27 pieces['b'] = pieces['w'];
28 break;
29 }
30 let positions = ArrayFun.range(8);
31 const kingPos = randInt(8);
32 let toRemove = [kingPos];
33 let knight1Pos = undefined;
34 let bishop1Pos = undefined;
35 if (kingPos == 0) {
36 if (Random.randBool())
37 knight1Pos = 1;
38 else
39 bishop1Pos = 1;
40 toRemove.push(1);
41 }
42 else if (kingPos == V.size.y - 1) {
43 if (Random.randBool())
44 knight1Pos = V.size.y - 2;
45 else
46 bishop1Pos = V.size.y - 2;
47 toRemove.push(V.size.y - 2);
48 }
49 else {
50 knight1Pos = kingPos + (Random.randBool() ? 1 : -1);
51 bishop1Pos = kingPos + (knight1Pos < kingPos ? 1 : -1);
52 toRemove.push(knight1Pos, bishop1Pos);
53 }
54 const firstPieces = [kingPos, knight1Pos, bishop1Pos]
55 .filter(elt => elt !== undefined);
56 firstPieces
57 .sort((a, b) => b - a)
58 .forEach(elt => positions.splice(elt, 1));
59 let randIndex = undefined;
60 if (bishop1Pos === undefined) {
61 const posWithIdx = positions.map((e,i) => { return {e: e, i: i}; });
62 let availableSquares = posWithIdx.filter(p => p.e % 2 == 0);
63 randIndex = randInt(availableSquares.length);
64 bishop1Pos = availableSquares[randIndex].e;
65 positions.splice(availableSquares[randIndex].i, 1);
66 }
67 const posWithIdx = positions.map((e,i) => { return {e: e, i: i}; });
68 const rem1B = bishop1Pos % 2;
69 let availableSquares = posWithIdx.filter(p => p.e % 2 == 1 - rem1B);
70 randIndex = randInt(availableSquares.length);
71 const bishop2Pos = availableSquares[randIndex].e;
72 positions.splice(availableSquares[randIndex].i, 1);
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 randIndex = randInt(3);
82 const queenPos = positions[randIndex];
83 positions.splice(randIndex, 1);
84 const rook1Pos = positions[0];
85 const rook2Pos = positions[1];
86 pieces[c][rook1Pos] = "r";
87 pieces[c][knight1Pos] = "n";
88 pieces[c][bishop1Pos] = "b";
89 pieces[c][queenPos] = "q";
90 pieces[c][kingPos] = "k";
91 pieces[c][bishop2Pos] = "b";
92 pieces[c][knight2Pos] = "n";
93 pieces[c][rook2Pos] = "r";
94 }
95
96 return {
97 fen: (
98 pieces["b"].join("") +
99 "/pppppppp/8/8/8/8/PPPPPPPP/" +
100 pieces["w"].join("").toUpperCase()
101 ),
102 o: {}
103 };
104 }
105
106 underCheck(color) {
107 const kingPos = this.searchKingPos(color)[0],
108 return (this.underAttack(kingPos, 'w') || this.underAttack(kingPos, 'b'));
109 }
110
111 };