#include "moves.h" #include "help.h" #include "types.h" #include #include int rookScan(game *g, move *moves, long long w, long long b); int bishopScan(game *g, move *moves, long long w, long long b); int kingScan(game *g, move *moves, long long w, long long b); int pawnMove(game *g, move *moves) { long long pawns = g->whiteToMove ? g->white.pawns : g->black.pawns; long long enemy = g->whiteToMove ? fullSet(&g->black) : fullSet(&g->white); long long occupied = fullSetBoth(g); long long promo = (0xFFULL) << (g->whiteToMove ? 56 : 0); int movdir = g->whiteToMove ? 8 : -8; int capLeft = g->whiteToMove ? 7 : -9; int capRight = g->whiteToMove ? 9 : -7; size_t index = 0; for (int i = 0; i < 64; ++i) { long long bit = 1ULL << i; char p = 0; if (!(pawns & bit)) continue; // forword int to = i + movdir; p = (promo & (1ULL << to)) ? 'q' : 0; if (to >= 0 && to < 64 && !(occupied & (1ULL << to))) { moves[index++] = (move){.From = i, .To = to, .Promo = p}; } // left to = i + capLeft; p = (promo & (1ULL << to)) ? 'q' : 0; if (i % 8 > 0 && (to >= 0 && to < 64) && (enemy & (1ULL << to))) { moves[index++] = (move){.From = i, .To = to, .Promo = p}; } // right to = i + capRight; p = (promo & (1ULL << to)) ? 'q' : 0; if (i % 8 < 7 && (to >= 0 && to < 64) && (enemy & (1ULL << to))) { moves[index++] = (move){.From = i, .To = to, .Promo = p}; } } return index; } int knightMove(game *g, move *moves) { long long knights = g->whiteToMove ? g->white.knights : g->black.knights; long long occupied = g->whiteToMove ? fullSet(&g->white) : fullSet(&g->black); int kMoves[] = {-17, -15, -10, -6, 6, 10, 15, 17}; int index = 0; for (int i = 0; i < 64; i++) { long long bit = 1ULL << i; if (!(knights & bit)) continue; for (int j = 0; j < 8; ++j) { int to = i + kMoves[j]; if (to < 0 || to > 64) continue; int fromFile = i % 8; int toFile = to % 8; int fromRank = i / 8; int toRank = to / 8; int fileDiff = abs(fromFile - toFile); int rankDiff = abs(fromRank - toRank); if (!((fileDiff == 1 && rankDiff == 2) || (fileDiff == 2 && rankDiff == 1))) continue; long long destBit = 1ULL << to; if (occupied & destBit) continue; moves[index++] = (move){.From = i, .To = to, .Promo=0}; } } return index; } int rookMove(game *g, move *moves) { return rookScan(g, moves, g->white.rooks, g->black.rooks); } int rookScan(game *g, move *moves, long long w, long long b) { long long rooks = g->whiteToMove ? w : b; long long occupied = g->whiteToMove ? fullSet(&g->white) : fullSet(&g->black); long long occupiedE = !g->whiteToMove ? fullSet(&g->white) : fullSet(&g->black); int index = 0; for (int i = 0; i < 64; i++) { long long bit = 1ULL << i; int x = i % 8; int y = i / 8; if (!(rooks & bit)) continue; // fwd for (int j = y + 1; j < 8; j++) { int to = (j * 8) + x; long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } // bck for (int j = y - 1; j >= 0; j--) { int to = (j * 8) + x; long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } // rht for (int j = x + 1; j < 8; j++) { int to = (y * 8) + j; long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } // lft for (int j = x - 1; j >= 0; j--) { int to = (y * 8) + j; long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } } return index; } int bishopMove(game *g, move *moves) { return bishopScan(g, moves, g->white.bishops, g->black.bishops); } int bishopScan(game *g, move *moves, long long w, long long b) { unsigned long long bishops = g->whiteToMove ? w : b; unsigned long long occupied = g->whiteToMove ? fullSet(&g->white) : fullSet(&g->black); unsigned long long occupiedE = !g->whiteToMove ? fullSet(&g->white) : fullSet(&g->black); int index = 0; for (int i = 0; i < 64; i++) { unsigned long long bit = 1ULL << i; int x = i % 8; int y = i / 8; if (!(bishops & bit)) continue; // ur for (int j = 1;; j++) { int xTo = x + j; int yTo = y + j; if (xTo >= 8 || yTo >= 8) break; int to = (yTo * 8) + xTo; unsigned long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } // ul for (int j = 1;; j++) { int xTo = x - j; int yTo = y + j; if (xTo < 0 || yTo >= 8) break; int to = (yTo * 8) + xTo; unsigned long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } // dr for (int j = 1;; j++) { int xTo = x + j; int yTo = y - j; if (xTo >= 8 || yTo < 0) break; int to = (yTo * 8) + xTo; unsigned long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } // dl for (int j = 1;; j++) { int xTo = x - j; int yTo = y - j; if (xTo < 0 || yTo < 0) break; int to = (yTo * 8) + xTo; unsigned long long lbit = 1ULL << to; if (occupied & lbit) break; moves[index++] = (move){.From = i, .To = to, .Promo=0}; if (occupiedE & lbit) break; } } return index; } int queenMove(game *g, move *moves){ int size = 0; unsigned long long w,b; w = g->white.queen; b = g->black.queen; size += rookScan(g,moves,w,b); size += bishopScan(g,(moves+size),w,b); return size; } int kingMove(game *g, move *moves){ unsigned long long king = g->whiteToMove ? g->white.king : g->black.king; unsigned long long occupied = g->whiteToMove ? fullSet(&g->white) : fullSet(&g->black); int index = 0; for (int i = 0; i < 64; i++){ unsigned long long bit = 1ULL << i; int x = i % 8; int y = i / 8; int movesX[] = {-1, 0, 1, -1, 1, -1, 0, 1}; int movesY[] = {-1, -1, -1, 0, 0, 1, 1, 1}; if(!(king & bit)) continue; for (int j = 0; j < 8; ++j) { int toX = x + movesX[j]; int toY = y + movesY[j]; int to = (toY * 8) + toX; if(to > 63 || to < 1) continue; unsigned long long destBit = 1ULL << to; if (toX >= 0 && toX < 8 && toY >= 0 && toY < 8) { if (!(occupied & destBit)) { moves[index++] = (move){.From = i, .To = to, .Promo=0}; } } } } return index; }