aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/board/board.cpp1
-rw-r--r--src/moves.cpp88
-rw-r--r--src/moves.hpp2
3 files changed, 56 insertions, 35 deletions
diff --git a/src/board/board.cpp b/src/board/board.cpp
index e68bf80..16efbd3 100644
--- a/src/board/board.cpp
+++ b/src/board/board.cpp
@@ -10,7 +10,6 @@
int PositionToIndex(Position i) { return i.rank * 8 + i.file; }
Position FindKing(Game *b, bool color) {
-
return IndexToPosition(__builtin_ctzll(b->PieceBitboards[color][KING]));
}
UndoMove MakeMove(Move move, Game *g) {
diff --git a/src/moves.cpp b/src/moves.cpp
index 8f21140..4cd7076 100644
--- a/src/moves.cpp
+++ b/src/moves.cpp
@@ -9,38 +9,63 @@
#include "board/board.hpp"
#include "moves.hpp"
-void GenerateKnightMoves(Game *b, int from, std::vector<Move> &moves,
- bool GenerateQuietMoves) {
- Piece knight = b->pieces[from];
- if (knight.type != KNIGHT) {
- assert(false && "Calling generate knight moves on non knight");
- return;
- }
- // Knight moves: https://www.chessprogramming.org/Knight_Pattern
- constexpr std::array<int, 8> knight_moves{-10, 6, 15, 17, 10, -6, -15, -17};
-
- for (int offset : knight_moves) {
- int next = from + offset;
- if (next >= 64 || next < 0) {
- continue;
- }
- const int fileDelta = std::abs((next % 8) - (from % 8));
- if (fileDelta != 1 && fileDelta != 2) {
- continue;
- };
- bool hasFriendlyPiece = b->turn
- ? (b->WhitePieceBitboard & (1ULL << (next)))
- : (b->BlackPieceBitboard & (1ULL << (next)));
- bool isCaptuare = b->PieceBitboard & (1ULL << next);
- if (hasFriendlyPiece) {
- continue;
- }
- if (!GenerateQuietMoves && isCaptuare) {
- continue;
+constexpr uint64_t KNIGHT_ATTACKS[64] = {
+ 0x0000000000020400ULL, 0x0000000000050800ULL, 0x00000000000A1100ULL,
+ 0x0000000000142200ULL, 0x0000000000284400ULL, 0x0000000000508800ULL,
+ 0x0000000000A01000ULL, 0x0000000000402000ULL, 0x0000000002040004ULL,
+ 0x0000000005080008ULL, 0x000000000A110011ULL, 0x0000000014220022ULL,
+ 0x0000000028440044ULL, 0x0000000050880088ULL, 0x00000000A0100010ULL,
+ 0x0000000040200020ULL, 0x0000000204000402ULL, 0x0000000508000805ULL,
+ 0x0000000A1100110AULL, 0x0000001422002214ULL, 0x0000002844004428ULL,
+ 0x0000005088008850ULL, 0x000000A0100010A0ULL, 0x0000004020002040ULL,
+ 0x0000020400040200ULL, 0x0000050800080500ULL, 0x00000A1100110A00ULL,
+ 0x0000142200221400ULL, 0x0000284400442800ULL, 0x0000508800885000ULL,
+ 0x0000A0100010A000ULL, 0x0000402000204000ULL, 0x0002040004020000ULL,
+ 0x0005080008050000ULL, 0x000A1100110A0000ULL, 0x0014220022140000ULL,
+ 0x0028440044280000ULL, 0x0050880088500000ULL, 0x00A0100010A00000ULL,
+ 0x0040200020400000ULL, 0x0204000402000000ULL, 0x0508000805000000ULL,
+ 0x0A1100110A000000ULL, 0x1422002214000000ULL, 0x2844004428000000ULL,
+ 0x5088008850000000ULL, 0xA0100010A0000000ULL, 0x4020002040000000ULL,
+ 0x0400040200000000ULL, 0x0800080500000000ULL, 0x1100110A00000000ULL,
+ 0x2200221400000000ULL, 0x4400442800000000ULL, 0x8800885000000000ULL,
+ 0x100010A000000000ULL, 0x2000204000000000ULL, 0x0004020000000000ULL,
+ 0x0008050000000000ULL, 0x00110A0000000000ULL, 0x0022140000000000ULL,
+ 0x0044280000000000ULL, 0x0088500000000000ULL, 0x0010A00000000000ULL,
+ 0x0020400000000000ULL};
+
+static void GenerateKnightMoves(Game *b, std::vector<Move> &moves,
+ bool GenerateQuietMoves) {
+ uint64_t knights = b->PieceBitboards[b->turn][KNIGHT];
+ while (knights != 0) {
+ int from = __builtin_ctzll(knights);
+ knights &= knights - 1;
+ uint64_t knight_attacks = KNIGHT_ATTACKS[from];
+ while (knight_attacks != 0) {
+ int next = __builtin_ctzll(knight_attacks);
+ knight_attacks &= knight_attacks - 1;
+
+ if (next >= 64 || next < 0) {
+ continue;
+ }
+ const int fileDelta = std::abs((next % 8) - (from % 8));
+ if (fileDelta != 1 && fileDelta != 2) {
+ continue;
+ };
+ bool hasFriendlyPiece = b->turn
+ ? (b->WhitePieceBitboard & (1ULL << (next)))
+ : (b->BlackPieceBitboard & (1ULL << (next)));
+ bool isCaptuared = b->PieceBitboard & (1ULL << next);
+ if (hasFriendlyPiece) {
+ continue;
+ }
+ if (!GenerateQuietMoves && !isCaptuared) {
+ continue;
+ }
+ moves.push_back({IndexToPosition(from), IndexToPosition(next)});
}
- moves.push_back({IndexToPosition(from), IndexToPosition(next)});
}
};
+
void GeneratePawnMoves(Game *b, int from, std::vector<Move> &moves,
bool quietMoves) {
Piece pawn = b->pieces[from];
@@ -146,6 +171,8 @@ std::vector<Move> GetPseudoLegalMoves(Game *b, bool GenerateQuietMoves) {
std::vector<Move> moves;
moves.reserve(40);
+ GenerateKnightMoves(b, moves, GenerateQuietMoves);
+
constexpr std::array<int, 4> rook_Moves{-1, 1, 8, -8};
constexpr std::array<int, 4> bishop_Moves{-9, 9, -7, 7};
@@ -164,9 +191,6 @@ std::vector<Move> GetPseudoLegalMoves(Game *b, bool GenerateQuietMoves) {
if (piece.type == PAWN) {
GeneratePawnMoves(b, i, moves, GenerateQuietMoves);
}
- if (piece.type == KNIGHT) {
- GenerateKnightMoves(b, i, moves, GenerateQuietMoves);
- };
if (piece.type == BISHOP) {
GenerateSlidingMoves(b, i, bishop_Moves, moves, GenerateQuietMoves);
}
diff --git a/src/moves.hpp b/src/moves.hpp
index e48d7f8..3764be4 100644
--- a/src/moves.hpp
+++ b/src/moves.hpp
@@ -12,8 +12,6 @@ void GenerateSlidingMoves(Game *g, int from,
std::vector<Move> &moves, bool GenerateQuietMoves);
void GenerateKingMoves(Game *g, int from, std::vector<Move> &moves,
bool GenerateQuietMoves);
-void GenerateKnightMoves(Game *b, int from, std::vector<Move> &moves,
- bool GenerateQuietMoves);
void GeneratePawnMoves(Game *b, int from, std::vector<Move> &moves,
bool GenerateQuietMoves);
void GenerateCastlingMoves(int from, Game *g, std::vector<Move> &moves);