Skip to content

Commit

Permalink
Adaptable TT Size + V1.0.0!
Browse files Browse the repository at this point in the history
  • Loading branch information
Vast342 committed Oct 16, 2023
1 parent 8eeb96b commit fa21e1e
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 20 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The C++ rewrite is complete! Clarity is now faster and better, using new techniq

For those who didn't see the engine in its depressing, confusing, error-filled C# state, this engine was originally written in C# before I decided to switch to C++. That decision was one of the greatest I think I've ever had, as the engine is now faster, easier to read, less error-filled(hopefully), and better overall.

My current Estimate of elo (calculated by playing large sums of games against engines with known CCRL ratings) is 2050.
My current Estimate of elo (calculated by playing large sums of games against engines with known CCRL ratings) is 2200.

#### Warning: Clarity currently uses pext for move generation, which means that CPUs without BMI2 or CPUs with a slow implementation (Zen 2 or earlier) will not be able to use it, A replacement (magic bitboards) is underway.

Expand Down Expand Up @@ -44,6 +44,17 @@ Evaluation:

## Feature List:

CLI:
1. UCI Implementation
2. printstate: shows the state of the board.
3. perftsuite <suite>: performs a suite of perft tests, currently only supports the suite ethereal.
4. perft <depth>: performs a perft test from the current position and outputs the result.
5. splitperft <depth>: performs a perft test from the current position and outputs the result seperated by which move is the first one done.
6: getfen: outputs a string of Forsyth-Edwards Notation (FEN) that encodes the current position.
7: incheck: outputs if the current position is in check or not.
8: evaluate: outputs the evaluation of the current position.
9: bench <depth>: performs the bench test, a fixed depth search on a series of 50 positions.

Board Representation:
1. Copymake moves
2. Board represented using 8 bitboards
Expand Down
37 changes: 36 additions & 1 deletion src/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ void Board::undoChangeColor() {
}

int Board::getEvaluation() {
// currently disabled passed pawn bonuses, as it wasn't gaining any elo
// currently disabled passed pawn bonuses, as it wasn't gaining any elo, even after my goofy and probablly messed up tuning
int egPhase = 24 - phase;
return ((mgEval * phase + egEval * egPhase) / 24) * ((2 * colorToMove) - 1);
//return (((mgEval * phase + egEval * egPhase) / 24) + getPassedPawnBonuses()) * ((2 * colorToMove) - 1);
Expand Down Expand Up @@ -875,4 +875,39 @@ bool Board::isRepeatedPosition() {
}
}
return false;
}

bool Board::isLegalMove(const Move& move) {
if(move.getValue() != 0) {
int startSquare = move.getStartSquare();
uint64_t occupiedBitboard = getOccupiedBitboard();
int movePiece = getType(pieceAtIndex(startSquare));
if(movePiece != None) {
uint64_t total = 0;
if(movePiece == Pawn) {
total = getPawnAttacks(startSquare, colorToMove);
uint64_t capturable = coloredBitboards[1 - colorToMove];
if(enPassantIndex != 64) {
capturable |= (1ULL << enPassantIndex);
}
total &= capturable;
total |= (1ULL << (startSquare + directionalOffsets[colorToMove])) & ~occupiedBitboard;
} else {
if(movePiece == Knight) {
total = getKnightAttacks(startSquare);
} else if(movePiece == Bishop) {
total = getBishopAttacks(startSquare, occupiedBitboard);
} else if(movePiece == Rook) {
total = getRookAttacks(startSquare, occupiedBitboard);
} else if(movePiece == Queen) {
total = getRookAttacks(startSquare, occupiedBitboard) | getBishopAttacks(startSquare, occupiedBitboard);
} else if(movePiece == King) {
total = getKingAttacks(startSquare);
}
total ^= (total & coloredBitboards[colorToMove]);
}
if((total & (1ULL << move.getEndSquare())) != 0) return true;
}
}
return false;
}
9 changes: 5 additions & 4 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ struct BoardState {

struct Move {
public:
int getStartSquare();
int getEndSquare();
int getFlag();
int getValue();
int getStartSquare() const;
int getEndSquare() const;
int getFlag() const;
int getValue() const;
Move(int startSquare, int endSquare, int flag);
Move();
Move(std::string longAlgebraic, const Board& board);
Expand Down Expand Up @@ -100,6 +100,7 @@ struct Board {
uint64_t fullZobristRegen();
bool isRepeatedPosition();
int detectPassedPawns();
bool isLegalMove(const Move& move);
private:
std::array<uint64_t, 2> coloredBitboards;
std::array<uint64_t, 6> pieceBitboards;
Expand Down
8 changes: 4 additions & 4 deletions src/move.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
#include "globals.h"

int Move::getValue() {
int Move::getValue() const {
return value;
}

int Move::getStartSquare() {
int Move::getStartSquare() const {
return value & 0b111111;
}

int Move::getEndSquare() {
int Move::getEndSquare() const {
return (value >> 6) & 0b111111;
}

int Move::getFlag() {
int Move::getFlag() const {
return value >> 12;
}

Expand Down
5 changes: 3 additions & 2 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ std::string getPV(Board board) {
std::string pv = "";
if(TT.matchZobrist(board.zobristHash)) {
Move bestMove = TT.getBestMove(board.zobristHash);
if(bestMove.getValue() != 0 && board.makeMove(bestMove)) {
// need a move.isLegal() to make sure that the move is legal in the position, not just that it doesn't put you in check
if(board.isLegalMove(bestMove) && board.makeMove(bestMove)) {
std::string restOfPV = getPV(board);
pv = toLongAlgebraic(bestMove) + " " + restOfPV;
}
Expand Down Expand Up @@ -328,7 +329,7 @@ Move think(Board board, int timeLeft) {
}
//std::string pv = getPV(board);
//std::cout << "info depth " << std::to_string(depth) << " nodes " << std::to_string(nodes) << " time " << std::to_string(elapsedTime) << " score cp " << std::to_string(score) << " pv " << pv << std::endl;
std::cout << "info depth " << std::to_string(depth) << " nodes " << std::to_string(nodes) << " time " << std::to_string(elapsedTime) << " score cp " << std::to_string(score) << std::endl;
std::cout << "info depth " << std::to_string(depth) << " nodes " << std::to_string(nodes) << " time " << std::to_string(elapsedTime) << " score cp " << std::to_string(score) << " pv " << toLongAlgebraic(rootBestMove) << std::endl;
}

return rootBestMove;
Expand Down
9 changes: 1 addition & 8 deletions src/uci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void sigmoidTest() {
}*/

void identify() {
std::cout << "id name Clarity V0.1.2\n";
std::cout << "id name Clarity V1.0.0\n";
std::cout << "id author Vast\n";
std::cout << "option name Hash type spin default 256 min 1 max 2048\n";
}
Expand Down Expand Up @@ -119,13 +119,6 @@ void interpretCommand(std::string command) {
splitPerft(board, std::stoi(bits[1]));
} else if(bits[0] == "evaluate") {
std::cout << "evaluation " << board.getEvaluation() << '\n';
} else if(bits[0] == "showstate") {
board.toString();
} else if(bits[0] == "detectpassers") {
const int passed = board.detectPassedPawns();
std::cout << "passed pawns: " << passed << '\n';
} else if(bits[0] == "masktest") {
std::cout << "mask: " << getPassedPawnMask(43, 1) << '\n';
} else if(bits[0] == "setoption") {
setOption(bits);
} else if(bits[0] == "bench") {
Expand Down

0 comments on commit fa21e1e

Please sign in to comment.