nkarve / surge

A fast bitboard-based chess move generator in C++
MIT License
63 stars 15 forks source link

Calling Position::set on existing object leads to wrong results #16

Open osvitashev opened 3 years ago

osvitashev commented 3 years ago

As far as i can say Position::set assumes the object is blank and does not clear the existing values in it, which leads to wrong move generation if the object is reused:

  int main() {
   initialise_all_databases();
   zobrist::initialise_zobrist_keys();

   Position p;
   Position::set("8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - ", p);
   auto n = perft<WHITE>(p, 4);
   std::cout<<n<<std::endl;
   Position::set("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", p);
   Position::set("8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - ", p); //same as first position
   n = perft<WHITE>(p, 4); //same as the first perft call
   std::cout << n << std::endl; //this gives wrong perft count

   return 0;
  }
Dark42ed commented 2 years ago

For anyone wondering, the solution is to create a new board and copy over the position.

Position newBoard;
Position::set(brokenBoard.fen(), newBoard);
// Use newBoard from here
nkarve commented 2 years ago

@Dark42ed nice temporary fix, but I'll be reworking Position::set soon, it's the most poorly implemented function in the whole library. The idea of having this function was originally pinched from Stockfish, but I think it would probably go better in the default/copy constructors.