Almost fixed Coregal
[xogo.git] / variants / Coregal / class.js
1 import ChessRules from "/base_rules.js";
2 import {FenUtil} from "/utils/setupPieces.js"
3
4 export default class CoregalRules extends ChessRules {
5
6 genRandInitBaseFen() {
7 const s = FenUtil.setupPieces(
8 ['r', 'n', 'b', 'l', 'k', 'b', 'n', 'r'],
9 {
10 randomness: this.options["randomness"],
11 between: [{p1: 'k', p2: 'r'}, {p1: 'l', p2: 'r'}],
12 diffCol: ['b'],
13 // 'k' and 'l' useful only to get relative position
14 flags: ['r', 'k', 'l']
15 }
16 );
17 // Re-arrange flags: king + royal queen positions are only
18 // useful to know ordering, and thus allowed castles.
19 let flags = "";
20 let relPos = { 'w': {}, 'b': {} };
21 for (let c of [0, 1]) {
22 const col = (c == 0 ? 'w' : 'b');
23 let first = "";
24 for (let i=4*c; i<4*(c+1); i++) {
25 const pos = parseInt(s.flags.charAt(i), 10);
26 const symb = s[col][pos];
27 if (['k', 'l'].includes(symb)) {
28 if (!first) {
29 relPos[col][symb] = '0'; //left
30 first = symb;
31 }
32 else
33 relPos[col][symb] = '1'; //right
34 }
35 else
36 flags += s.flags.charAt(i);
37 }
38 }
39 return {
40 fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
41 s.w.join("").toUpperCase(),
42 o: {
43 flags: flags + flags, //duplicate: one for each royal piece
44 relPos: this.getRelposFen(relPos)
45 }
46 };
47 }
48
49 getPartFen(o) {
50 return (Object.assign(
51 {"relpos": o.init ? o.relPos : this.getRelposFen()},
52 super.getPartFen(o)
53 ));
54 }
55
56 getRelposFen(relPos) {
57 relPos = relPos || this.relPos;
58 return (
59 relPos['w']['k'] + relPos['w']['l'] +
60 relPos['b']['k'] + relPos['b']['l']
61 );
62 }
63
64 setOtherVariables(fenParsed, pieceArray) {
65 super.setOtherVariables(fenParsed, pieceArray);
66 this.relPos = {
67 'w': {
68 'k': fenParsed.relpos[0],
69 'l': fenParsed.relpos[1]
70 },
71 'b': {
72 'k': fenParsed.relpos[2],
73 'l': fenParsed.relpos[3]
74 }
75 };
76 }
77
78 pieces() {
79 let res = super.pieces();
80 res['l'] = JSON.parse(JSON.stringify(res['q']));
81 // TODO: CSS royal queen symbol (with cross?)
82 res['l']["class"] = "royal_queen";
83 return res;
84 }
85
86 setFlags(fenflags) {
87 this.castleFlags = {
88 k: {
89 w: [0, 1].map(i => parseInt(fenflags.charAt(i), 10)),
90 b: [2, 3].map(i => parseInt(fenflags.charAt(i), 10))
91 },
92 l: {
93 w: [4, 5].map(i => parseInt(fenflags.charAt(i), 10)),
94 b: [6, 7].map(i => parseInt(fenflags.charAt(i), 10))
95 }
96 };
97 }
98
99 getFlagsFen() {
100 return ['k', 'l'].map(p => {
101 return ['w', 'b'].map(c => {
102 return this.castleFlags[p][c].map(x => x.toString(10)).join("");
103 }).join("")
104 }).join("");
105 }
106
107 isKing(x, y, p) {
108 if (!p)
109 p = this.getPiece(x, y);
110 return ['k', 'l'].includes(p); //no cannibal mode
111 }
112
113 getCastleMoves([x, y]) {
114 const c = this.getColor(x, y),
115 p = this.getPiece(x, y);
116 // Relative position of the selected piece: left or right ?
117 // If left: small castle left, large castle right.
118 // If right: usual situation.
119 const finalSquares = [
120 this.relPos[c][p] == '0' ? [1, 2] : [2, 3], //0 == left
121 this.relPos[c][p] == '1' ? [6, 5] : [5, 4] //1 == right
122 ];
123 const moves =
124 super.getCastleMoves([x, y], finalSquares, null, this.castleFlags[p][c]);
125 return moves;
126 }
127
128 updateCastleFlags(move) {
129 super.updateCastleFlags(move, this.castleFlags['k'], 'k');
130 super.updateCastleFlags(move, this.castleFlags['l'], 'l');
131 }
132
133 };