- if ( !(attackers_to(st->epSquare) & pieces(sideToMove, PAWN))
- || !(pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))))
- st->epSquare = SQ_NONE;
+ // En passant square will be considered only if
+ // a) side to move have a pawn threatening epSquare
+ // b) there is an enemy pawn in front of epSquare
+ // c) there is no piece on epSquare or behind epSquare
+ // d) enemy pawn didn't block a check of its own color by moving forward
+ enpassant = pawn_attacks_bb(~sideToMove, st->epSquare) & pieces(sideToMove, PAWN)
+ && (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove)))
+ && !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove))))
+ && ( file_of(square<KING>(sideToMove)) == file_of(st->epSquare)
+ || !(blockers_for_king(sideToMove) & (st->epSquare + pawn_push(~sideToMove))));
+ }
+
+ // It's necessary for st->previous to be intialized in this way because legality check relies on its existence
+ if (enpassant) {
+ st->previous = new StateInfo();
+ remove_piece(st->epSquare - pawn_push(sideToMove));
+ st->previous->checkersBB = attackers_to(square<KING>(~sideToMove)) & pieces(sideToMove);
+ st->previous->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square<KING>(WHITE), st->previous->pinners[BLACK]);
+ st->previous->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square<KING>(BLACK), st->previous->pinners[WHITE]);
+ put_piece(make_piece(~sideToMove, PAWN), st->epSquare - pawn_push(sideToMove));