Draft Diamond variant
[xogo.git] / variants / Diamond / class.js
1 import ChessRules from "/base_rules.js";
2 import {ArrayFun} from "/utils/array.js";
3 import {Random} from "/utils/alea.js";
4
5 export default class DiamondRules extends ChessRules {
6
7 get hasFlags() {
8 return false;
9 }
10
11 get hasEnpassant() {
12 return false;
13 }
14
15 getSvgChessboard() {
16 const diagonal = 10 * this.size.y * Math.sqrt(2);
17 const halfDiag = 0.5 * diagonal;
18 const deltaTrans = 10 * this.size.y * (Math.sqrt(2) - 1) / 2;
19 let board = `
20 <svg
21 viewBox="0 0 ${diagonal} ${diagonal}"
22 class="chessboard_SVG">`;
23 board += `<g transform="rotate(45 ${halfDiag} ${halfDiag})
24 translate(${deltaTrans} ${deltaTrans})">`;
25 board += this.getBaseSvgChessboard();
26 board += "</g></svg>";
27 return board;
28 }
29
30 getPieceWidth(rwidth) {
31 return (0.95 * rwidth / (Math.sqrt(2) * this.size.y));
32 }
33
34 getPixelPosition(i, j, r) {
35 if (i < 0 || j < 0 || typeof i == "string")
36 return super.getPixelPosition(i, j, r);
37 const sqSize = this.getPieceWidth(r.width) / 0.95;
38 const flipped = this.flippedBoard;
39 i = (flipped ? this.size.x - 1 - i : i);
40 j = (flipped ? this.size.y - 1 - j : j);
41 const sq2 = Math.sqrt(2);
42 const shift = [- sqSize / 2, sqSize * (sq2 - 1) / 2];
43 const x = (j - i) * sqSize / sq2 + shift[0] + r.width / 2;
44 const y = (i + j) * sqSize / sq2 + shift[1];
45 return [r.x + x, r.y + y];
46 }
47
48 genRandInitBaseFen() {
49 if (this.options["randomness"] == 0) {
50 return {
51 fen: "krbp4/rqnp4/nbpp4/pppp4/4PPPP/4PPBN/4PNQR/4PBRK",
52 o: {}
53 };
54 }
55 let pieces = { w: new Array(8), b: new Array(8) };
56 for (let c of ["w", "b"]) {
57 if (c == 'b' && options.randomness == 1) {
58 pieces['b'] = pieces['w'];
59 break;
60 }
61 // Get random squares for every piece, totally freely
62 let positions = Random.shuffle(ArrayFun.range(8));
63 const composition = ['b', 'b', 'r', 'r', 'n', 'n', 'k', 'q'];
64 const rem2 = positions[0] % 2;
65 if (rem2 == positions[1] % 2) {
66 // Fix bishops (on different colors)
67 for (let i=2; i<8; i++) {
68 if (positions[i] % 2 != rem2) {
69 [positions[1], positions[i]] = [positions[i], positions[1]];
70 break;
71 }
72 }
73 }
74 for (let i = 0; i < 8; i++)
75 pieces[c][positions[i]] = composition[i];
76 }
77 const fen = (
78 pieces["b"].slice(0, 3).join("") + "p4/" +
79 pieces["b"].slice(3, 6).join("") + "p4/" +
80 pieces["b"].slice(6, 8).join("") + "pp4/" +
81 "pppp4/4PPPP/" +
82 "4PP" + pieces["w"].slice(6, 8).reverse().join("").toUpperCase() + "/" +
83 "4P" + pieces["w"].slice(3, 6).reverse().join("").toUpperCase() + "/" +
84 "4P" + pieces["w"].slice(0, 3).reverse().join("").toUpperCase());
85 return { fen: fen, o: {} };
86 }
87
88 pieces(color, x, y) {
89 let res = super.pieces(color, x, y);
90 const pawnShift = this.getPawnShift(color || 'w');
91 res['p'].moves = [{steps: [[pawnShift, pawnShift]], range: 1}];
92 res['p'].attack = [{steps: [[0, pawnShift], [pawnShift, 0]], range: 1}];
93 return res;
94 }
95
96 };