Chess engine in cpp
A chess engine battle.i won

Chess engine in cpp

Avatar of TheVelvetGambit
| 0

Chess engines are cool

Chess.com even uses them too!

You can make one yourself like I did myself

It's okay if you did it bad,you are just a beginner

Well I'm not

So my chess engine may be good but it's okay if yours is not

I am about to give you a source code of ONE OF MY CHESS ENGINES

It's coded in cpp

Source code is below

typedef uint64_t U64;

const U64 FILE_A = 0x8080808080808080ULL;

const U64 RANK_5 = 0xff00000000ULL;

#define set_bit(b, i) ((b) |= (1ULL << i))

#define get_bit(b, i) ((b) & (1ULL << i))

#define clear_bit(b, i) ((b) &= ~(1ULL << i))

#define get_LSB(b) (__builtin_ctzll(b))

inline int pop_LSB(U64 &b) {

    int i = get_LSB(b);

    b &= b - 1;

    return i;

}

constexpr U64 west(U64 b) { return (b & ~FILE_A) << 1; }

constexpr U64 east(U64 b) { return (b & ~FILE_H) >> 1; }

constexpr U64 north_west(U64 b) { return (b & ~FILE_A) << 9; }

constexpr U64 north_east(U64 b) { return (b & ~FILE_H) << 7; }

// ... etc

U64 attacks, knights = 0ULL;

// place knight on board

set_bit(knights, square);

// add attacks

attacks = (((knights >> 6) | (knights << 10)) & ~FILE_GH) |

          (((knights >> 10) | (knights << 6)) & ~FILE_AB) |

          (((knights >> 15) | (knights << 17)) & ~FILE_H) |

          (((knights >> 17) | (knights << 15)) & ~FILE_A);

U64 attacks = KING_ATTACKS[from] & targets;

// only look at the pawns on the 7th rank

U64 promotions = (bitboards[P] & RANK_7)

// promote north if the square is empty

U64 north_promotions = north(promotions) & empties;

// promote west/east if there is an enemy piece there that we may capture

U64 west_promotions = north_west(promotions) & blacks;

U64 east_promotions = north_east(promotions) & blacks;

U64 ROOK_ATTACKS[64][4096];

U64 Board::getRookAttacks(int square, U64 blockers) const {

  return ROOK_ATTACKS[square][getRookKey(blockers, square)];

}

Board::MoveVec Board::generateMoves<LEGAL>(MoveVec &moves) const {

  // if the king is in check then the legal moves can only be evasions

  isKingInCheck(boardTurn) ? generateMoves<EVASIONS>(moves) : generateMoves<PSEUDO_LEGAL>(moves);

  // extract legal moves from pseudo-legal moves

  std::vector<Move> legal_moves;

  legal_moves.reserve(MOVES_RESERVE_SIZE);

  for (auto &move: moves) {

    if (isMoveLegal(move)) legal_moves.push_back(move);

  }

  return legal_moves;

}

MoveVec &moves;

generateQueenMoves(moves, friendly_queens, ~friendlies);

void Board::generateQueenMoves(MoveVec &moves, U64 queens, U64 targets) const {

  // for each of our queens

  while (queens) {

    // get the position of the queen

    int from = pop_LSB(queens);

    // get the (pre-calculated) attacks of the queen

    // we limit the attacks to contain enemy squares (captures) and

    // empty squares (regular moves), moving to a friendly square is not possible

    U64 attacks = getQueenAttacks(from, all) & targets;

    // add a move for each attack

    while (attacks) addMove(Move(getSquare(from), getSquare(pop_LSB(attacks))), moves);

  }

}

// promotion-eligible pawns are on rank 7

U64 promotions = pawns & RANK_7;

U64 non_promotions = pawns & ~RANK_7;

// pawns can be pushed if there is an empty space

U64 singles = north(non_promotions) & empties;

U64 doubles = north(singles & RANK_3) & empties;

if (promotions) {

  // north promotions are regular pushes and need an empty square

  U64 north_promotions = north(promotions) & empties;

  // west/east promotions can only be captures

  U64 west_promotions = north_west(promotions) & blacks;

  U64 east_promotions = north_east(promotions) & blacks;

}

// captures can happen left/right and need an enemy piece

U64 west_captures = north_west(non_promotions) & blacks;

U64 east_captures = north_east(non_promotions) & blacks;

if (enpassant) {

  U64 enpassants = non_promotions & PAWN_ATTACKS[0][get_LSB(enpassant)];

}

if (turn == WHITE && hasCastlingRights(CastlingRights::WhiteKingside)) {

  if (!get_bit(all, f1) && !get_bit(all, g1) &&

    !isSquareAttackedBy(e1, BLACK) &&

    !isSquareAttackedBy(f1, BLACK))

    addMove(Move(Square::E1, Square::G1), moves);

}

uint64_t perft(Board &board, int depth) {

  std::vector<Move> moves;

  moves.reserve(MOVES_RESERVE_SIZE);

  moves = board.generateMoves<LEGAL>(moves);

  uint64_t nodes = 0;

  if (depth == 1) return moves.size();

  for (const auto &move: moves) {

    Position position = board.copyBoard(board);

    board.makeMove(move);

    nodes += perft(board, depth - 1);

    board.restorePosition(board, position);

  }

  return nodes;

}

const int PIECE_SCORES_MATERIAL[6] = {

    // pawn, knight, bishop, rook, queen, king

    100, 300, 300, 500, 900, 12000

};

const int KNIGHT_SCORES_POSITIONAL[64] = {

  // a score for each square on the board

  -58, -38, -13, -28, -31, -27, -63, -99,

  -25, -8, -25, -2, -9, -25, -24, -52,

  -24, -20, 10, 9, -1, -9, -19, -41,

  -17, 3, 22, 22, 22, 11, 8, -18,

  -18, -6, 16, 25, 16, 17, 4, -18,

  -23, -3, -1, 15, 10, -3, -20, -22,

  -42, -20, -10, -5, -2, -20, -23, -44,

  -29, -51, -23, -15, -22, -18, -50, -64,

};

for (auto &move: moves) {

  int score = 0;

  // capture moves (10010 - 10055)

  if (captured.has_value()) {

    score = 10000 + MVV_LVA[moved.value().toInt() - 6 * (moved.value().toInt() >= 6)][captured.value().toInt()

        - 6 * (captured.value().toInt() >= 6)];

  }

  // promotion moves (9300 - 9900)

  if (promotion.has_value()) {

    score = 9000 + PIECE_SCORES[static_cast<int>(promotion.value())];

  }

  move.setScore(score);

}

Now that is my chess engine source code learn a coding language and code a chess engine (only if you want to).

my first brilliant