1 import { ChessRules
} from "@/base_rules";
3 export class TakenmakeRules
extends ChessRules
{
4 setOtherVariables(fen
) {
5 super.setOtherVariables(fen
);
6 // Stack of "last move" only for intermediate captures
7 this.lastMoveEnd
= [null];
10 getPotentialMovesFrom([x
, y
], asA
) {
11 const L
= this.lastMoveEnd
.length
;
12 if (!asA
&& !!this.lastMoveEnd
[L
-1]) {
13 asA
= this.lastMoveEnd
[L
-1].p
;
14 if (x
!= this.lastMoveEnd
[L
-1].x
|| y
!= this.lastMoveEnd
[L
-1].y
) {
15 // A capture was played: wrong square
20 const piece
= this.getPiece(x
, y
);
21 switch (asA
|| piece
) {
23 if (!asA
|| piece
== V
.PAWN
)
24 moves
= this.getPotentialPawnMoves([x
, y
]);
26 // Special case: we don't want promotion, since just moving like
27 // a pawn, but I'm in fact not a pawn :)
28 const shiftX
= (this.turn
== 'w' ? -1 : 1);
29 if (this.board
[x
+ shiftX
][y
] == V
.EMPTY
)
30 moves
= [this.getBasicMove([x
, y
], [x
+ shiftX
, y
])];
34 moves
= this.getPotentialRookMoves([x
, y
]);
37 moves
= this.getPotentialKnightMoves([x
, y
]);
40 moves
= this.getPotentialBishopMoves([x
, y
]);
43 moves
= this.getPotentialKingMoves([x
, y
]);
46 moves
= this.getPotentialQueenMoves([x
, y
]);
49 // Post-process: if capture,
50 // can a move "as-capturer" be achieved with the same piece?
52 const color
= this.turn
;
53 return moves
.filter(m
=> {
54 if (m
.vanish
.length
== 2 && m
.appear
.length
== 1) {
58 this.getPotentialMovesFrom([m
.end
.x
, m
.end
.y
], m
.vanish
[1].p
);
60 makeMoves
.every(mm
=> {
61 // Cannot castle after a capturing move
62 // (with the capturing piece):
63 if (mm
.vanish
.length
== 2) return true;
65 const res
= this.underCheck(color
);
78 // Moving "as a": filter out captures (no castles here)
79 return moves
.filter(m
=> m
.vanish
.length
== 1);
82 getPossibleMovesFrom(sq
) {
83 const L
= this.lastMoveEnd
.length
;
85 if (!!this.lastMoveEnd
[L
-1]) {
87 sq
[0] != this.lastMoveEnd
[L
-1].x
||
88 sq
[1] != this.lastMoveEnd
[L
-1].y
92 asA
= this.lastMoveEnd
[L
-1].p
;
94 return this.filterValid(this.getPotentialMovesFrom(sq
, asA
));
98 let noCaptureMoves
= [];
99 let captureMoves
= [];
101 if (m
.vanish
.length
== 1 || m
.appear
.length
== 2) noCaptureMoves
.push(m
);
102 else captureMoves
.push(m
);
104 // Capturing moves were already checked in getPotentialMovesFrom()
105 return super.filterValid(noCaptureMoves
).concat(captureMoves
);
109 move.flags
= JSON
.stringify(this.aggregateFlags());
110 this.epSquares
.push(this.getEpSquare(move));
111 V
.PlayOnBoard(this.board
, move);
112 if (move.vanish
.length
== 1 || move.appear
.length
== 2) {
113 // Not a capture: change turn
114 this.turn
= V
.GetOppCol(this.turn
);
116 this.lastMoveEnd
.push(null);
119 this.lastMoveEnd
.push(
120 Object
.assign({}, move.end
, { p: move.vanish
[1].p
})
127 const c
= move.vanish
[0].c
;
128 const piece
= move.vanish
[0].p
;
129 if (piece
== V
.KING
&& move.appear
.length
> 0) {
130 this.kingPos
[c
][0] = move.appear
[0].x
;
131 this.kingPos
[c
][1] = move.appear
[0].y
;
133 super.updateCastleFlags(move, piece
);
137 this.disaggregateFlags(JSON
.parse(move.flags
));
138 this.epSquares
.pop();
139 this.lastMoveEnd
.pop();
140 V
.UndoOnBoard(this.board
, move);
141 if (move.vanish
.length
== 1 || move.appear
.length
== 2) {
142 this.turn
= V
.GetOppCol(this.turn
);
145 super.postUndo(move);