make main
make runThis header file is the fundation for “boardmap.c ”, where the chess board is represented by bitboards. In more detail in this file we set up bitboard operations , declare global variables and essential functions.
First we decare the bitboards for white pieces (U64 whitePieces;) , for black pieces (U64 blackPieces;) , and for every piece in the board (U64 pieces;). ( Here “U64” is defined in boardmap.h ). Then we initialize them in the function initialize_board
void initialize_board() {
whitePieces = 0x000000000000FFFFULL;
blackPieces = 0xFFFF000000000000ULL;
pieces = whitePieces | blackPieces;
}Then , depending on whose turn it is (black or white) we return the appropreate in the function getGlobalVar:
U64 getGlobalVar(char color) {
if (color == 'w'){
return whitePieces;
}else if (color == 'b'){
return blackPieces;
}else{
return pieces;
}
}This header file is about chess positions using FEN. It contains the definition of the FEN structure, function declarations (parse_fen,new_fen,coord_to_square)(that will be used in fen.c)
In this function we first have to initialize the board with spaces. First we have to tokenize the FEN string by spaces. The first token represents the board layout, using digits to indicate consecutive empty squares and slashes / to separate rows. The FEN also tells us the turn, castling rights, en passant targets, half-move clock and total moves.
This function constructs a FEN string from a given FEN structure . it iterates over each row and counts empty spaces, adds the piece symbols or the number of empty squares and adds information about whose turn it is , castling rights, en passant target, half-move clock and full move number.
This function converts board array coords into standard algebraic notation.
This function takes the coordinate conversion to check if a given space matches the en passant target stored in the FEN structure.
Checks single and double forward moves, diagonal captures and en passant captures (for pawns)
Checks for L-shaped based moves (for knights)
Checks diagonal moves, ensuring no other pieces block the path (for bishops)
Checks horizontal or vertical moves ,and that that the path is clear (for rooks)
Combines the logic of both bishop and rook moves (for queen)
Checks that the king moves only one square in any direction (for king)
In addition to all the piece specified rules , this function verifies that the destination square is not occupied by a friendly piece
Takes the move expressed in algebraic notation and updates the board accordingly. In more detail, for castling it moves both king and rook to their new positions, and also removes the rightd for the moving side. The function finds what to move from the notation (it identifies the destination square and piece). For pawns it identifies special cases such as double moves, diagonal captures, en passant and promotions. (it promotes to a queen by default if no promotion piece is specified) . if no piece can legally move to the destination square it prints an error and exits. Then the bitboard is updated using SET_BIT , CLEAR_BIT previously declared in boardmap.h. the half-move clock resets if a pawn is moves otherwise it increments, if a king or a rook are moved then it updates the castling rights. At the end of the move, the turn is switched to the opposite color
This function takes the initial FEN structure and a move string , applies the move using apply_move function and returns the updated board position as a new FEN structure
This header file is for move generation (legal chess moves according to chess rules) using bitboards. This declares the functions find_moves , which will be used to find all legal moves, initNonSlidingMoves which are precomputed moves for knights, kings, and pawns , and printBitboard (debugging)
This function is used to display the 64 bit integer bb as an 8x8 grid (each bit represents a square on the chess board)
In this function we calculate all possible knight move from a given square (it returns the computed bitboard that represents all legal moves for the knight from that square)
In this we calculate all possible moves for a king from a given square (it returns the bitboard of all squares that the king can move to from a given square)
This function initializes a global array by computing and storing all possible moves for a knight and king for every square on the board
This function generates all legal moves for the player whose turn it is using bitboards to be more efficient .
This header declares the move function wich is responsible for updating the game state based on a given move
This function counts the number of moves that are represented in a string (where each move is separated by a space).
This function counts the moves provides in the moves string
This header declares the function find_best_move
First thig we do is define the value of each piece. This will be used later when evaluating the board. Then we create the structure “Move” , which holds the information of a move. Meaning from what square the piece started , where the destination square is , the type of piece that moves, if the move is a capture, and if it is a promotion (for pawns ).
typedef struct {
int fromX, fromY, toX, toY;
char piece;
bool isCapture;
char promotion;
} Move;Then we create the structure of the tree nodes “Node” . this Node holds the current state of the game (the current board ) , the move that lead to this node, the evaluation of the move (moveScore), an array of pointers to child nodes (children), and the amount of children the tree has (childcount)
typedef struct node {
char board[8][8];
Move move;
long long int moveScore;
struct node **children;
int childcount;
} Node;Then we create the structure of the transposition table entry (TTEntry).This structure is used to cache previously computed board evaluations to speed up search (basically avoid re-exloration).
typedef struct {
unsigned long long key;
long long evaluation;
int depth;
} TTEntry;This function takes the move in short algebraic notation and “decodes it”. What I mean by this is it takes the string and extractes all the information inorder to use it later.it checks for castling also, and primotions.it extracts the destination square from the last 2 characters . if the first character is one of "K Q R B N" then it means it is not a pawn and we need to save what piece it is. For pawns it distinguishesbetween simple forward moves and captures.
This function builds an algebraic string representation from a Move structure
(it takes all the information (if it is a castle , capture , promotion , destination square)).
This function iterates over every square of the board, summing up the values of white pieces and subtracting the values of black pieces.
This function creates new board states by copying the source board, moving the piece from its starting square to the destination (playing the move ), and then emptying the original square.
This function creates a new node to the game tree (allocates and initializes a new node).
It dynamically resizes the parents children array (using realloc) and adds a new child to the tree (basically adds a new possible state of the game )
This function frees all the allocated memomy used by the tree.
This algorithm helps quickly compare board states, making the program more efficient
This function scans the board for moves that capture enemy pieces
This function first computes an evaluation of the current board, then generates all capture moves and recursively evaluates these moves while applying alpha–beta cutoffs.
This is the core recursive search algorithm. It choses the bmove with the highest board evaluation
This function instead of searching to fixed depth starts with a shallow depth and incrementally increases it. This method allows the engine to return the best move found within the allotted time
Here all the other filles work together to create the chess engine.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/Headers/fen.h"
#include "include/Headers/find_moves.h"
#include "include/Headers/boardmap.h"
#include "include/Headers/find_best_move.h"Here we include all the necessary libraries, as well as all the headers we created.
This function takes a pointer to a FEN structure and prints the current board state
This function allocates a new string (512 characters) and copies the input string into it while omitting any double-quote characters. It ensures the returned string is null-terminated
This function takes a string of moves and an index and extracts the move at that index
This function searches for a specific move within the moves string and returns its index
This is a helper function that prints the board as an 8×8 grid, displaying each square’s content with tabs for readability
Prints a bitboard representation (using a 64-bit unsigned integer). It checks each bit (using a macro GET_BIT) and prints a "1" if the bit is set or a dot otherwise