Как я могу дополнительно оптимизировать генерацию перемещения в моем шахматном двигателе C ++? [закрыто]C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Как я могу дополнительно оптимизировать генерацию перемещения в моем шахматном двигателе C ++? [закрыто]

Сообщение Anonymous »

Я строю шахматный двигатель в C ++ и в настоящее время работаю над генерацией движения. Чтобы измерить производительность, я использую Perft, но моя главная цель состоит в том, чтобы сделать сам генератор движения быстрее., std :: counst_zero , std :: popcount )
[*] Эффективная компоновка и повторное использование данных (плоские массивы, предварительные маски)
[*] Нет динамических ассигнований

с ними. Реализация: < /p>

Код: Выделить всё

size_t perft(int depth, bool printCountAfterMoves) {
size_t nodes = 0;

MoveList legalMoves = moveGenerator.generateLegalMoves();

if (depth == 1) {
return static_cast(legalMoves.getMovesCount());
}

for (Move move : legalMoves) {
position.makeMove(move);
size_t count = perft(depth - 1, false);

if (printCountAfterMoves) [[unlikely]] {
std::cout pieces[position->usColor * 6 + PT_KING]);
assert(kingSq < 64);

Bitboard occ = position->occForColor[WHITE] | position->occForColor[BLACK];

Bitboard attackMask = computeAttackMask(occ);
Bitboard checkerMask = computeCheckerMask(kingSq, occ);
bool isInCheck = std::popcount(checkerMask) >= 1;
bool isInDoubleCheck = std::popcount(checkerMask) == 2;
// if in normal check and the checking piece is a slider piece, generate the block mask
Bitboard checkBlockMask =
isInCheck && !isInDoubleCheck &&
(checkerMask & ~position->pieces[position->oppColor * 6 + PT_PAWN] &
~position->pieces[position->oppColor * 6 + PT_KNIGHT])
? BETWEEN_MASK[kingSq][std::countr_zero(checkerMask)]
: 0ULL;
Bitboard checkEvasionMask = checkerMask | checkBlockMask;
Bitboard pinMask = computePinMask(kingSq, occ);

Bitboard capturableSquares = ~position->occForColor[position->usColor];
if (!isInDoubleCheck) [[likely]] {
// pawns
Bitboard freeSquares = ~occ;
Bitboard pawns = position->pieces[position->usColor * 6 + PT_PAWN];
while (pawns) {
Bitboard currPawn = pawns & -pawns;
int currPawnSq = std::countr_zero(currPawn);

if (position->usColor == WHITE) {
// we are white
// pushes
Bitboard singlePush = WHITE_PAWN_SINGLE_PUSH_MASK[currPawnSq] & freeSquares;
Bitboard doublePush = ((singlePush & RANK_3) occForColor[position->oppColor];
Bitboard rightCapture = WHITE_PAWN_CAPTURE_RIGHT_MASK[currPawnSq] &
position->occForColor[position->oppColor];

Bitboard normalMoves = singlePush | doublePush | leftCapture | rightCapture;

// en-passant
Bitboard ep =
isEpLegal(kingSq, occ, currPawn)
? (WHITE_PAWN_CAPTURE_LEFT_MASK[currPawnSq] & position->epSquare) |
(WHITE_PAWN_CAPTURE_RIGHT_MASK[currPawnSq] & position->epSquare)
: 0ULL;

if (isInCheck) {
normalMoves &= checkEvasionMask;

// if en-passant does not resolve the check, disallow it
if ((ep >> 8) != checkEvasionMask) {
ep = 0ULL;
}
}

if (currPawn & pinMask) {
normalMoves &= LINE_MASK[currPawnSq][kingSq];
ep &= LINE_MASK[currPawnSq][kingSq];
}

// add en-passant move
if (ep) {
moveList.add(Move(currPawn, ep, PT_PAWN, PT_NULL, false, true));
}

// add each normal move
while (normalMoves) {
Bitboard to = normalMoves & -normalMoves;

// promotion
if (to &  RANK_8) {
moveList.add(Move(currPawn, to, PT_PAWN, PT_KNIGHT, false, false));
moveList.add(Move(currPawn, to, PT_PAWN, PT_BISHOP, false, false));
moveList.add(Move(currPawn, to, PT_PAWN, PT_ROOK, false, false));
moveList.add(Move(currPawn, to, PT_PAWN, PT_QUEEN, false, false));
}
else {
moveList.add(Move(currPawn, to, PT_PAWN, PT_NULL, false, false));
}

normalMoves &= normalMoves - 1;
}
}
else {
// we are black
// pushes
Bitboard singlePush = BLACK_PAWN_SINGLE_PUSH_MASK[currPawnSq] & freeSquares;
Bitboard doublePush = ((singlePush & RANK_6) >> 8) & freeSquares;

// captures
Bitboard leftCapture = BLACK_PAWN_CAPTURE_LEFT_MASK[currPawnSq] &
position->occForColor[position->oppColor];
Bitboard rightCapture = BLACK_PAWN_CAPTURE_RIGHT_MASK[currPawnSq] &
position->occForColor[position->oppColor];

Bitboard normalMoves = singlePush | doublePush | leftCapture | rightCapture;

// en-passant
Bitboard ep =
isEpLegal(kingSq, occ, currPawn)
? (BLACK_PAWN_CAPTURE_LEFT_MASK[currPawnSq] & position->epSquare) |
(BLACK_PAWN_CAPTURE_RIGHT_MASK[currPawnSq] & position->epSquare)
: 0ULL;

if (isInCheck) {
normalMoves &= checkEvasionMask;

// if en-passant does not resolve the check, disallow it
if ((ep pieces[position->usColor * 6 + PT_KNIGHT];
while (knights) {
Bitboard currKnight = knights & -knights;
Bitboard moves = KNIGHT_MOVE_MASK[std::countr_zero(currKnight)] & capturableSquares;

// checks & pins
if (isInCheck) {
moves &= checkEvasionMask;
}

if (currKnight & pinMask) {
moves &= LINE_MASK[std::countr_zero(currKnight)][kingSq];
}

addMovesToList(moveList, currKnight, moves, PT_KNIGHT);
knights &= knights - 1;
}

// bishops
Bitboard bishops = position->pieces[position->usColor * 6 + PT_BISHOP];
while (bishops) {
Bitboard currBishop = bishops & -bishops;
Bitboard moves =
getBishopAttacks(std::countr_zero(currBishop), occ) & capturableSquares;

// checks & pins
if (isInCheck) {
moves &= checkEvasionMask;
}

if (currBishop &  pinMask) {
moves &= LINE_MASK[std::countr_zero(currBishop)][kingSq];
}

addMovesToList(moveList, currBishop, moves, PT_BISHOP);
bishops &= bishops - 1;
}

// rooks
Bitboard rooks = position->pieces[position->usColor * 6 + PT_ROOK];
while (rooks) {
Bitboard currRook = rooks & -rooks;
Bitboard moves = getRookAttacks(std::countr_zero(currRook), occ) & capturableSquares;

// checks & pins
if (isInCheck) {
moves &= checkEvasionMask;
}

if (currRook & pinMask) {
moves &= LINE_MASK[std::countr_zero(currRook)][kingSq];
}

addMovesToList(moveList, currRook, moves, PT_ROOK);
rooks &= rooks - 1;
}

// queens
Bitboard queens = position->pieces[position->usColor * 6 + PT_QUEEN];
while (queens) {
Bitboard currQueen = queens & -queens;
Bitboard moves = (getRookAttacks(std::countr_zero(currQueen), occ) |
getBishopAttacks(std::countr_zero(currQueen), occ)) &
capturableSquares;

// checks & pins
if (isInCheck) {
moves &= checkEvasionMask;
}

if (currQueen & pinMask) {
moves &= LINE_MASK[std::countr_zero(currQueen)][kingSq];
}

addMovesToList(moveList, currQueen, moves, PT_QUEEN);
queens &= queens - 1;
}
}

// king
Bitboard kingMoves = KING_MOVE_MASK[kingSq] & capturableSquares & ~attackMask;
addMovesToList(moveList, position->pieces[position->usColor * 6 + PT_KING], kingMoves, PT_KING);

if (!isInCheck) {
if (position->usColor == WHITE) {
constexpr Bitboard E1 = 1ULL 

Подробнее здесь: [url]https://stackoverflow.com/questions/79760571/how-can-i-further-optimize-move-generation-in-my-c-chess-engine[/url]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»