From: Marco Costalba Date: Sun, 16 Sep 2012 12:06:13 +0000 (+0200) Subject: Fix crash under Chess 960 X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=22a5f91aa79e065387e780bbffc1bbadfd84e8d6;hp=9ce74698463d0b3320892b060f0fbac70415f033;ds=inline Fix crash under Chess 960 We have a crash with this position: rkqbnnbr/pppppppp/8/8/8/8/PPPPPPPP/RKQBNNBR w HAha - What happens is that even if we are castling QUEEN_SIDE, in this case we have kfrom (B8) < kto (C8) so the loop that checks for attackers runs forever leading to a crash. The fix is to check for (kto > kfrom) instead of Side == KING_SIDE, but this is slower in the normal case of ortodhox chess, so rewrite generate_castle() to handle the chess960 case as a template parameter and allow the compiler to optimize out the comparison in case of normal chess. Reported by Ray Banks. --- diff --git a/src/movegen.cpp b/src/movegen.cpp index 4a190345..be848cf1 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -31,7 +31,7 @@ (*mlist++).move = make_move(to - (d), to); } namespace { - template + template MoveStack* generate_castle(const Position& pos, MoveStack* mlist, Color us) { if (pos.castle_impeded(us, Side) || !pos.can_castle(make_castle_right(us, Side))) @@ -46,16 +46,18 @@ namespace { assert(!pos.in_check()); - for (Square s = kto; s != kfrom; s += (Square)(Side == KING_SIDE ? -1 : 1)) + const int K = Chess960 ? kto > kfrom ? -1 : 1 + : Side == KING_SIDE ? -1 : 1; + + for (Square s = kto; s != kfrom; s += (Square)K) if (pos.attackers_to(s) & enemies) return mlist; // Because we generate only legal castling moves we need to verify that // when moving the castling rook we do not discover some hidden checker. // For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1. - if ( pos.is_chess960() - && (pos.attackers_to(kto, pos.pieces() ^ rfrom) & enemies)) - return mlist; + if (Chess960 && (pos.attackers_to(kto, pos.pieces() ^ rfrom) & enemies)) + return mlist; (*mlist++).move = make(kfrom, rfrom); @@ -273,8 +275,16 @@ namespace { if (Type != CAPTURES && Type != EVASIONS && pos.can_castle(us)) { - mlist = generate_castle(pos, mlist, us); - mlist = generate_castle(pos, mlist, us); + if (pos.is_chess960()) + { + mlist = generate_castle(pos, mlist, us); + mlist = generate_castle(pos, mlist, us); + } + else + { + mlist = generate_castle(pos, mlist, us); + mlist = generate_castle(pos, mlist, us); + } } return mlist;