1 class BerolinaRules
extends ChessRules
3 // En-passant after 2-sq jump
4 getEpSquare(moveOrSquare
)
8 if (typeof moveOrSquare
=== "string")
10 const square
= moveOrSquare
;
13 // Enemy pawn initial column must be given too:
15 const epParts
= square
.split(",");
16 res
.push(V
.SquareToCoords(epParts
[0]));
17 res
.push(V
.ColumnToCoord(epParts
[1]));
20 // Argument is a move:
21 const move = moveOrSquare
;
22 const [sx
,ex
,sy
] = [move.start
.x
,move.end
.x
,move.start
.y
];
23 if (this.getPiece(sx
,sy
) == V
.PAWN
&& Math
.abs(sx
- ex
) == 2)
29 y: (move.end
.y
+ sy
)/2
34 return undefined; //default
37 // Special pawns movements
38 getPotentialPawnMoves([x
,y
])
40 const color
= this.turn
;
42 const [sizeX
,sizeY
] = [V
.size
.x
,V
.size
.y
];
43 const shiftX
= (color
== "w" ? -1 : 1);
44 const firstRank
= (color
== 'w' ? sizeX
-1 : 0);
45 const startRank
= (color
== "w" ? sizeX
-2 : 1);
46 const lastRank
= (color
== "w" ? 0 : sizeX
-1);
47 const finalPieces
= x
+ shiftX
== lastRank
48 ? [V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
]
51 // One square diagonally
52 for (let shiftY
of [-1,1])
54 if (this.board
[x
+shiftX
][y
+shiftY
] == V
.EMPTY
)
56 for (let piece
of finalPieces
)
58 moves
.push(this.getBasicMove([x
,y
], [x
+shiftX
,y
+shiftY
],
61 if (x
== startRank
&& y
+2*shiftY
>=0 && y
+2*shiftY
<sizeY
62 && this.board
[x
+2*shiftX
][y
+2*shiftY
] == V
.EMPTY
)
65 moves
.push(this.getBasicMove([x
,y
], [x
+2*shiftX
,y
+2*shiftY
]));
70 if (this.board
[x
+shiftX
][y
] != V
.EMPTY
71 && this.canTake([x
,y
], [x
+shiftX
,y
]))
73 for (let piece
of finalPieces
)
74 moves
.push(this.getBasicMove([x
,y
], [x
+shiftX
,y
], {c:color
,p:piece
}));
78 const Lep
= this.epSquares
.length
;
79 const epSquare
= this.epSquares
[Lep
-1]; //always at least one element
80 if (!!epSquare
&& epSquare
[0].x
== x
+shiftX
&& epSquare
[0].y
== y
81 && Math
.abs(epSquare
[1] - y
) == 1)
83 let enpassantMove
= this.getBasicMove([x
,y
], [x
+shiftX
,y
]);
84 enpassantMove
.vanish
.push({
88 c: this.getColor(x
,epSquare
[1])
90 moves
.push(enpassantMove
);
96 isAttackedByPawn([x
,y
], colors
)
100 let pawnShift
= (c
=="w" ? 1 : -1);
101 if (x
+pawnShift
>=0 && x
+pawnShift
<V
.size
.x
)
103 if (this.getPiece(x
+pawnShift
,y
)==V
.PAWN
104 && this.getColor(x
+pawnShift
,y
)==c
)
115 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
119 const finalSquare
= V
.CoordsToSquare(move.end
);
121 if (move.vanish
.length
== 2) //capture
122 notation
= "Px" + finalSquare
;
125 // No capture: indicate the initial square for potential ambiguity
126 const startSquare
= V
.CoordsToSquare(move.start
);
127 notation
= startSquare
+ finalSquare
;
129 if (move.appear
[0].p
!= V
.PAWN
) //promotion
130 notation
+= "=" + move.appear
[0].p
.toUpperCase();
133 return super.getNotation(move); //all other pieces are orthodox