Start Absoption
[xogo.git] / variants / Absorption / class.js
1 import ChessRules from "/base_rules.js";
2
3 export default class AbsorptionRules extends ChessRules {
4
5 static get Options() {
6 return {
7 select: C.Options.select,
8 check: [],
9 styles: [
10 "balance",
11 "capture",
12 "cylinder",
13 "dark",
14 "doublemove",
15 "progressive",
16 "recycle",
17 "rifle", //TODO? absorb powers from afar?
18 "teleport",
19 "zen"
20 ]
21 };
22 }
23
24 pieces(color) {
25 const fusions = {{
26 // amazon
27 'a': {
28 "class": "amazon",
29 steps: [
30 [0, 1], [0, -1], [1, 0], [-1, 0],
31 [1, 1], [1, -1], [-1, 1], [-1, -1]
32 ]
33
34 //TODO: steps object avec range + steps... "moving"?
35
36 steps: [
37 [1, 2], [1, -2], [-1, 2], [-1, -2],
38 [2, 1], [-2, 1], [2, -1], [-2, -1]
39 ],
40 steps: [[0, 1], [0, -1], [1, 0], [-1, 0]]
41 },
42 // empress
43 'e': {
44 "class": "empress",
45 steps: [
46 [1, 2], [1, -2], [-1, 2], [-1, -2],
47 [2, 1], [-2, 1], [2, -1], [-2, -1]
48 ],
49 },
50 // princess
51 'b': {
52 "class": "bishop",
53 steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]]
54 },
55 // queen
56 'q': {
57 "class": "queen",
58 },
59
60 },
61 return (
62 Object.assign(
63 super.pieces(color)
64 )
65 );
66 }
67
68 static get MergeComposed() {
69 return {
70 "be": "a",
71 "bs": "s",
72 "er": "e",
73 "rs": "a",
74 "eq": "a",
75 "qs": "a",
76 "ee": "e",
77 "es": "a",
78 "ss": "s"
79 };
80 }
81
82 static Fusion(p1, p2) {
83 if (p1 == V.KING) return p1;
84 if (p1 == V.PAWN) return p2;
85 if (p2 == V.PAWN) return p1;
86 if ([p1, p2].includes(V.KNIGHT)) {
87 if ([p1, p2].includes(V.QUEEN)) return V.QN;
88 if ([p1, p2].includes(V.ROOK)) return V.RN;
89 if ([p1, p2].includes(V.BISHOP)) return V.BN;
90 // p1 or p2 already have knight + other piece
91 return (p1 == V.KNIGHT ? p2 : p1);
92 }
93 if ([p1, p2].includes(V.QN)) return V.QN;
94 for (let p of [p1, p2]) {
95 if ([V.BN, V.RN].includes(p))
96 return V.MergeComposed[[p1, p2].sort().join("")];
97 }
98 // bishop + rook, or queen + [bishop or rook]
99 return V.QUEEN;
100 }
101
102 getPotentialMovesFrom(sq) {
103 let moves = [];
104 const piece = this.getPiece(sq[0], sq[1]);
105 switch (piece) {
106 case V.RN:
107 moves =
108 super.getPotentialRookMoves(sq).concat(
109 super.getPotentialKnightMoves(sq));
110 break;
111 case V.BN:
112 moves =
113 super.getPotentialBishopMoves(sq).concat(
114 super.getPotentialKnightMoves(sq));
115 break;
116 case V.QN:
117 moves =
118 super.getPotentialQueenMoves(sq).concat(
119 super.getPotentialKnightMoves(sq));
120 break;
121 default:
122 moves = super.getPotentialMovesFrom(sq);
123 }
124 // Filter out capturing promotions (except one),
125 // because they are all the same.
126 moves = moves.filter(m => {
127 return (
128 m.vanish.length == 1 ||
129 m.vanish[0].p != V.PAWN ||
130 [V.PAWN, V.QUEEN].includes(m.appear[0].p)
131 );
132 });
133 moves.forEach(m => {
134 if (
135 m.vanish.length == 2 &&
136 m.appear.length == 1 &&
137 piece != m.vanish[1].p
138 ) {
139 // Augment pieces abilities in case of captures
140 m.appear[0].p = V.Fusion(piece, m.vanish[1].p);
141 }
142 });
143 return moves;
144 }
145
146 isAttacked(sq, color) {
147 return (
148 super.isAttacked(sq, color) ||
149 this.isAttackedByBN(sq, color) ||
150 this.isAttackedByRN(sq, color) ||
151 this.isAttackedByQN(sq, color)
152 );
153 }
154
155 isAttackedByBN(sq, color) {
156 return (
157 this.isAttackedBySlideNJump(sq, color, V.BN, V.steps[V.BISHOP]) ||
158 this.isAttackedBySlideNJump(
159 sq, color, V.BN, V.steps[V.KNIGHT], 1)
160 );
161 }
162
163 isAttackedByRN(sq, color) {
164 return (
165 this.isAttackedBySlideNJump(sq, color, V.RN, V.steps[V.ROOK]) ||
166 this.isAttackedBySlideNJump(
167 sq, color, V.RN, V.steps[V.KNIGHT], 1)
168 );
169 }
170
171 isAttackedByQN(sq, color) {
172 return (
173 this.isAttackedBySlideNJump(
174 sq, color, V.QN, V.steps[V.BISHOP].concat(V.steps[V.ROOK])) ||
175 this.isAttackedBySlideNJump(
176 sq, color, V.QN, V.steps[V.KNIGHT], 1)
177 );
178 }
179
180 static get VALUES() {
181 return Object.assign(
182 { a: 12, e: 7, s: 5 },
183 ChessRules.VALUES
184 );
185 }
186
187 getNotation(move) {
188 let notation = super.getNotation(move);
189 if (move.vanish[0].p != V.PAWN && move.appear[0].p != move.vanish[0].p)
190 // Fusion (not from a pawn: handled in ChessRules)
191 notation += "=" + move.appear[0].p.toUpperCase();
192 return notation;
193 }
194
195 };