forked from rooklift/nibbler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path43_chess960.js
79 lines (55 loc) · 1.67 KB
/
43_chess960.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
"use strict";
function c960_arrangement(n) {
// Given n, generate a string like "RNBQKBNR".
// AFAIK, matches the scheme of Reinhard Scharnagl.
if (n < 0) {
n *= -1;
}
n = Math.floor(n) % 960;
let pieces = [".", ".", ".", ".", ".", ".", ".", "."];
// Helper function to place a piece at an "index",
// but considering only empty spots.
let insert = (index, piece) => {
let skips = 0;
for (let i = 0; i < 8; i++) {
if (pieces[i] === ".") {
if (skips === index) {
pieces[i] = piece;
return;
} else {
skips++;
}
}
}
};
// Place bishops in final positions...
pieces[(Math.floor(n / 4) % 4) * 2] = "B";
pieces[(n % 4) * 2 + 1] = "B";
// Place queen in one of 6 remaining spots...
let qi = Math.floor(n / 16) % 6;
insert(qi, "Q");
// Knights are arranged in one of 10 possible configurations
// (considering only the remaining spots)...
let ni1 = [0, 0, 0, 0, 1, 1, 1, 2, 2, 3][Math.floor(n / 96)];
let ni2 = [1, 2, 3, 4, 2, 3, 4, 3, 4, 4][Math.floor(n / 96)];
insert(ni2, "N"); // Must be done in this order,
insert(ni1, "N"); // works because ni2 > ni1
// Place left rook, king, right rook in first available spots...
insert(0, "R");
insert(0, "K");
insert(0, "R");
return pieces.join("");
}
function c960_fen(n) {
// Given n, produce a full FEN.
let pieces = c960_arrangement(n); // The uppercase version.
let s = `${pieces.toLowerCase()}/pppppppp/8/8/8/8/PPPPPPPP/${pieces}`;
let castling_rights = "";
for (let i = 0; i < 8; i++) {
if (pieces[i] === "R") {
castling_rights += String.fromCharCode(i + 65);
}
}
castling_rights += castling_rights.toLowerCase();
return `${s} w ${castling_rights} - 0 1`;
}