X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fmovegen.cpp;h=78533a9e75acf3f8fe4421e3bb4d49db99716311;hp=f22df724952a81d82cac66616c6921641b560d5e;hb=1dc1cecf01352a39bc1b80c83f6e8e4e97d859e1;hpb=9bffe811c44b88ba3b5dd0904539c8ca14257a35 diff --git a/src/movegen.cpp b/src/movegen.cpp index f22df724..78533a9e 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -40,46 +40,46 @@ namespace { QUEEN_SIDE }; - static const bool CAPTURE = true; - static const bool NON_CAPTURE = false; + const bool CAPTURE = true; + const bool NON_CAPTURE = false; - // Function + // Functions bool castling_is_check(const Position&, CastlingSide); - // Main templates + // Helper templates template - MoveStack* generate_castle_moves(const Position&, MoveStack*); - - template - MoveStack* generate_piece_checks(const Position&, MoveStack*, Color us, Bitboard, Square); + MoveStack* generate_castle_moves(const Position& pos, MoveStack* mlist); - // Helper templates template - MoveStack* do_generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned, - Bitboard blockSquares, MoveStack* mlist); + MoveStack* generate_pawn_blocking_evasions(const Position&, Bitboard, Bitboard, MoveStack*); template - MoveStack* do_generate_pawn_captures(const Position& pos, MoveStack* mlist); + MoveStack* generate_pawn_captures(const Position& pos, MoveStack* mlist); template - MoveStack* do_generate_pawn_noncaptures(const Position& pos, MoveStack* mlist); + MoveStack* generate_pawn_noncaptures(const Position& pos, MoveStack* mlist); - // Template generate_pawn_checks() with specializations template - MoveStack* do_generate_pawn_checks(const Position&, Bitboard, Square, MoveStack*); + MoveStack* generate_pawn_checks(const Position&, Bitboard, Square, MoveStack*); + + // Template generate_piece_checks() with specializations + template + MoveStack* generate_piece_checks(const Position&, MoveStack*, Color, Bitboard, Square); - template - inline MoveStack* generate_pawn_checks(const Position& p, MoveStack* m, Bitboard dc, Square ksq) { - return do_generate_pawn_checks(p, dc, ksq, m); - } template<> - inline MoveStack* generate_pawn_checks(const Position& p, MoveStack* m, Bitboard dc, Square ksq) { - return do_generate_pawn_checks(p, dc, ksq, m); + inline MoveStack* generate_piece_checks(const Position& p, MoveStack* m, Color us, Bitboard dc, Square ksq) { + + if (us == WHITE) + return generate_pawn_checks(p, dc, ksq, m); + else + return generate_pawn_checks(p, dc, ksq, m); + } // Template generate_piece_moves() with specializations template MoveStack* generate_piece_moves(const Position&, MoveStack*, Color us, Bitboard); + template<> MoveStack* generate_piece_moves(const Position& pos, MoveStack* mlist, Color us, Bitboard target); @@ -89,11 +89,11 @@ namespace { assert(Piece == PAWN); if (Capture) - return (us == WHITE ? do_generate_pawn_captures(p, m) - : do_generate_pawn_captures(p, m)); + return (us == WHITE ? generate_pawn_captures(p, m) + : generate_pawn_captures(p, m)); else - return (us == WHITE ? do_generate_pawn_noncaptures(p, m) - : do_generate_pawn_noncaptures(p, m)); + return (us == WHITE ? generate_pawn_noncaptures(p, m) + : generate_pawn_noncaptures(p, m)); } // Template generate_piece_blocking_evasions() with specializations @@ -101,7 +101,13 @@ namespace { MoveStack* generate_piece_blocking_evasions(const Position&, MoveStack*, Color us, Bitboard, Bitboard); template<> - MoveStack* generate_piece_blocking_evasions(const Position& p, MoveStack* m, Color us, Bitboard np, Bitboard bs); + inline MoveStack* generate_piece_blocking_evasions(const Position& p, MoveStack* m, Color us, + Bitboard pnd, Bitboard bs) { + if (us == WHITE) + return generate_pawn_blocking_evasions(p, pnd, bs, m); + else + return generate_pawn_blocking_evasions(p, pnd, bs, m); + } } @@ -170,13 +176,8 @@ int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { assert(pos.piece_on(ksq) == king_of_color(opposite_color(us))); - // Pawn moves - if (us == WHITE) - mlist = generate_pawn_checks(pos, mlist, dc, ksq); - else - mlist = generate_pawn_checks(pos, mlist, dc, ksq); - // Pieces moves + mlist = generate_piece_checks(pos, mlist, us, dc, ksq); mlist = generate_piece_checks(pos, mlist, us, dc, ksq); mlist = generate_piece_checks(pos, mlist, us, dc, ksq); mlist = generate_piece_checks(pos, mlist, us, dc, ksq); @@ -203,7 +204,7 @@ int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { /// only legal moves. It returns the number of generated moves. This /// function is very ugly, and needs cleaning up some time later. FIXME -int generate_evasions(const Position& pos, MoveStack* mlist) { +int generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned) { assert(pos.is_ok()); assert(pos.is_check()); @@ -267,13 +268,10 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { assert(pos.color_of_piece_on(checksq) == them); - // Find pinned pieces - Bitboard not_pinned = ~pos.pinned_pieces(us); - // Generate captures of the checking piece // Pawn captures - b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & not_pinned; + b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & ~pinned; while (b1) { from = pop_1st_bit(&b1); @@ -290,7 +288,7 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { // 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)) ) & not_pinned; + | (pos.piece_attacks(checksq) & pos.rooks_and_queens(us)) ) & ~pinned; while (b1) { @@ -299,7 +297,7 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { } // Blocking check evasions are possible only if the checking piece is - // a slider + // a slider. if (checkers & pos.sliders()) { Bitboard blockSquares = squares_between(checksq, ksq); @@ -307,11 +305,11 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB); // Pieces moves - mlist = generate_piece_blocking_evasions(pos, mlist, us, not_pinned, blockSquares); - mlist = generate_piece_blocking_evasions(pos, mlist, us, not_pinned, blockSquares); - mlist = generate_piece_blocking_evasions(pos, mlist, us, not_pinned, blockSquares); - mlist = generate_piece_blocking_evasions(pos, mlist, us, not_pinned, blockSquares); - mlist = generate_piece_blocking_evasions(pos, mlist, us, not_pinned, blockSquares); + mlist = generate_piece_blocking_evasions(pos, mlist, us, pinned, blockSquares); + mlist = generate_piece_blocking_evasions(pos, mlist, us, pinned, blockSquares); + mlist = generate_piece_blocking_evasions(pos, mlist, us, pinned, blockSquares); + mlist = generate_piece_blocking_evasions(pos, mlist, us, pinned, blockSquares); + mlist = generate_piece_blocking_evasions(pos, mlist, us, pinned, blockSquares); } // Finally, the ugly special case of en passant captures. An en passant @@ -326,7 +324,7 @@ int generate_evasions(const Position& pos, MoveStack* mlist) { assert(b1 != EmptyBoardBB); - b1 &= not_pinned; + b1 &= ~pinned; while (b1) { from = pop_1st_bit(&b1); @@ -360,15 +358,15 @@ int generate_legal_moves(const Position& pos, MoveStack* mlist) { assert(pos.is_ok()); + Bitboard pinned = pos.pinned_pieces(pos.side_to_move()); + if (pos.is_check()) - return generate_evasions(pos, mlist); + return generate_evasions(pos, mlist, pinned); // Generate pseudo-legal moves int n = generate_captures(pos, mlist); n += generate_noncaptures(pos, mlist + n); - Bitboard pinned = pos.pinned_pieces(pos.side_to_move()); - // Remove illegal moves from the list for (int i = 0; i < n; i++) if (!pos.pl_move_is_legal(mlist[i].move, pinned)) @@ -588,31 +586,26 @@ namespace { template MoveStack* generate_piece_blocking_evasions(const Position& pos, MoveStack* mlist, Color us, - Bitboard not_pinned, Bitboard blockSquares) { + Bitboard pinned, Bitboard blockSquares) { + Square from; + Bitboard b; - Bitboard b = pos.pieces_of_color_and_type(us, Piece) & not_pinned; - while (b) + for (int i = 0, e = pos.piece_count(us, Piece); i < e; i++) { - Square from = pop_1st_bit(&b); - Bitboard bb = pos.piece_attacks(from) & blockSquares; - SERIALIZE_MOVES(bb); + from = pos.piece_list(us, Piece, i); + if (pinned && bit_is_set(pinned, from)) + continue; + + b = pos.piece_attacks(from) & blockSquares; + SERIALIZE_MOVES(b); } return mlist; } - template<> - MoveStack* generate_piece_blocking_evasions(const Position& p, MoveStack* m, Color us, - Bitboard np, Bitboard bs) { - if (us == WHITE) - return do_generate_pawn_blocking_evasions(p, np, bs, m); - else - return do_generate_pawn_blocking_evasions(p, np, bs, m); - } - template - MoveStack* do_generate_pawn_captures(const Position& pos, MoveStack* mlist) { + MoveStack* generate_pawn_captures(const Position& pos, MoveStack* mlist) { Square to; Bitboard pawns = pos.pawns(Us); @@ -685,7 +678,7 @@ namespace { template - MoveStack* do_generate_pawn_noncaptures(const Position& pos, MoveStack* mlist) { + MoveStack* generate_pawn_noncaptures(const Position& pos, MoveStack* mlist) { Bitboard pawns = pos.pawns(Us); Bitboard enemyPieces = pos.pieces_of_color(Them); @@ -742,7 +735,7 @@ namespace { template - MoveStack* do_generate_pawn_checks(const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist) + MoveStack* generate_pawn_checks(const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist) { // Find all friendly pawns not on the enemy king's file Bitboard b1, b2, b3; @@ -831,12 +824,12 @@ namespace { } template - MoveStack* do_generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned, - Bitboard blockSquares, MoveStack* mlist) { + MoveStack* generate_pawn_blocking_evasions(const Position& pos, Bitboard pinned, + Bitboard blockSquares, MoveStack* mlist) { Square to; // Find non-pinned pawns - Bitboard b1 = pos.pawns(Us) & not_pinned; + Bitboard b1 = pos.pawns(Us) & ~pinned; // Single pawn pushes. We don't have to AND with empty squares here, // because the blocking squares will always be empty. @@ -859,7 +852,7 @@ namespace { // Double pawn pushes b2 = (Us == WHITE ? b1 << 8 : b1 >> 8) & pos.empty_squares() & TRank3BB; - b2 = (Us == WHITE ? b2 << 8 : b2 >> 8) & blockSquares;; + b2 = (Us == WHITE ? b2 << 8 : b2 >> 8) & blockSquares; while (b2) { to = pop_1st_bit(&b2);