// static Move MoveChecker::complete(IncompleteMove incomplete_move, const ChessBoard& board) { const Position src(incomplete_move.source()); const Piece::piece_index_t piece_index = board.piece_index(src); const Position dst(incomplete_move.destination()); const int color_index = static_cast<int>(board.turn_color()); if (BitBoard(src) & BitBoard(MagicNumbers::c_king_positions[color_index]) && BitBoard(dst) & BitBoard(MagicNumbers::c_castle_squares[color_index]) && piece_index == PieceSet::c_king_index) { if (dst.column() == Position::c_kings_knight_column) { return Move(src, dst, Move::c_castle_k_flag); } else { assert(dst.column() == Position::c_queens_bishop_column); return Move(src, dst, Move::c_castle_q_flag); } } const BitBoard capturable = board.opponents(); const BitBoard dst_board(dst); const bool is_capture = capturable & dst_board; if (piece_index == PieceSet::c_pawn_index) { if (board.ep_captures() & dst_board) { return Move(src, dst, Move::c_ep_flag); } else if (incomplete_move.is_promotion()) { const uint16_t flags = (static_cast<uint16_t>(is_capture) << 14) | incomplete_move.m_state; return Move(src, dst, flags); } else if (abs(src.row() - dst.row()) == 2) { return Move(src, dst, Move::c_double_pawn_push_flag); } } return Move(src, dst, is_capture << 14); }
void Board::MovePiece(int from, int to, int piece) { ulong mask = BitBoard(from) ^ BitBoard(to); int pieceType = Pieces::GetPieceTypeFromPiece(piece); pieceBitBoards[pieceType] ^= mask; int color = Pieces::GetColorFromPiece(piece); colorBitBoards[color] ^= mask; occupiedSquares ^= mask; pieces[from] = Pieces::None; pieces[to] = piece; }
ulong Board::GetSafeKingMoves(int color) { ulong safeMoves = 0; int kingSquare = GetKingSquare(color); ulong moves = MoveGenerator::kingAttacks[kingSquare]; ulong newMoves = moves & (~colorBitBoards[color]); moves = newMoves; if(moves != 0) { RemovePiece(kingSquare, Pieces::GetPiece(PieceTypes::King, color)); while(moves != 0) { int move = PopLowestSetBit(moves); if(!IsSquareAttacked(move, OtherColor(color))) { safeMoves |= BitBoard(move); } } AddPiece(kingSquare, Pieces::GetPiece(PieceTypes::King, color)); } return safeMoves; }
//! Make BitBoard containing original BitBoard and one more square //! @param lhs another square //! @param rhs original BitBoard //! @return resulting BitBoard constexpr BitBoard operator|(Square lhs, BitBoard rhs) { return BitBoard(lhs) | rhs; }
//! Make BitBoard containing original BitBoard and one more square //! @param lhs original BitBoard //! @param rhs another square //! @return resulting BitBoard constexpr BitBoard operator|(BitBoard lhs, Square rhs) { return lhs | BitBoard(rhs); }
//! Make BitBoard containing two squares //! @param lhs one square //! @param rhs another square //! @return BitBoard containing both squares constexpr BitBoard operator|(Square lhs, Square rhs) { return BitBoard(BitBoard(lhs) | BitBoard(rhs)); }
//! Make inverted BitBoard //! @param bb original BitBoard //! @return BitBoard with all bits inverted //! //! This means that new BitBoard will contain only those squares //! that original one does not contain. constexpr BitBoard operator~(BitBoard bb) { return BitBoard(~bb.data()); }
//! Make BitBoard intersected with another one //! @param lhs one BitBoard //! @param rhs another BitBoard //! @return BitBoard containing all squares that both bitboards contain constexpr BitBoard operator&(BitBoard lhs, BitBoard rhs) { return BitBoard(lhs.data() & rhs.data()); }
//! Add Square to BitBoard //! @param rhs another BitBoard //! @return reference to self BitBoard &operator|=(Square rhs) { data_ |= BitBoard(rhs).data_; return *this; }