bbc35a467d42588869fc2c849e856a408234fc28
[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) {
65 super.setOtherVariables(fenParsed);
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(color, x, y) {
79 let res = super.pieces(color, x, y);
80 res['l'] = JSON.parse(JSON.stringify(res['q']));
81 // TODO: CSS royal queen symbol (with cross?)
82 res['l']["class"] = "royal_queen";
83 res['='] = {"class": "castle"}; //for castle display
84 return res;
85 }
86
87 setFlags(fenflags) {
88 this.castleFlags = {
89 k: {
90 w: [0, 1].map(i => parseInt(fenflags.charAt(i), 10)),
91 b: [2, 3].map(i => parseInt(fenflags.charAt(i), 10))
92 },
93 l: {
94 w: [4, 5].map(i => parseInt(fenflags.charAt(i), 10)),
95 b: [6, 7].map(i => parseInt(fenflags.charAt(i), 10))
96 }
97 };
98 }
99
100 getFlagsFen() {
101 return ['k', 'l'].map(p => {
102 return ['w', 'b'].map(c => {
103 return this.castleFlags[p][c].map(x => x.toString(10)).join("");
104 }).join("")
105 }).join("");
106 }
107
108 isKing(x, y, p) {
109 if (!p)
110 p = this.getPiece(x, y);
111 return ['k', 'l'].includes(p); //no cannibal mode
112 }
113
114 getCastleMoves([x, y]) {
115 const c = this.getColor(x, y),
116 p = this.getPiece(x, y);
117 // Relative position of the selected piece: left or right ?
118 // If left: small castle left, large castle right.
119 // If right: usual situation.
120 const finalSquares = [
121 this.relPos[c][p] == '0' ? [1, 2] : [2, 3], //0 == left
122 this.relPos[c][p] == '1' ? [6, 5] : [5, 4] //1 == right
123 ];
124 let moves =
125 super.getCastleMoves([x, y], finalSquares, null, this.castleFlags[p][c]);
126 if (p == 'l')
127 moves.forEach(m => m.choice = '='); //required (for display)
128 return moves;
129 }
130
131 updateCastleFlags(move) {
132 super.updateCastleFlags(move, this.castleFlags['k'], 'k');
133 super.updateCastleFlags(move, this.castleFlags['l'], 'l');
134 }
135
136 };