diff --git a/headers/moves.h b/headers/moves.h index 298db2b..35f4730 100644 --- a/headers/moves.h +++ b/headers/moves.h @@ -3,4 +3,8 @@ #include "types.h" int pawnMove(game *g, move *moves); int knightMove(game *g, move* moves); +int rookMove(game *g, move *moves); +int bishopMove(game *g, move *moves); +int kingMove(game *g, move *moves); +int queenMove(game *g, move *moves); #endif diff --git a/src/main.c b/src/main.c index 094594a..49783ae 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "moves.h" #include "types.h" #include "help.h" @@ -50,12 +51,18 @@ int main() { playMoves(g, lineRest); } else if (!strcmp("ucinewgame", token)) { } else if (!strcmp("isready", token)) { + srand(time(NULL)); printf("readyok\n"); } else if (!strcmp("go", token)) { - - move mov[200]; - int cnt = knightMove(g, mov); - move *m = &mov[0]; + static move mov[1500];//big dumb buffer + int cnt = 0; + cnt += pawnMove(g,mov); + cnt += knightMove(g,(mov+cnt)); + cnt += rookMove(g,(mov+cnt)); + cnt += bishopMove(g,(mov+cnt)); + cnt += kingMove(g,(mov+cnt)); + cnt += queenMove(g,(mov+cnt)); + move *m = &mov[rand() % cnt]; char *end = ""; int yTo, xTo, yFrom, xFrom; @@ -64,9 +71,9 @@ int main() { xFrom = m->From % 8; yFrom = m->From / 8 + 1; - if ((g->whiteToMove && yTo == 8) || (!g->whiteToMove && yTo == 1)) { - // end = "q\n"; - end = "\n"; + long long bit = 1LL << m->From; + if (((g->whiteToMove && yTo == 8) || (!g->whiteToMove && yTo == 1)) && ((findSet(g,bit) == &g->white.pawns) || (findSet(g,bit) == &g->black.pawns))) { + end = "q\n"; } else { end = "\n"; } diff --git a/src/moves.c b/src/moves.c index 2284924..0ae4f2e 100644 --- a/src/moves.c +++ b/src/moves.c @@ -1,9 +1,13 @@ -#include "types.h" #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); @@ -41,17 +45,11 @@ int pawnMove(game *g, move *moves) { 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 kMoves[] = {-17, -15, -10, -6, 6, 10, 15, 17}; int index = 0; for (int i = 0; i < 64; i++) { @@ -71,11 +69,12 @@ int knightMove(game *g, move *moves) { int fileDiff = abs(fromFile - toFile); int rankDiff = abs(fromRank - toRank); - if (!((fileDiff == 1 && rankDiff == 2) || (fileDiff == 2 && rankDiff == 1))) + if (!((fileDiff == 1 && rankDiff == 2) || + (fileDiff == 2 && rankDiff == 1))) continue; long long destBit = 1LL << to; - if (occupied & destBit) // Skip if destination has friendly piece + if (occupied & destBit) continue; moves[index++] = (move){.From = i, .To = to}; @@ -83,3 +82,200 @@ int knightMove(game *g, move *moves) { } 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 = 1LL << 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 = 1LL << to; + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + if (occupiedE & lbit) + break; + } + + // bck + for (int j = y - 1; j >= 0; j--) { + int to = (j * 8) + x; + long long lbit = 1LL << to; + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + if (occupiedE & lbit) + break; + } + + // rht + for (int j = x + 1; j < 8; j++) { + int to = (y * 8) + j; + long long lbit = 1LL << to; + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + if (occupiedE & lbit) + break; + } + + // lft + for (int j = x - 1; j >= 0; j--) { + int to = (y * 8) + j; + long long lbit = 1LL << to; + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + 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) { + long long bishops = 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 = 1LL << 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; + long long lbit = 1LL << to; + + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + 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; + long long lbit = 1LL << to; + + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + 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; + long long lbit = 1LL << to; + + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + 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; + long long lbit = 1LL << to; + + if (occupied & lbit) + break; + moves[index++] = (move){.From = i, .To = to}; + if (occupiedE & lbit) + break; + } + } + return index; +} + +int queenMove(game *g, move *moves){ + int size = 0; + long long w,b; + w = g->white.queen; + b = g->black.queen; + size += rookScan(g,moves,w,b); + size += bishopScan(g,moves,w,b); + return size; +} + + +int kingMove(game *g, move *moves){ + long long king = g->whiteToMove ? g->white.king : g->black.king; + long long occupied = g->whiteToMove ? fullSet(&g->white) : fullSet(&g->black); + int index = 0; + + for (int i = 0; i < 64; i++){ + long long bit = 1LL << 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; + long long destBit = 1LL << to; + + if (toX >= 0 && toX < 8 && toY >= 0 && toY < 8) { + if (!(occupied & destBit)) { + moves[index++] = (move){.From = i, .To = to}; + } + } + } + } + return index; +}