1 import { ChessRules
} from "@/base_rules";
3 export class ZenRules
extends ChessRules
{
4 getEpSquare(moveOrSquare
) {
5 if (!moveOrSquare
) return undefined;
6 if (typeof moveOrSquare
=== "string") {
7 const square
= moveOrSquare
;
8 if (square
== "-") return undefined;
9 return V
.SquareToCoords(square
);
11 const move = moveOrSquare
;
15 // Exclude captures (of rooks for example)
16 move.vanish
.length
== 1 &&
18 Math
.abs(s
.x
- e
.x
) == 2 &&
19 move.appear
[0].p
== V
.PAWN
29 // TODO(?): some duplicated code in 2 next functions
30 getSlideNJumpMoves([x
, y
], steps
, oneStep
) {
32 outerLoop: for (let loop
= 0; loop
< steps
.length
; loop
++) {
33 const step
= steps
[loop
];
36 while (V
.OnBoard(i
, j
) && this.board
[i
][j
] == V
.EMPTY
) {
37 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
38 if (oneStep
) continue outerLoop
;
42 // No capture check: handled elsewhere (next method)
47 // follow steps from x,y until something is met.
48 // if met piece is opponent and same movement (asA): eat it!
49 findCaptures_aux([x
, y
], asA
) {
50 const color
= this.getColor(x
, y
);
55 ? V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
])
66 const oneStep
= [V
.KNIGHT
,V
.PAWN
].includes(asA
); //we don't capture king
67 const lastRank
= color
== "w" ? 0 : V
.size
.x
- 1;
68 const promotionPieces
= [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
];
69 outerLoop: for (let loop
= 0; loop
< steps
.length
; loop
++) {
70 const step
= steps
[loop
];
73 while (V
.OnBoard(i
, j
) && this.board
[i
][j
] == V
.EMPTY
) {
74 if (oneStep
) continue outerLoop
;
80 this.getColor(i
, j
) == V
.GetOppCol(color
) &&
81 this.getPiece(i
, j
) == asA
84 if (this.getPiece(x
, y
) == V
.PAWN
&& i
== lastRank
) {
85 // Special case of promotion:
86 promotionPieces
.forEach(p
=> {
87 moves
.push(this.getBasicMove([x
, y
], [i
, j
], { c: color
, p: p
}));
91 moves
.push(this.getBasicMove([x
, y
], [i
, j
]));
98 // Find possible captures from a square: look in every direction!
102 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, V
.PAWN
));
103 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, V
.ROOK
));
104 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, V
.KNIGHT
));
105 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, V
.BISHOP
));
106 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, V
.QUEEN
));
112 return false; //captures handled separately
115 getPotentialPawnMoves([x
, y
]) {
116 let moves
= super.getPotentialPawnMoves([x
, y
]);
117 // Add "zen" captures
118 Array
.prototype.push
.apply(moves
, this.findCaptures([x
, y
]));
122 getPotentialRookMoves(sq
) {
123 let noCaptures
= this.getSlideNJumpMoves(sq
, V
.steps
[V
.ROOK
]);
124 let captures
= this.findCaptures(sq
);
125 return noCaptures
.concat(captures
);
128 getPotentialKnightMoves(sq
) {
129 let noCaptures
= this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], "oneStep");
130 let captures
= this.findCaptures(sq
);
131 return noCaptures
.concat(captures
);
134 getPotentialBishopMoves(sq
) {
135 let noCaptures
= this.getSlideNJumpMoves(sq
, V
.steps
[V
.BISHOP
]);
136 let captures
= this.findCaptures(sq
);
137 return noCaptures
.concat(captures
);
140 getPotentialQueenMoves(sq
) {
141 let noCaptures
= this.getSlideNJumpMoves(
143 V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
])
145 let captures
= this.findCaptures(sq
);
146 return noCaptures
.concat(captures
);
149 getPotentialKingMoves(sq
) {
150 // Initialize with normal moves
151 let noCaptures
= this.getSlideNJumpMoves(
153 V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]),
156 let captures
= this.findCaptures(sq
);
157 return noCaptures
.concat(captures
).concat(this.getCastleMoves(sq
));
161 // Recognize special moves first
162 if (move.appear
.length
== 2) {
164 if (move.end
.y
< move.start
.y
) return "0-0-0";
168 // Translate initial square (because pieces may fly unusually!)
169 const initialSquare
= V
.CoordsToSquare(move.start
);
171 // Translate final square
172 const finalSquare
= V
.CoordsToSquare(move.end
);
175 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
176 if (piece
== V
.PAWN
) {
177 // pawn move (TODO: enPassant indication)
178 if (move.vanish
.length
> 1) {
180 notation
= initialSquare
+ "x" + finalSquare
;
182 else notation
= finalSquare
;
183 if (piece
!= move.appear
[0].p
)
185 notation
+= "=" + move.appear
[0].p
.toUpperCase();
188 notation
= piece
.toUpperCase();
189 if (move.vanish
.length
> 1) notation
+= initialSquare
+ "x";
190 notation
+= finalSquare
;
195 static get VALUES() {