working move gen

This commit is contained in:
2024-03-19 22:21:18 +01:00
parent f0fe9454f8
commit 3b9fc1f872
11 changed files with 95 additions and 66 deletions

134
src/common/bitboard.c Normal file
View File

@ -0,0 +1,134 @@
#include <ctype.h>
#include <stdbool.h>
#include <stdint.h>
#include <chess/types.h>
#include <stdlib.h>
bool bitsetGet(uint_least64_t bitset, uint_least8_t i) {
return (bitset >> i) & 1u;
}
uint_least64_t bitsetClear(uint_least64_t bitset, uint_least8_t i) {
return bitset & ~((uint_least64_t)1 << i);
}
uint_least64_t bitsetSet(uint_least64_t bitset, uint_least8_t i) {
return bitset | ((uint_least64_t)1 << i);
}
uint_least64_t bitboardGetMask(const uint_least64_t *board, struct piece_t piece) {
return board[piece.color * PIECES_LENGTH + piece.type];
}
void bitboardSetMask(uint_least64_t *board, struct piece_t piece, uint_least64_t value) {
board[piece.color * PIECES_LENGTH + piece.type] = value;
}
uint_least64_t bitboardMaskAllPieces(const uint_least64_t *board) {
const struct piece_t blackPiece = {ALL_PIECES, BLACK};
const struct piece_t whitePiece = {ALL_PIECES, WHITE};
return bitboardGetMask(board, blackPiece) | bitboardGetMask(board, whitePiece);
}
bool bitboardGetAllPieces(const uint_least64_t *board, uint_least8_t i) {
return bitsetGet(bitboardMaskAllPieces(board), i);
}
bool bitboardGet(const uint_least64_t *board, struct piece_t piece, uint_least8_t i) {
return bitsetGet(bitboardGetMask(board, piece), i);
}
static void bitboardClearHelper(uint_least64_t *board, struct piece_t piece, uint_least8_t i) {
const uint_least64_t newMask = bitsetClear(bitboardGetMask(board, piece), i);
bitboardSetMask(board, piece, newMask);
}
void bitboardClear(uint_least64_t *board, struct piece_t piece, uint_least8_t i) {
const struct piece_t allPiece = {ALL_PIECES, piece.color};
bitboardClearHelper(board, allPiece, i);
bitboardClearHelper(board, piece, i);
}
static void bitboardSetHelper(uint_least64_t *board, struct piece_t piece, uint_least8_t i) {
const uint_least64_t newMask = bitsetSet(bitboardGetMask(board, piece), i);
bitboardSetMask(board, piece, newMask);
}
void bitboardSet(uint_least64_t *board, struct piece_t piece, uint_least8_t i) {
const struct piece_t allPiece = {ALL_PIECES, piece.color};
bitboardSetHelper(board, allPiece, i);
bitboardSetHelper(board, piece, i);
}
struct piece_t pieceAtField(const uint_least64_t *board, uint_least8_t i) {
for(uint_least8_t color = BLACK; color <= WHITE; ++color) {
for(uint_least8_t pieceType = KING; pieceType < PIECES_LENGTH; ++pieceType) {
const struct piece_t piece = {pieceType, color};
if(bitboardGet(board, piece, i)) {
return piece;
}
}
}
{
const struct piece_t pieceError = {NOT_SELECTED, BLACK};
return pieceError;
}
}
struct gameState_t newGameState(uint_least64_t *board, char *FEN) {
const char startFEN[] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
struct gameState_t gameState = {board};
for(uint_least8_t i = 0; i < BITBOARD_LENGTH; ++i) {
board[i] = 0;
}
for(uint_least8_t field = 0; *FEN != ' '; ++FEN, ++field) {
struct piece_t piece;
switch(tolower(*FEN)) {
case 'k':
piece.type = KING;
break;
case 'q':
piece.type = QUEEN;
break;
case 'r':
piece.type = ROOK;
break;
case 'n':
piece.type = KNIGHT;
break;
case 'b':
piece.type = BISHOP;
break;
case 'p':
piece.type = PAWN;
break;
case '/':
continue;
default:
if(isdigit(*FEN)) {
field += *FEN - '0';
}
continue;
}
if(isalpha(*FEN)) piece.color = isupper(*FEN);
bitboardSet(board, piece, field);
}
gameState.color = *++FEN == 'w' ? WHITE : BLACK;
struct castle_t canCastle[2] = {};
FEN += 2;
if(*FEN == '-') ++FEN;
else {
for(; *FEN != ' '; ++FEN) {
struct castle_t *playerCastle = canCastle + (isupper(*FEN) ? WHITE : BLACK);
if(tolower(*FEN) == 'k') playerCastle->shortCastle = true;
else playerCastle->longCastle = true;
}
}
if(*++FEN == '-') ++FEN;
else {
gameState.enPassantTo = *FEN++ - 'a';
gameState.enPassantTo += (BOARD_SIZE - *FEN++) * BOARD_SIZE;
}
gameState.halfMoveCounter = atoi(++FEN);
return gameState;
}

24
src/common/magic.c Normal file
View File

@ -0,0 +1,24 @@
#include <stdint.h>
#include <chess/types.h>
#include <chess/generated/moveConsts.h>
#include <chess/bitboard.h>
uint_least64_t slidingMovementMask(const uint_least8_t *direction, uint_least8_t directionLength,
uint_least8_t field, uint_least64_t blockMask) {
defineDirectionOffset;
const uint_least8_t *localDirectionOffset = DIRECTION_OFFSET + field * DIRECTION_LENGTH;
uint_least64_t movementMask = 0;
for(uint_least8_t j = 0; j < directionLength; ++j) {
const int_least8_t modifier = DIRECTION_MODIFIER[direction[j]];
for(uint_least8_t currentField = field + modifier, i = 0;
i < localDirectionOffset[direction[j]]; ++i, currentField += modifier) {
movementMask = bitsetSet(movementMask, currentField);
if(bitsetGet(blockMask, currentField)) break;
}
}
return movementMask;
}
uint_least64_t* getMagicAttackPtr(const uint_least64_t mask, const struct magic_t magic) {
return magic.attackTable + ((mask * magic.magicNumber) >> magic.shift);
}

22
src/common/print.c Normal file
View File

@ -0,0 +1,22 @@
#include "chess/types.h"
#include <stdio.h>
#include <stdint.h>
#include <chess/bitboard.h>
void printerll(FILE *file, long long num) {
fprintf(file, "%lld", num);
}
void printerull(FILE *file, unsigned long long num) {
fprintf(file, "%lluu", num);
}
// for debugging
void printPieceMask(uint_least64_t mask) {
for(uint_least8_t i = 0; i < BOARD_SIZE; ++i, mask >>= BOARD_SIZE) {
for(uint_least8_t j = 0; j < BOARD_SIZE; ++j) {
printf("%d ", bitsetGet(mask, j));
}
printf("\n");
}
}