2424#include < sstream>
2525#include " utils/exception.h"
2626
27+ #ifdef _MSC_VER
28+ #include < nmmintrin.h>
29+ #endif
30+
2731namespace lczero {
2832
2933using std::string;
@@ -199,7 +203,8 @@ MoveList ChessBoard::GeneratePseudovalidMoves() const {
199203 }
200204 }
201205 if (can_castle) {
202- result.emplace_back (source, BoardSquare (0 , 6 ));
206+ result.emplace_back (source, BoardSquare (0 , 7 ));
207+ result.back ().SetCastling ();
203208 }
204209 }
205210 if (castlings_.we_can_000 ()) {
@@ -219,7 +224,8 @@ MoveList ChessBoard::GeneratePseudovalidMoves() const {
219224 }
220225 }
221226 if (can_castle) {
222- result.emplace_back (source, BoardSquare (0 , 2 ));
227+ result.emplace_back (source, BoardSquare (0 , 0 ));
228+ result.back ().SetCastling ();
223229 }
224230 }
225231 continue ;
@@ -303,7 +309,7 @@ MoveList ChessBoard::GeneratePseudovalidMoves() const {
303309 // Ordinary capture.
304310 result.emplace_back (source, destination);
305311 }
306- } else if (dst_row == 5 and pawns_.get (7 , dst_col)) {
312+ } else if (dst_row == 5 && pawns_.get (7 , dst_col)) {
307313 // En passant.
308314 result.emplace_back (source, destination);
309315 }
@@ -330,9 +336,9 @@ bool ChessBoard::ApplyMove(Move move) {
330336 const auto to_row = to.row ();
331337 const auto to_col = to.col ();
332338
333- // Move in our pieces.
339+ // Remove our piece from old location, but not put to destination
340+ // (for the case of castling).
334341 our_pieces_.reset (from);
335- our_pieces_.set (to);
336342
337343 // Remove captured piece
338344 bool reset_50_moves = their_pieces_.get (to);
@@ -364,24 +370,33 @@ bool ChessBoard::ApplyMove(Move move) {
364370 if (from == our_king_) {
365371 castlings_.reset_we_can_00 ();
366372 castlings_.reset_we_can_000 ();
367- our_king_ = to;
368373 // Castling
369- if (to_col - from_col == 2 ) {
374+ if (to_col - from_col > 1 ) {
370375 // 0-0
371376 our_pieces_.reset (7 );
372377 rooks_.reset (7 );
373378 our_pieces_.set (5 );
374379 rooks_.set (5 );
375- } else if (from_col - to_col == 2 ) {
380+ our_king_ = BoardSquare (0 , 6 ); /* g8 */
381+ our_pieces_.set (our_king_);
382+ } else if (from_col - to_col > 1 ) {
376383 // 0-0-0
377384 our_pieces_.reset (0 );
378385 rooks_.reset (0 );
379386 our_pieces_.set (3 );
380387 rooks_.set (3 );
388+ our_king_ = BoardSquare (0 , 2 ); /* c8 */
389+ our_pieces_.set (our_king_);
390+ } else {
391+ our_king_ = to;
392+ our_pieces_.set (to);
381393 }
382394 return reset_50_moves;
383395 }
384396
397+ // Now destination square for our piece is known.
398+ our_pieces_.set (to);
399+
385400 // Promotion
386401 if (move.promotion () != Move::Promotion::None) {
387402 switch (move.promotion ()) {
@@ -418,7 +433,7 @@ bool ChessBoard::ApplyMove(Move move) {
418433 pawns_.reset (from);
419434
420435 // Set en passant flag.
421- if (to_row - from_row == 2 and pawns_.get (to)) {
436+ if (to_row - from_row == 2 && pawns_.get (to)) {
422437 pawns_.set (0 , to_col);
423438 }
424439 return reset_50_moves;
@@ -600,8 +615,13 @@ bool ChessBoard::HasMatingMaterial() const {
600615 return true ;
601616 }
602617
618+ #ifdef _MSC_VER
619+ int our = _mm_popcnt_u64 (our_pieces_.as_int ());
620+ int their = _mm_popcnt_u64 (their_pieces_.as_int ());
621+ #else
603622 int our = __builtin_popcountll (our_pieces_.as_int ());
604623 int their = __builtin_popcountll (their_pieces_.as_int ());
624+ #endif
605625 if (our > 2 || their > 2 ) {
606626 return true ;
607627 }
@@ -661,7 +681,8 @@ string ChessBoard::DebugString() const {
661681 }
662682 if (i == 0 ) {
663683 result += " " + castlings_.as_string ();
664- result += flipped_ ? " (from black's eyes)" : " (from white's eyes)" ;
684+ result += flipped_ ? " (from black's eyes)" : " (from white's eyes)" ;
685+ result += " Hash: " + std::to_string (Hash ());
665686 }
666687 result += ' \n ' ;
667688 }
0 commit comments