9b071d34c6bf5f97ce0e64d53f427b2f0e1acbe3
1 import { ChessRules
} from "@/base_rules";
3 export class BerolinaRules
extends ChessRules
{
6 return (b
[1] == 'p' ? "Berolina/" : "") + b
;
9 // En-passant after 2-sq jump
10 getEpSquare(moveOrSquare
) {
11 if (!moveOrSquare
) return undefined;
12 if (typeof moveOrSquare
=== "string") {
13 const square
= moveOrSquare
;
14 if (square
== "-") return undefined;
15 // Enemy pawn initial column must be given too:
17 const epParts
= square
.split(",");
18 res
.push(V
.SquareToCoords(epParts
[0]));
19 res
.push(V
.ColumnToCoord(epParts
[1]));
22 // Argument is a move:
23 const move = moveOrSquare
;
24 const [sx
, ex
, sy
] = [move.start
.x
, move.end
.x
, move.start
.y
];
25 if (this.getPiece(sx
, sy
) == V
.PAWN
&& Math
.abs(sx
- ex
) == 2) {
29 y: (move.end
.y
+ sy
) / 2
31 // The arrival column must be remembered, because
32 // potentially two pawns could be candidates to be captured:
33 // one on our left, and one on our right.
37 return undefined; //default
40 static IsGoodEnpassant(enpassant
) {
41 if (enpassant
!= "-") {
42 const epParts
= enpassant
.split(",");
43 const epSq
= V
.SquareToCoords(epParts
[0]);
44 if (isNaN(epSq
.x
) || isNaN(epSq
.y
) || !V
.OnBoard(epSq
)) return false;
45 const arrCol
= V
.ColumnToCoord(epParts
[1]);
46 if (isNaN(arrCol
) || arrCol
< 0 || arrCol
>= V
.size
.y
) return false;
52 const L
= this.epSquares
.length
;
53 if (!this.epSquares
[L
- 1]) return "-"; //no en-passant
55 V
.CoordsToSquare(this.epSquares
[L
- 1][0]) +
57 V
.CoordToColumn(this.epSquares
[L
- 1][1])
61 getEnpassantCaptures([x
, y
], shift
) {
62 const Lep
= this.epSquares
.length
;
63 const epSquare
= this.epSquares
[Lep
- 1]; //always at least one element
66 epSquare
[0].x
== x
+ shift
&&
69 let enpassantMove
= this.getBasicMove([x
, y
], [x
+ shift
, y
]);
70 enpassantMove
.vanish
.push({
74 c: this.getColor(x
, epSquare
[1])
76 return [enpassantMove
];
81 // Special pawns movements
82 getPotentialPawnMoves([x
, y
]) {
83 const color
= this.turn
;
85 const [sizeX
, sizeY
] = [V
.size
.x
, V
.size
.y
];
86 const shiftX
= color
== "w" ? -1 : 1;
87 const startRank
= color
== "w" ? sizeX
- 2 : 1;
88 const lastRank
= color
== "w" ? 0 : sizeX
- 1;
90 x
+ shiftX
== lastRank
91 ? [V
.ROOK
, V
.KNIGHT
, V
.BISHOP
, V
.QUEEN
]
94 // One square diagonally
95 for (let shiftY
of [-1, 1]) {
96 if (this.board
[x
+ shiftX
][y
+ shiftY
] == V
.EMPTY
) {
97 for (let piece
of finalPieces
) {
99 this.getBasicMove([x
, y
], [x
+ shiftX
, y
+ shiftY
], {
106 V
.PawnSpecs
.twoSquares
&&
108 y
+ 2 * shiftY
>= 0 &&
109 y
+ 2 * shiftY
< sizeY
&&
110 this.board
[x
+ 2 * shiftX
][y
+ 2 * shiftY
] == V
.EMPTY
114 this.getBasicMove([x
, y
], [x
+ 2 * shiftX
, y
+ 2 * shiftY
])
121 this.board
[x
+ shiftX
][y
] != V
.EMPTY
&&
122 this.canTake([x
, y
], [x
+ shiftX
, y
])
124 for (let piece
of finalPieces
) {
126 this.getBasicMove([x
, y
], [x
+ shiftX
, y
], { c: color
, p: piece
})
131 // Next condition so that other variants could inherit from this class
132 if (V
.HasEnpassant
) {
133 // NOTE: backward en-passant captures are not considered
134 // because no rules define them (for now).
135 Array
.prototype.push
.apply(
137 this.getEnpassantCaptures([x
, y
], shiftX
)
144 isAttackedByPawn([x
, y
], color
) {
145 let pawnShift
= (color
== "w" ? 1 : -1);
147 x
+ pawnShift
>= 0 && x
+ pawnShift
< V
.size
.x
&&
148 this.getPiece(x
+ pawnShift
, y
) == V
.PAWN
&&
149 this.getColor(x
+ pawnShift
, y
) == color
153 static get SEARCH_DEPTH() {
158 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
159 if (piece
== V
.PAWN
) {
161 const finalSquare
= V
.CoordsToSquare(move.end
);
163 if (move.vanish
.length
== 2)
165 notation
= "Px" + finalSquare
;
167 // No capture: indicate the initial square for potential ambiguity
168 const startSquare
= V
.CoordsToSquare(move.start
);
169 notation
= startSquare
+ finalSquare
;
171 if (move.appear
[0].p
!= V
.PAWN
)
173 notation
+= "=" + move.appear
[0].p
.toUpperCase();
176 return super.getNotation(move); //all other pieces are orthodox