X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmovegen.cpp;h=bfeb7247c56b9c97085fc5ad2b26e57cb4eff8a7;hb=607ac0687a53c764ad548932d35e651c540f4764;hp=079918e96279ddaab10a35ac4e533c87e0180cf1;hpb=3849beb979ee17f027d83bbc15d1da85175b9798;p=stockfish diff --git a/src/movegen.cpp b/src/movegen.cpp index 079918e9..bfeb7247 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -137,36 +137,33 @@ namespace { /// generate_captures generates() all pseudo-legal captures and queen /// promotions. The return value is the number of moves generated. -int generate_captures(const Position& pos, MoveStack* mlist) { +MoveStack* generate_captures(const Position& pos, MoveStack* mlist) { assert(pos.is_ok()); assert(!pos.is_check()); Color us = pos.side_to_move(); Bitboard target = pos.pieces_of_color(opposite_color(us)); - MoveStack* mlist_start = mlist; mlist = generate_piece_moves(pos, mlist, us, target); mlist = generate_piece_moves(pos, mlist, us, target); mlist = generate_piece_moves(pos, mlist, us, target); mlist = generate_piece_moves(pos, mlist, us, target); mlist = generate_piece_moves(pos, mlist, us); - mlist = generate_piece_moves(pos, mlist, us, target); - return int(mlist - mlist_start); + return generate_piece_moves(pos, mlist, us, target); } /// generate_noncaptures() generates all pseudo-legal non-captures and /// underpromotions. The return value is the number of moves generated. -int generate_noncaptures(const Position& pos, MoveStack* mlist) { +MoveStack* generate_noncaptures(const Position& pos, MoveStack* mlist) { assert(pos.is_ok()); assert(!pos.is_check()); Color us = pos.side_to_move(); Bitboard target = pos.empty_squares(); - MoveStack* mlist_start = mlist; mlist = generate_piece_moves(pos, mlist, us); mlist = generate_piece_moves(pos, mlist, us, target); @@ -175,22 +172,20 @@ int generate_noncaptures(const Position& pos, MoveStack* mlist) { mlist = generate_piece_moves(pos, mlist, us, target); mlist = generate_piece_moves(pos, mlist, us, target); mlist = generate_castle_moves(pos, mlist); - mlist = generate_castle_moves(pos, mlist); - return int(mlist - mlist_start); + return generate_castle_moves(pos, mlist); } /// generate_non_capture_checks() generates all pseudo-legal non-capturing, /// non-promoting checks. It returns the number of generated moves. -int generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { +MoveStack* generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bitboard dc) { assert(pos.is_ok()); assert(!pos.is_check()); Color us = pos.side_to_move(); Square ksq = pos.king_square(opposite_color(us)); - MoveStack* mlist_start = mlist; assert(pos.piece_on(ksq) == piece_of_color_and_type(opposite_color(us), KING)); @@ -213,7 +208,7 @@ int generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bitboard && castling_is_check(pos, KING_SIDE)) mlist = generate_castle_moves(pos, mlist); - return int(mlist - mlist_start); + return mlist; } @@ -221,7 +216,7 @@ int generate_non_capture_checks(const Position& pos, MoveStack* mlist, Bitboard /// in check. Unlike the other move generation functions, this one generates /// only legal moves. It returns the number of generated moves. -int generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned) { +MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned) { assert(pos.is_ok()); assert(pos.is_check()); @@ -230,7 +225,6 @@ int generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned) { Color us = pos.side_to_move(); Color them = opposite_color(us); Square ksq = pos.king_square(us); - MoveStack* mlist_start = mlist; assert(pos.piece_on(ksq) == piece_of_color_and_type(us, KING)); @@ -350,7 +344,7 @@ int generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned) { } } } - return int(mlist - mlist_start); + return mlist; } @@ -360,7 +354,7 @@ int generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pinned) { /// very hard to write an efficient legal move generator, but for the moment /// we don't need it. -int generate_legal_moves(const Position& pos, MoveStack* mlist) { +MoveStack* generate_legal_moves(const Position& pos, MoveStack* mlist) { assert(pos.is_ok()); @@ -370,15 +364,17 @@ int generate_legal_moves(const Position& pos, MoveStack* mlist) { return generate_evasions(pos, mlist, pinned); // Generate pseudo-legal moves - int n = generate_captures(pos, mlist); - n += generate_noncaptures(pos, mlist + n); + MoveStack* last = generate_captures(pos, mlist); + last = generate_noncaptures(pos, last); // Remove illegal moves from the list - for (int i = 0; i < n; i++) - if (!pos.pl_move_is_legal(mlist[i].move, pinned)) - mlist[i--].move = mlist[--n].move; - - return n; + for (MoveStack* cur = mlist; cur != last; cur++) + if (!pos.pl_move_is_legal(cur->move, pinned)) + { + cur->move = (--last)->move; + cur--; + } + return last; } @@ -567,6 +563,30 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) { } +/// Another version of move_is_legal(), which takes only a position and a move +/// as input. This function does not require that the side to move is not in +/// check. It is not optimized for speed, and is only used for verifying move +/// legality when building a PV from the transposition table. + +bool move_is_legal(const Position& pos, const Move m) { + + Bitboard pinned = pos.pinned_pieces(pos.side_to_move()); + if (!pos.is_check()) + return move_is_legal(pos, m, pinned); + else + { + Position p(pos); + MoveStack mlist[64]; + MoveStack* last = generate_evasions(p, mlist, pinned); + for (MoveStack* cur = mlist; cur != last; cur++) + if (cur->move == m) + return true; + + return false; + } +} + + namespace { template