movegen: cleanup + change casling/king moves handling
This commit is contained in:
@@ -26,7 +26,6 @@
|
|||||||
#include "attack.h"
|
#include "attack.h"
|
||||||
#include "move-gen.h"
|
#include "move-gen.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pseudo_is_legal() - check if a move is legal.
|
* pseudo_is_legal() - check if a move is legal.
|
||||||
* @pos: position
|
* @pos: position
|
||||||
@@ -36,13 +35,18 @@
|
|||||||
*/
|
*/
|
||||||
bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
||||||
{
|
{
|
||||||
color_t us = pos->turn, them = OPPONENT(us);
|
color_t us = pos->turn;
|
||||||
square_t from = move_from(move), to = move_to(move);
|
color_t them = OPPONENT(us);
|
||||||
square_t king = pos->king[us];
|
square_t from = move_from(move);
|
||||||
|
square_t to = move_to(move);
|
||||||
|
square_t kingsq = pos->king[us];
|
||||||
|
square_t ep = pos->en_passant;
|
||||||
bitboard_t kingbb = pos->bb[us][KING];
|
bitboard_t kingbb = pos->bb[us][KING];
|
||||||
bitboard_t occ = pos_occ(pos);
|
bitboard_t occ = pos_occ(pos);
|
||||||
u64 pinned = BIT(from) & pos->blockers;
|
u64 pinned = BIT(from) & pos->blockers;
|
||||||
u64 checkers = pos->checkers;
|
u64 checkers = pos->checkers;
|
||||||
|
|
||||||
|
bug_on(pos->board[from] == NO_PIECE || COLOR(pos->board[from]) != us);
|
||||||
|
|
||||||
/* (1) - Castling & King
|
/* (1) - Castling & King
|
||||||
* For castling, we need to check intermediate squares attacks only.
|
* For castling, we need to check intermediate squares attacks only.
|
||||||
@@ -50,60 +54,52 @@ bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
|||||||
* king from occupation bitboard (to catch king moving away from checker
|
* king from occupation bitboard (to catch king moving away from checker
|
||||||
* on same line) !
|
* on same line) !
|
||||||
*/
|
*/
|
||||||
if (unlikely(from == king)) {
|
if (is_castle(move)) {
|
||||||
if (unlikely(is_castle(move))) {
|
int dir = to > from? 1: -1;
|
||||||
square_t dir = to > from? 1: -1;
|
if (sq_is_attacked(pos, occ, from + dir, them))
|
||||||
if (sq_is_attacked(pos, occ, from + dir, them))
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
if (from == kingsq) {
|
||||||
return !sq_is_attacked(pos, occ ^ kingbb, to, them);
|
return !sq_is_attacked(pos, occ ^ kingbb, to, them);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (2) - King is in check
|
/* (2) - King is in check
|
||||||
* Double-check is already handled in (1), as only K moves were generated
|
* Double-check is already handled in (1), as only K moves were generated
|
||||||
* by pseudo legal move generator.
|
* by pseudo legal move generator.
|
||||||
* Here, allowed dest squares are only on King-checker line, or on checker
|
* Special cases (illegal):
|
||||||
* square.
|
* - e.p., if the grabbed pawn is *not* giving check
|
||||||
* attacker.
|
* - piece is pinned
|
||||||
* Special cases:
|
|
||||||
* e.p., legal if the grabbed pawn is giving check
|
|
||||||
* pinned piece: always illegal
|
|
||||||
*/
|
*/
|
||||||
if (checkers) {
|
if (checkers) {
|
||||||
if (pinned)
|
if (pinned)
|
||||||
return false;
|
return false;
|
||||||
if (bb_multiple(checkers))
|
|
||||||
return false;
|
|
||||||
square_t checker = ctz64(checkers);
|
|
||||||
if (is_enpassant(move)) {
|
if (is_enpassant(move)) {
|
||||||
return pos->en_passant + sq_up(them) == checker;
|
return ep + sq_up(them) == ctz64(checkers);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
//bitboard_t between = bb_between[king][checker] | pos->checkers;
|
|
||||||
//return mask(to) & between;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (3) - pinned pieces
|
/* (3) - pinned pieces
|
||||||
* We verify here that pinned piece P stays on line King-P.
|
* We verify here that pinned piece P stays on line between K & dest square.
|
||||||
*/
|
*/
|
||||||
if (BIT(from) & pos->blockers) {
|
if (pinned) {
|
||||||
return bb_line[from][king] & BIT(to); /* is to on pinner line ? */
|
return bb_line[from][kingsq] & BIT(to); /* is to on pinner line ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (4) - En-passant
|
/* (4) - En-passant
|
||||||
* pinned pieces are handled in pinned section.
|
* pinned piece is already handled in (3).
|
||||||
* One case not handled anywhere else: when the two "disappearing" pawns
|
* One case not handled anywhere else: when the two "disappearing" pawns
|
||||||
* would discover a R/Q horizontal check.
|
* would discover a R/Q horizontal check.
|
||||||
|
* Note: grabbed pawn *cannot* discover a check (impossible position).
|
||||||
*/
|
*/
|
||||||
if (unlikely(is_enpassant(move))) {
|
if (is_enpassant(move)) {
|
||||||
bitboard_t rank5 = bb_rel_rank(RANK_5, us);
|
bitboard_t rank5 = bb_rel_rank(RANK_5, us);
|
||||||
|
|
||||||
if (unlikely((pos->bb[us][KING] & rank5))) {
|
if (kingbb & rank5) {
|
||||||
bitboard_t exclude = BIT(pos->en_passant - sq_up(us)) | BIT(from);
|
bitboard_t exclude = BIT(ep + sq_up(them)) | BIT(from);
|
||||||
bitboard_t rooks = (pos->bb[them][ROOK] | pos->bb[them][QUEEN]) & rank5;
|
bitboard_t rooks = (pos->bb[them][ROOK] | pos->bb[them][QUEEN]) & rank5;
|
||||||
|
|
||||||
if (hyperbola_rank_moves(occ ^ exclude, king) & rooks)
|
return !(hyperbola_rank_moves(occ ^ exclude, kingsq) & rooks);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -349,12 +345,12 @@ movelist_t *pos_gen_pseudo(pos_t *pos, movelist_t *movelist)
|
|||||||
bitboard_t dest_squares = ~my_pieces;
|
bitboard_t dest_squares = ~my_pieces;
|
||||||
bitboard_t occ = my_pieces | enemy_pieces;
|
bitboard_t occ = my_pieces | enemy_pieces;
|
||||||
bitboard_t empty = ~occ;
|
bitboard_t empty = ~occ;
|
||||||
|
move_t *moves = movelist->move;
|
||||||
|
square_t king = pos->king[us];
|
||||||
|
|
||||||
bitboard_t from_bb, to_bb;
|
bitboard_t from_bb, to_bb;
|
||||||
bitboard_t tmp_bb;
|
bitboard_t tmp_bb;
|
||||||
move_t *moves = movelist->move;
|
|
||||||
square_t from, to;
|
square_t from, to;
|
||||||
square_t king = pos->king[us];
|
|
||||||
|
|
||||||
/* king - MUST BE FIRST */
|
/* king - MUST BE FIRST */
|
||||||
to_bb = bb_king_moves(dest_squares, king);
|
to_bb = bb_king_moves(dest_squares, king);
|
||||||
@@ -379,6 +375,8 @@ movelist_t *pos_gen_pseudo(pos_t *pos, movelist_t *movelist)
|
|||||||
* To square attack check will be done in gen_is_legal.
|
* To square attack check will be done in gen_is_legal.
|
||||||
*/
|
*/
|
||||||
if (can_oo(pos->castle, us)) {
|
if (can_oo(pos->castle, us)) {
|
||||||
|
|
||||||
|
/* CHANGE HERE, either with bitmask >> or direct sq check */
|
||||||
bitboard_t occmask = rel_rank1 & (FILE_Fbb | FILE_Gbb);
|
bitboard_t occmask = rel_rank1 & (FILE_Fbb | FILE_Gbb);
|
||||||
if (!(occ & occmask)) {
|
if (!(occ & occmask)) {
|
||||||
*moves++ = move_make_flags(king, king + 2, M_CASTLE_K);
|
*moves++ = move_make_flags(king, king + 2, M_CASTLE_K);
|
||||||
|
Reference in New Issue
Block a user