Commit | Line | Data |
---|---|---|
b99ce1fb BA |
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 | }; |