Skip to content

Commit

Permalink
16 bit move (#73)
Browse files Browse the repository at this point in the history
this encodes a move into 16bits, this way each transposition entry is smaller and we can fit in more entries while keeping the hash size the same.

ELO   | 43.94 +- 14.94 (95%)
SPRT  | 8.0+0.08s Threads=1 Hash=8MB
LLR   | 3.03 (-2.94, 2.94) [0.00, 5.00]
GAMES | N: 1232 W: 438 L: 283 D: 511

Bench: 2700249
  • Loading branch information
Disservin authored Jun 16, 2022
1 parent fe537d7 commit ba9e15a
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 48 deletions.
32 changes: 16 additions & 16 deletions src/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,9 @@ PieceType Board::piece_type(Piece piece) {

std::string Board::printMove(Move& move) {
std::string m = "";
m += squareToString[move.from];
m += squareToString[move.to];
if (move.promoted) m += PieceToPromPiece[Piece(move.piece)];
m += squareToString[move.from()];
m += squareToString[move.to()];
if (move.promoted()) m += PieceToPromPiece[Piece(move.piece())];
return m;
}

Expand Down Expand Up @@ -720,9 +720,9 @@ Movelist Board::capturemoves() {


void Board::makeMove(Move& move) {
Piece piece = makePiece(move.piece, sideToMove);
Square from = move.from;
Square to = move.to;
Piece piece = makePiece(move.piece(), sideToMove);
Square from = move.from();
Square to = move.to();
Piece capture = board[to];

hashHistory[fullMoveNumber] = hashKey;
Expand All @@ -737,7 +737,7 @@ void Board::makeMove(Move& move) {
if (enPassantSquare != NO_SQ) hashKey ^= updateKeyEnPassant(enPassantSquare);
enPassantSquare = NO_SQ;

if (move.piece == KING) {
if (move.piece() == KING) {
if (sideToMove == White && from == SQ_E1 && to == SQ_G1 && castlingRights & wk) {
removePiece(WhiteRook, SQ_H1);
placePiece(WhiteRook, SQ_F1);
Expand Down Expand Up @@ -775,7 +775,7 @@ void Board::makeMove(Move& move) {
}
hashKey ^= updateKeyCastling();
}
else if (move.piece == ROOK) {
else if (move.piece() == ROOK) {
hashKey ^= updateKeyCastling();
if (sideToMove == White && from == SQ_A1 ) {
castlingRights &= ~wq;
Expand All @@ -791,7 +791,7 @@ void Board::makeMove(Move& move) {
}
hashKey ^= updateKeyCastling();
}
else if (move.piece == PAWN) {
else if (move.piece() == PAWN) {
halfMoveClock = 0;
if (ep) {
removePiece(makePiece(PAWN, ~sideToMove), Square(to - (sideToMove * -2 + 1) * 8));
Expand Down Expand Up @@ -828,7 +828,7 @@ void Board::makeMove(Move& move) {
}
}

if (move.promoted) {
if (move.promoted()) {
halfMoveClock = 0;
removePiece(makePiece(PAWN, sideToMove), from);
placePiece(piece, to);
Expand Down Expand Up @@ -857,11 +857,11 @@ void Board::unmakeMove(Move& move) {
hashKey = restore.h;
fullMoveNumber--;

Square from = move.from;
Square to = move.to;
bool promotion = move.promoted;
Square from = move.from();
Square to = move.to();
bool promotion = move.promoted();
sideToMove = ~sideToMove;
Piece piece = makePiece(move.piece, sideToMove);
Piece piece = makePiece(move.piece(), sideToMove);

if (promotion) {
removePiece(piece, to);
Expand All @@ -876,15 +876,15 @@ void Board::unmakeMove(Move& move) {
placePiece(piece, from);
}

if (to == enPassantSquare && move.piece == PAWN) {
if (to == enPassantSquare && move.piece() == PAWN) {
int8_t offset = sideToMove == White ? -8 : 8;
placePiece(makePiece(PAWN, ~sideToMove), Square(enPassantSquare + offset));
}
else if (capture != None) {
placePiece(capture, to);
}
else {
if (move.piece == KING) {
if (move.piece() == KING) {
if (from == SQ_E1 && to == SQ_G1 && castlingRights & wk) {
removePiece(WhiteRook, SQ_F1);
placePiece(WhiteRook, SQ_H1);
Expand Down
34 changes: 17 additions & 17 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ int Search::qsearch(int depth, int alpha, int beta, int ply) {
for (int i = 0; i < (int)ml.size; i++) {
Move move = ml.list[i];

Piece captured = board.pieceAtB(move.to);
Piece captured = board.pieceAtB(move.to());
// delta pruning, if the move + a large margin is still less then alpha we can safely skip this
if (stand_pat + 400 + piece_values[EG][captured%6] < alpha && !move.promoted && board.nonPawnMat(color)) continue;
if (stand_pat + 400 + piece_values[EG][captured%6] < alpha && !move.promoted() && board.nonPawnMat(color)) continue;

nodes++;
board.makeMove(move);
Expand Down Expand Up @@ -236,7 +236,7 @@ int Search::absearch(int depth, int alpha, int beta, int ply, bool null) {

for (int i = 0; i < ml.size; i++) {
Move move = ml.list[i];
bool capture = board.pieceAtB(move.to) != None;
bool capture = board.pieceAtB(move.to()) != None;

if (!capture) quietMoves++;

Expand All @@ -257,7 +257,7 @@ int Search::absearch(int depth, int alpha, int beta, int ply, bool null) {
if (depth <= 4 && !PvNode
&& !capture && !inCheck && !givesCheck
&& quietMoves > lmpM[depth]
&& !move.promoted) {
&& !move.promoted()) {
board.unmakeMove(move);
continue;
}
Expand Down Expand Up @@ -292,12 +292,12 @@ int Search::absearch(int depth, int alpha, int beta, int ply, bool null) {
}

board.unmakeMove(move);
spentEffort[move.from][move.to] += nodes - nodeCount;
spentEffort[move.from()][move.to()] += nodes - nodeCount;

int bonus = std::clamp(depth * depth, 0, 400);

if (!capture && score < best)
history_table[color][move.piece][move.from][move.to] = std::clamp(history_table[color][move.piece][move.from][move.to] - 32 * bonus, -100000, 16384);
history_table[color][move.piece()][move.from()][move.to()] = std::clamp(history_table[color][move.piece()][move.from()][move.to()] - 32 * bonus, -100000, 16384);

if (score > best) {
best = score;
Expand All @@ -314,7 +314,7 @@ int Search::absearch(int depth, int alpha, int beta, int ply, bool null) {

// update History Table
if (!capture)
history_table[color][move.piece][move.from][move.to] += 2 * (32 * bonus - history_table[color][move.piece][move.from][move.to] * bonus / 512);
history_table[color][move.piece()][move.from()][move.to()] += 2 * (32 * bonus - history_table[color][move.piece()][move.from()][move.to()] * bonus / 512);

if (score >= beta) {
// update Killer Moves
Expand Down Expand Up @@ -409,7 +409,7 @@ int Search::iterative_deepening(int search_depth, uint64_t maxN, Time time) {
}


int effort = nodes - startNodes == 0 ? 0 : (spentEffort[prev_bestmove.from][prev_bestmove.to] * 100) / (nodes - startNodes);
int effort = nodes - startNodes == 0 ? 0 : (spentEffort[prev_bestmove.from()][prev_bestmove.to()] * 100) / (nodes - startNodes);

if (depth >= 8 && effort >= 95 && searchTime != 0 && !adjustedTime) {
adjustedTime = true;
Expand Down Expand Up @@ -444,22 +444,22 @@ int Search::mmlva(Move& move) {
{0, 505, 504, 503, 502, 501, 500},
{0, 605, 604, 603, 602, 601, 600},
{0, 705, 704, 703, 702, 701, 700} };
int attacker = board.piece_type(board.pieceAtB(move.from)) + 1;
int victim = board.piece_type(board.pieceAtB(move.to)) + 1;
int attacker = board.piece_type(board.pieceAtB(move.from())) + 1;
int victim = board.piece_type(board.pieceAtB(move.to())) + 1;
return mvvlva[victim][attacker];
}

int Search::score_move(Move& move, int ply, bool ttMove) {
if (move == pv[ply]) {
return 2147483647;
}
else if (ttMove && move == TTable[board.hashKey % TT_SIZE].move) {
else if (ttMove && move.get() == TTable[board.hashKey % TT_SIZE].move) {
return 2147483647 - 1;
}
else if (move.promoted) {
return 2147483647 - 20 + move.piece;
else if (move.promoted()) {
return 2147483647 - 20 + move.piece();
}
else if (board.pieceAtB(move.to) != None) {
else if (board.pieceAtB(move.to()) != None) {
return mmlva(move) * 10000;
}
else if (move == pv_table[0][ply]) {
Expand All @@ -471,8 +471,8 @@ int Search::score_move(Move& move, int ply, bool ttMove) {
else if (killerMoves[1][ply] == move) {
return killerscore2;
}
else if (history_table[board.sideToMove][move.piece][move.from][move.to]) {
return history_table[board.sideToMove][move.piece][move.from][move.to];
else if (history_table[board.sideToMove][move.piece()][move.from()][move.to()]) {
return history_table[board.sideToMove][move.piece()][move.from()][move.to()];
}
else {
return 0;
Expand Down Expand Up @@ -505,7 +505,7 @@ bool Search::store_entry(U64 index, int depth, int bestvalue, int old_alpha, int
TTable[index].score = bestvalue;
TTable[index].age = startAge;
TTable[index].key = key;
TTable[index].move = pv_table[0][ply];
TTable[index].move = pv_table[0][ply].get();
return true;
}
return false;
Expand Down
12 changes: 6 additions & 6 deletions src/tt.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
#include "types.h"

struct TEntry {
U64 key = 0ULL;
uint8_t depth = 0;
Flag flag = NONEBOUND;
int score = 0;
uint16_t age = 0;
Move move{};
U64 key;
uint8_t depth;
uint8_t flag;
uint16_t move;
int score;
uint16_t age;
};
47 changes: 38 additions & 9 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,43 @@ static constexpr U64 PAWN_ATTACKS_TABLE[2][64] = {
}
};

struct Move {
PieceType piece{ NONETYPE };
Square from{ NO_SQ };
Square to{ NO_SQ };
bool promoted{};
int value{};
Move(PieceType p = NONETYPE, Square f = NO_SQ, Square t = NO_SQ, bool pr = false) :
piece(p), from(f), to(t), promoted(pr) {}
class Move {
public:
uint16_t move;

// move score
int value;

// constructor for encoding a move
inline Move(
PieceType piece = NONETYPE,
Square source = NO_SQ,
Square target = NO_SQ,
bool promoted = false

) {
move = (uint16_t)source | (uint16_t)target << 6 | (uint16_t)piece << 12 | (uint16_t)promoted << 15;
}

inline Square from() {
return Square(move & 0b111111);
}

inline Square to() {
return Square((move & 0b111111000000) >> 6);
}

inline PieceType piece() {
return PieceType((move & 0b111000000000000) >> 12);
}

inline bool promoted() {
return bool((move & 0b1000000000000000) >> 15);
}

inline uint16_t get() {
return move;
}
};

static Move nullmove = Move(NONETYPE, NO_SQ, NO_SQ, false);
Expand All @@ -246,5 +275,5 @@ static constexpr U64 BK_CASTLE_MASK = (1ULL << SQ_F8) | (1ULL << SQ_G8);
static constexpr U64 BQ_CASTLE_MASK = (1ULL << SQ_D8) | (1ULL << SQ_C8) | (1ULL << SQ_B8);

inline bool operator==(Move& m, Move& m2) {
return m.piece == m2.piece && m.from == m2.from && m.to == m2.to && m.promoted == m2.promoted;
return m.move == m2.move;
}

0 comments on commit ba9e15a

Please sign in to comment.