Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
jhonnold committed Mar 27, 2024
2 parents e47f0ed + 206d192 commit 0e20828
Show file tree
Hide file tree
Showing 48 changed files with 545 additions and 337 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ dkms.conf
berserk
berserk-popcnt
.vscode
.idea
dist

*.log
Expand Down
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

Berserk is a UCI compliant chess engine written in C
Copyright (C) 2023 Jay Honnold
Copyright (C) 2024 Jay Honnold

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

Berserk Copyright (C) 2023 Jay Honnold
Berserk Copyright (C) 2024 Jay Honnold
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
Expand Down
7 changes: 3 additions & 4 deletions resources/update.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

set -uex

# Select a compiler, prioritize Clang
if hash clang 2>/dev/null; then
cc=clang
Expand All @@ -11,7 +13,6 @@ else
fi

# Clone Berserk
echo "Cloning Berserk"
git clone --depth 1 --branch main https://github.com/jhonnold/berserk.git
success=$?

Expand All @@ -23,8 +24,7 @@ else
fi;

cd berserk/src
echo "Compiling Berserk with make pgo CC=$cc"
make pgo CC=$cc
make build CC=$cc ARCH=native

if test -f berserk; then
echo "Compilation complete..."
Expand All @@ -34,7 +34,6 @@ else
fi

EXE=$PWD/berserk
echo "Setting EXE to $EXE"

$EXE bench 13 > bench.log 2 >&1
grep Results bench.log
2 changes: 1 addition & 1 deletion src/attacks.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion src/attacks.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion src/bench.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion src/bench.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion src/berserk.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion src/bits.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion src/bits.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
136 changes: 50 additions & 86 deletions src/board.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Berserk is a UCI compliant chess engine written in C
// Copyright (C) 2023 Jay Honnold
// Copyright (C) 2024 Jay Honnold

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand All @@ -17,6 +17,7 @@
#include "board.h"

#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -51,6 +52,7 @@ void ClearBoard(Board* board) {

board->piecesCounts = 0ULL;
board->zobrist = 0ULL;
board->pawnZobrist = 0ULL;

board->stm = WHITE;
board->xstm = BLACK;
Expand Down Expand Up @@ -159,9 +161,10 @@ void ParseFen(char* fen, Board* board) {
OccBB(BOTH) = OccBB(WHITE) | OccBB(BLACK);

SetSpecialPieces(board);
SetThreatsAndEasyCaptures(board);
SetThreats(board);

board->zobrist = Zobrist(board);
board->zobrist = Zobrist(board);
board->pawnZobrist = PawnZobrist(board);
}

void BoardToFen(char* fen, Board* board) {
Expand Down Expand Up @@ -263,58 +266,45 @@ inline void SetSpecialPieces(Board* board) {
}
}

inline void SetThreatsAndEasyCaptures(Board* board) {
inline void SetThreats(Board* board) {
// Invert these to be confusing.
const int stm = board->xstm;
const int xstm = board->stm;

board->threatened = board->easyCapture = 0;

// Take the enemy king off for through threats.
BitBoard occ = OccBB(BOTH) ^ PieceBB(KING, xstm);

BitBoard opponentPieces = OccBB(xstm) ^ PieceBB(PAWN, xstm);

BitBoard pawnAttacks = stm == WHITE ? ShiftNW(PieceBB(PAWN, WHITE)) | ShiftNE(PieceBB(PAWN, WHITE)) :
ShiftSW(PieceBB(PAWN, BLACK)) | ShiftSE(PieceBB(PAWN, BLACK));
board->threatened |= pawnAttacks;
board->easyCapture |= pawnAttacks & opponentPieces;

// remove minors
opponentPieces ^= PieceBB(KNIGHT, xstm) | PieceBB(BISHOP, xstm);

BitBoard knights = PieceBB(KNIGHT, stm);
while (knights) {
BitBoard atx = GetKnightAttacks(PopLSB(&knights));

board->threatened |= atx;
board->easyCapture |= opponentPieces & atx;
}

BitBoard bishops = PieceBB(BISHOP, stm);
while (bishops) {
BitBoard atx = GetBishopAttacks(PopLSB(&bishops), occ);

board->threatened |= atx;
board->easyCapture |= opponentPieces & atx;
}

// remove rooks
opponentPieces ^= PieceBB(ROOK, xstm);

BitBoard rooks = PieceBB(ROOK, stm);
while (rooks) {
BitBoard atx = GetRookAttacks(PopLSB(&rooks), occ);

board->threatened |= atx;
board->easyCapture |= opponentPieces & atx;
}

BitBoard queens = PieceBB(QUEEN, stm);
BitBoard pawnAttacks = stm == WHITE ? ShiftNW(PieceBB(PAWN, WHITE)) | ShiftNE(PieceBB(PAWN, WHITE)) :
ShiftSW(PieceBB(PAWN, BLACK)) | ShiftSE(PieceBB(PAWN, BLACK));
board->threatenedBy[PAWN] = pawnAttacks;
board->threatened = board->threatenedBy[PAWN];

board->threatenedBy[KNIGHT] = 0;
BitBoard knights = PieceBB(KNIGHT, stm);
while (knights)
board->threatenedBy[KNIGHT] |= GetKnightAttacks(PopLSB(&knights));
board->threatened |= board->threatenedBy[KNIGHT];

board->threatenedBy[BISHOP] = 0;
BitBoard bishops = PieceBB(BISHOP, stm);
while (bishops)
board->threatenedBy[BISHOP] |= GetBishopAttacks(PopLSB(&bishops), occ);
board->threatened |= board->threatenedBy[BISHOP];

board->threatenedBy[ROOK] = 0;
BitBoard rooks = PieceBB(ROOK, stm);
while (rooks)
board->threatenedBy[ROOK] |= GetRookAttacks(PopLSB(&rooks), occ);
board->threatened |= board->threatenedBy[ROOK];

board->threatenedBy[QUEEN] = 0;
BitBoard queens = PieceBB(QUEEN, stm);
while (queens)
board->threatened |= GetQueenAttacks(PopLSB(&queens), occ);
board->threatenedBy[QUEEN] |= GetQueenAttacks(PopLSB(&queens), occ);
board->threatened |= board->threatenedBy[QUEEN];

board->threatened |= GetKingAttacks(LSB(PieceBB(KING, stm)));
board->threatenedBy[KING] = GetKingAttacks(LSB(PieceBB(KING, stm)));
board->threatened |= board->threatenedBy[KING];
}

void MakeMove(Move move, Board* board) {
Expand All @@ -328,16 +318,8 @@ void MakeMoveUpdate(Move move, Board* board, int update) {
int captured = IsEP(move) ? Piece(PAWN, board->xstm) : board->squares[to];

// store hard to recalculate values
board->history[board->histPly].capture = captured;
board->history[board->histPly].castling = board->castling;
board->history[board->histPly].ep = board->epSquare;
board->history[board->histPly].fmr = board->fmr;
board->history[board->histPly].nullply = board->nullply;
board->history[board->histPly].zobrist = board->zobrist;
board->history[board->histPly].checkers = board->checkers;
board->history[board->histPly].pinned = board->pinned;
board->history[board->histPly].threatened = board->threatened;
board->history[board->histPly].easyCapture = board->easyCapture;
memcpy(&board->history[board->histPly], board, offsetof(Board, stm));
board->history[board->histPly].capture = captured;

board->fmr++;
board->nullply++;
Expand All @@ -350,6 +332,8 @@ void MakeMoveUpdate(Move move, Board* board, int update) {
board->squares[to] = piece;

board->zobrist ^= ZOBRIST_PIECES[piece][from] ^ ZOBRIST_PIECES[piece][to];
if (PieceType(piece) == PAWN)
board->pawnZobrist ^= ZOBRIST_PIECES[piece][from] ^ ZOBRIST_PIECES[piece][to];

if (IsCas(move)) {
int rookFrom = board->cr[CASTLING_ROOK[to]];
Expand Down Expand Up @@ -377,6 +361,8 @@ void MakeMoveUpdate(Move move, Board* board, int update) {
FlipBit(OccBB(BOTH), capSq);

board->zobrist ^= ZOBRIST_PIECES[captured][capSq];
if (PieceType(captured) == PAWN)
board->pawnZobrist ^= ZOBRIST_PIECES[captured][capSq];

board->piecesCounts -= PieceCount(captured);
board->phase -= PHASE_VALUES[PieceType(captured)];
Expand Down Expand Up @@ -410,6 +396,7 @@ void MakeMoveUpdate(Move move, Board* board, int update) {
board->squares[to] = promoted;

board->zobrist ^= ZOBRIST_PIECES[piece][to] ^ ZOBRIST_PIECES[promoted][to];
board->pawnZobrist ^= ZOBRIST_PIECES[piece][to];
board->piecesCounts += PieceCount(promoted) - PieceCount(piece);
board->phase += PHASE_VALUES[PieceType(promoted)];
}
Expand All @@ -422,11 +409,12 @@ void MakeMoveUpdate(Move move, Board* board, int update) {
board->xstm = board->stm;
board->stm ^= 1;
board->zobrist ^= ZOBRIST_SIDE_KEY;
board->pawnZobrist ^= ZOBRIST_SIDE_KEY;

// special pieces must be loaded after the stm has changed
// this is because the new stm to move will be the one in check
SetSpecialPieces(board);
SetThreatsAndEasyCaptures(board);
SetThreats(board);

if (update) {
board->accumulators->move = move;
Expand All @@ -449,15 +437,7 @@ void UndoMove(Move move, Board* board) {
board->accumulators--;

// reload historical values
board->castling = board->history[board->histPly].castling;
board->epSquare = board->history[board->histPly].ep;
board->fmr = board->history[board->histPly].fmr;
board->nullply = board->history[board->histPly].nullply;
board->zobrist = board->history[board->histPly].zobrist;
board->checkers = board->history[board->histPly].checkers;
board->pinned = board->history[board->histPly].pinned;
board->threatened = board->history[board->histPly].threatened;
board->easyCapture = board->history[board->histPly].easyCapture;
memcpy(board, &board->history[board->histPly], offsetof(Board, stm));

if (IsPromo(move)) {
int promoted = PromoPiece(move, board->stm);
Expand Down Expand Up @@ -503,16 +483,7 @@ void UndoMove(Move move, Board* board) {
}

void MakeNullMove(Board* board) {
board->history[board->histPly].capture = NO_PIECE;
board->history[board->histPly].castling = board->castling;
board->history[board->histPly].ep = board->epSquare;
board->history[board->histPly].fmr = board->fmr;
board->history[board->histPly].nullply = board->nullply;
board->history[board->histPly].zobrist = board->zobrist;
board->history[board->histPly].checkers = board->checkers;
board->history[board->histPly].pinned = board->pinned;
board->history[board->histPly].threatened = board->threatened;
board->history[board->histPly].easyCapture = board->easyCapture;
memcpy(&board->history[board->histPly], board, offsetof(Board, stm));

board->fmr++;
board->nullply = 0;
Expand All @@ -522,13 +493,14 @@ void MakeNullMove(Board* board) {
board->epSquare = 0;

board->zobrist ^= ZOBRIST_SIDE_KEY;
board->pawnZobrist ^= ZOBRIST_SIDE_KEY;

board->histPly++;
board->stm = board->xstm;
board->xstm ^= 1;

SetSpecialPieces(board);
SetThreatsAndEasyCaptures(board);
SetThreats(board);
}

void UndoNullMove(Board* board) {
Expand All @@ -537,15 +509,7 @@ void UndoNullMove(Board* board) {
board->histPly--;

// reload historical values
board->castling = board->history[board->histPly].castling;
board->epSquare = board->history[board->histPly].ep;
board->fmr = board->history[board->histPly].fmr;
board->nullply = board->history[board->histPly].nullply;
board->zobrist = board->history[board->histPly].zobrist;
board->checkers = board->history[board->histPly].checkers;
board->pinned = board->history[board->histPly].pinned;
board->threatened = board->history[board->histPly].threatened;
board->easyCapture = board->history[board->histPly].easyCapture;
memcpy(board, &board->history[board->histPly], offsetof(Board, stm));
}

inline int IsDraw(Board* board, int ply) {
Expand Down
Loading

0 comments on commit 0e20828

Please sign in to comment.