X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmovegen.cpp;h=ed09d44b7a82c7b63d93c49fb1af9068e7b35a06;hb=84d6fe0f31069bc612f856ab7cd54d9aad7907ca;hp=bfeb7247c56b9c97085fc5ad2b26e57cb4eff8a7;hpb=9e4befe3f1ea324bece88aee2e97b38659411c52;p=stockfish diff --git a/src/movegen.cpp b/src/movegen.cpp index bfeb7247..ed09d44b 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -135,7 +135,7 @@ namespace { /// generate_captures generates() all pseudo-legal captures and queen -/// promotions. The return value is the number of moves generated. +/// promotions. Returns a pointer to the end of the move list. MoveStack* generate_captures(const Position& pos, MoveStack* mlist) { @@ -155,7 +155,7 @@ MoveStack* generate_captures(const Position& pos, MoveStack* mlist) { /// generate_noncaptures() generates all pseudo-legal non-captures and -/// underpromotions. The return value is the number of moves generated. +/// underpromotions. Returns a pointer to the end of the move list. MoveStack* generate_noncaptures(const Position& pos, MoveStack* mlist) { @@ -177,7 +177,7 @@ MoveStack* generate_noncaptures(const Position& pos, MoveStack* mlist) { /// generate_non_capture_checks() generates all pseudo-legal non-capturing, -/// non-promoting checks. It returns the number of generated moves. +/// non-promoting checks. Returns a pointer to the end of the move list. MoveStack* generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { @@ -214,7 +214,7 @@ MoveStack* generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bi /// generate_evasions() generates all check evasions when the side to move is /// in check. Unlike the other move generation functions, this one generates -/// only legal moves. It returns the number of generated moves. +/// only legal moves. Returns a pointer to the end of the move list. MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned) { @@ -235,17 +235,17 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin // Find squares attacked by slider checkers, we will // remove them from king evasions set so to avoid a couple // of cycles in the slow king evasions legality check loop - // and to be able to use square_is_attacked(). + // and to be able to use attackers_to(). Bitboard checkers = pos.checkers(); Bitboard checkersAttacks = EmptyBoardBB; - Bitboard b = checkers & (pos.queens() | pos.bishops()); + Bitboard b = checkers & pos.pieces(BISHOP, QUEEN); while (b) { from = pop_1st_bit(&b); checkersAttacks |= bishop_attacks_bb(from, b_noKing); } - b = checkers & (pos.queens() | pos.rooks()); + b = checkers & pos.pieces(ROOK, QUEEN); while (b) { from = pop_1st_bit(&b); @@ -253,13 +253,14 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin } // Generate evasions for king - Bitboard b1 = pos.piece_attacks(ksq) & ~pos.pieces_of_color(us) & ~checkersAttacks; + Bitboard b1 = pos.piece_attacks_from(ksq) & ~pos.pieces_of_color(us) & ~checkersAttacks; + Bitboard enemy = pos.pieces_of_color(them); while (b1) { to = pop_1st_bit(&b1); - // Note that we can use square_is_attacked() only because we + // Note that we can use attackers_to() only because we // have already removed slider checkers. - if (!pos.square_is_attacked(to, them)) + if (!(pos.attackers_to(to) & enemy)) (*mlist++).move = make_move(ksq, to); } @@ -275,7 +276,7 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin // Generate captures of the checking piece // Pawn captures - b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & ~pinned; + b1 = pos.pawn_attacks_from(checksq, them) & pos.pieces(PAWN, us) & ~pinned; while (b1) { from = pop_1st_bit(&b1); @@ -290,9 +291,9 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin } // Pieces captures - b1 = ( (pos.piece_attacks(checksq) & pos.knights(us)) - | (pos.piece_attacks(checksq) & pos.bishops_and_queens(us)) - | (pos.piece_attacks(checksq) & pos.rooks_and_queens(us)) ) & ~pinned; + b1 = ( (pos.piece_attacks_from(checksq) & pos.pieces(KNIGHT, us)) + | (pos.piece_attacks_from(checksq) & pos.pieces(BISHOP, QUEEN, us)) + | (pos.piece_attacks_from(checksq) & pos.pieces(ROOK, QUEEN, us)) ) & ~pinned; while (b1) { @@ -302,7 +303,7 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin // Blocking check evasions are possible only if the checking piece is // a slider. - if (checkers & pos.sliders()) + if (checkers & (pos.pieces(BISHOP) | pos.pieces(ROOK) | pos.pieces(QUEEN))) { Bitboard blockSquares = squares_between(checksq, ksq); @@ -323,10 +324,10 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin // check. If pos.ep_square() is set, the last move made must have been // a double pawn push. If, furthermore, the checking piece is a pawn, // an en passant check evasion may be possible. - if (pos.ep_square() != SQ_NONE && (checkers & pos.pawns(them))) + if (pos.ep_square() != SQ_NONE && (checkers & pos.pieces(PAWN, them))) { to = pos.ep_square(); - b1 = pos.pawn_attacks(them, to) & pos.pawns(us); + b1 = pos.pawn_attacks_from(to, them) & pos.pieces(PAWN, us); // The checking pawn cannot be a discovered (bishop) check candidate // otherwise we were in check also before last double push move. @@ -441,7 +442,7 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) { // is occupied or under attack. for (s = Min(from, g1); s <= Max(from, g1); s++) if ( (s != from && s != to && !pos.square_is_empty(s)) - || pos.square_is_attacked(s, them)) + ||(pos.attackers_to(s) & pos.pieces_of_color(them))) illegal = true; // Check if any of the squares between king and rook @@ -472,7 +473,7 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) { for (s = Min(from, c1); s <= Max(from, c1); s++) if( (s != from && s != to && !pos.square_is_empty(s)) - || pos.square_is_attacked(s, them)) + ||(pos.attackers_to(s) & pos.pieces_of_color(them))) illegal = true; for (s = Min(to, d1); s <= Max(to, d1); s++) @@ -557,7 +558,7 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) { } // Luckly we can handle all the other pieces in one go - return ( pos.piece_attacks_square(pos.piece_on(from), from, to) + return ( bit_is_set(pos.piece_attacks_from(pc, from), to) && pos.pl_move_is_legal(m, pinned) && !move_is_promotion(m)); } @@ -598,7 +599,7 @@ namespace { for (int i = 0, e = pos.piece_count(us, Piece); i < e; i++) { from = pos.piece_list(us, Piece, i); - b = pos.piece_attacks(from) & target; + b = pos.piece_attacks_from(from) & target; SERIALIZE_MOVES(b); } return mlist; @@ -616,7 +617,7 @@ namespace { if (pinned && bit_is_set(pinned, from)) continue; - b = pos.piece_attacks(from) & target; + b = pos.piece_attacks_from(from) & target; SERIALIZE_MOVES(b); } return mlist; @@ -628,7 +629,7 @@ namespace { Bitboard b; Square from = pos.king_square(us); - b = pos.piece_attacks(from) & target; + b = pos.piece_attacks_from(from) & target; SERIALIZE_MOVES(b); return mlist; } @@ -675,7 +676,7 @@ namespace { const SquareDelta TDELTA_N = (Us == WHITE ? DELTA_N : DELTA_S); Square to; - Bitboard pawns = pos.pawns(Us); + Bitboard pawns = pos.pieces(PAWN, Us); Bitboard enemyPieces = pos.pieces_of_color(opposite_color(Us)); bool possiblePromotion = (pawns & TRank7BB); @@ -700,7 +701,7 @@ namespace { assert(Us != WHITE || square_rank(pos.ep_square()) == RANK_6); assert(Us != BLACK || square_rank(pos.ep_square()) == RANK_3); - Bitboard b1 = pawns & pos.pawn_attacks(Them, pos.ep_square()); + Bitboard b1 = pawns & pos.pawn_attacks_from(pos.ep_square(), Them); assert(b1 != EmptyBoardBB); while (b1) @@ -725,7 +726,7 @@ namespace { Bitboard b1, b2; Square to; - Bitboard pawns = pos.pawns(Us); + Bitboard pawns = pos.pieces(PAWN, Us); Bitboard emptySquares = pos.empty_squares(); if (pawns & TRank7BB) // There is some promotion candidate ? @@ -786,7 +787,7 @@ namespace { Square to; Bitboard b1, b2, b3; - Bitboard pawns = pos.pawns(Us); + Bitboard pawns = pos.pieces(PAWN, Us); if (dc & pawns) { @@ -819,11 +820,11 @@ namespace { // Direct checks, single pawn pushes Bitboard empty = pos.empty_squares(); b2 = move_pawns(b1) & empty; - b3 = b2 & pos.pawn_attacks(Them, ksq); + b3 = b2 & pos.pawn_attacks_from(ksq, Them); SERIALIZE_MOVES_D(b3, -TDELTA_N); // Direct checks, double pawn pushes - b3 = move_pawns(b2 & TRank3BB) & empty & pos.pawn_attacks(Them, ksq); + b3 = move_pawns(b2 & TRank3BB) & empty & pos.pawn_attacks_from(ksq, Them); SERIALIZE_MOVES_D(b3, -TDELTA_N -TDELTA_N); return mlist; } @@ -832,14 +833,14 @@ namespace { MoveStack* generate_piece_checks(const Position& pos, MoveStack* mlist, Color us, Bitboard dc, Square ksq) { - Bitboard target = pos.pieces_of_color_and_type(us, Piece); + Bitboard target = pos.pieces(Piece, us); // Discovered checks Bitboard b = target & dc; while (b) { Square from = pop_1st_bit(&b); - Bitboard bb = pos.piece_attacks(from) & pos.empty_squares(); + Bitboard bb = pos.piece_attacks_from(from) & pos.empty_squares(); if (Piece == KING) bb &= ~QueenPseudoAttacks[ksq]; @@ -850,7 +851,7 @@ namespace { b = target & ~dc; if (Piece != KING || b) { - Bitboard checkSqs = pos.piece_attacks(ksq) & pos.empty_squares(); + Bitboard checkSqs = pos.piece_attacks_from(ksq) & pos.empty_squares(); if (!checkSqs) return mlist; @@ -862,7 +863,7 @@ namespace { || (Piece == BISHOP && !(BishopPseudoAttacks[from] & checkSqs))) continue; - Bitboard bb = pos.piece_attacks(from) & checkSqs; + Bitboard bb = pos.piece_attacks_from(from) & checkSqs; SERIALIZE_MOVES(bb); } } @@ -881,7 +882,7 @@ namespace { Square to; // Find non-pinned pawns and push them one square - Bitboard b1 = move_pawns(pos.pawns(Us) & ~pinned); + Bitboard b1 = move_pawns(pos.pieces(PAWN, Us) & ~pinned); // We don't have to AND with empty squares here, // because the blocking squares will always be empty. @@ -942,7 +943,7 @@ namespace { // It is a bit complicated to correctly handle Chess960 for (s = Min(ksq, s1); s <= Max(ksq, s1); s++) if ( (s != ksq && s != rsq && pos.square_is_occupied(s)) - || pos.square_is_attacked(s, them)) + ||(pos.attackers_to(s) & pos.pieces_of_color(them))) illegal = true; for (s = Min(rsq, s2); s <= Max(rsq, s2); s++)