1 import ChessRules
from "/base_rules.js";
3 export default class AbsorptionRules
extends ChessRules
{
7 select: C
.Options
.select
,
32 [0, 1], [0, -1], [1, 0], [-1, 0],
33 [1, 1], [1, -1], [-1, 1], [-1, -1]
38 [1, 2], [1, -2], [-1, 2], [-1, -2],
39 [2, 1], [-2, 1], [2, -1], [-2, -1]
49 [1, 2], [1, -2], [-1, 2], [-1, -2],
50 [2, 1], [-2, 1], [2, -1], [-2, -1]
56 steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]]
59 return Object
.assign(fusions
, super.pieces(color
));
62 static get MergeComposed() {
76 static Fusion(p1
, p2
) {
77 if (p1
== V
.KING
) return p1
;
78 if (p1
== V
.PAWN
) return p2
;
79 if (p2
== V
.PAWN
) return p1
;
80 if ([p1
, p2
].includes(V
.KNIGHT
)) {
81 if ([p1
, p2
].includes(V
.QUEEN
)) return V
.QN
;
82 if ([p1
, p2
].includes(V
.ROOK
)) return V
.RN
;
83 if ([p1
, p2
].includes(V
.BISHOP
)) return V
.BN
;
84 // p1 or p2 already have knight + other piece
85 return (p1
== V
.KNIGHT
? p2 : p1
);
87 if ([p1
, p2
].includes(V
.QN
)) return V
.QN
;
88 for (let p
of [p1
, p2
]) {
89 if ([V
.BN
, V
.RN
].includes(p
))
90 return V
.MergeComposed
[[p1
, p2
].sort().join("")];
92 // bishop + rook, or queen + [bishop or rook]
96 getPotentialMovesFrom(sq
) {
98 const piece
= this.getPiece(sq
[0], sq
[1]);
102 super.getPotentialRookMoves(sq
).concat(
103 super.getPotentialKnightMoves(sq
));
107 super.getPotentialBishopMoves(sq
).concat(
108 super.getPotentialKnightMoves(sq
));
112 super.getPotentialQueenMoves(sq
).concat(
113 super.getPotentialKnightMoves(sq
));
116 moves
= super.getPotentialMovesFrom(sq
);
118 // Filter out capturing promotions (except one),
119 // because they are all the same.
120 moves
= moves
.filter(m
=> {
122 m
.vanish
.length
== 1 ||
123 m
.vanish
[0].p
!= V
.PAWN
||
124 [V
.PAWN
, V
.QUEEN
].includes(m
.appear
[0].p
)
129 m
.vanish
.length
== 2 &&
130 m
.appear
.length
== 1 &&
131 piece
!= m
.vanish
[1].p
133 // Augment pieces abilities in case of captures
134 m
.appear
[0].p
= V
.Fusion(piece
, m
.vanish
[1].p
);
140 isAttacked(sq
, color
) {
142 super.isAttacked(sq
, color
) ||
143 this.isAttackedByBN(sq
, color
) ||
144 this.isAttackedByRN(sq
, color
) ||
145 this.isAttackedByQN(sq
, color
)
149 isAttackedByBN(sq
, color
) {
151 this.isAttackedBySlideNJump(sq
, color
, V
.BN
, V
.steps
[V
.BISHOP
]) ||
152 this.isAttackedBySlideNJump(
153 sq
, color
, V
.BN
, V
.steps
[V
.KNIGHT
], 1)
157 isAttackedByRN(sq
, color
) {
159 this.isAttackedBySlideNJump(sq
, color
, V
.RN
, V
.steps
[V
.ROOK
]) ||
160 this.isAttackedBySlideNJump(
161 sq
, color
, V
.RN
, V
.steps
[V
.KNIGHT
], 1)
165 isAttackedByQN(sq
, color
) {
167 this.isAttackedBySlideNJump(
168 sq
, color
, V
.QN
, V
.steps
[V
.BISHOP
].concat(V
.steps
[V
.ROOK
])) ||
169 this.isAttackedBySlideNJump(
170 sq
, color
, V
.QN
, V
.steps
[V
.KNIGHT
], 1)
174 static get VALUES() {
175 return Object
.assign(
176 { a: 12, e: 7, s: 5 },
182 let notation
= super.getNotation(move);
183 if (move.vanish
[0].p
!= V
.PAWN
&& move.appear
[0].p
!= move.vanish
[0].p
)
184 // Fusion (not from a pawn: handled in ChessRules)
185 notation
+= "=" + move.appear
[0].p
.toUpperCase();