Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuning #32

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ src/version.h
.*
chess2
test/test
tuning/tuning
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ cleanextras:

iwyuextras:
cd src && make iwyu && cd ..
cd tuning && make iwyu && cd ..

chess2: $(obj)
$(CC) $(CFLAGS) -o $@ $^ src/*.o
1 change: 1 addition & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void print_bitboard(BITBOARD bb) {
}

int stopped = 0;
int nodes;

int main(int argc, char *argv[])
{
Expand Down
23 changes: 23 additions & 0 deletions scripts/tune_db_extract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# extract epd database from pgn generated by cutechess for tuning
# cutechess/cutechess-cli -each tc=1/1+0.08 proto=uci -engine cmd=chess-2/chess2_latest book=openings.bin -engine cmd=chess-2/chess2_other book=openings.bin -rounds 60000 -concurrency 4 -pgnout games_fast.pgn -recover &
import chess.pgn

fn = 'games_fast.pgn'

with open(fn, encoding='utf-8') as h:
while True:
game = chess.pgn.read_game(h)
if game is None:
break

for node in game.mainline():
comment = node.comment
if comment=='book':
pass
elif comment.startswith('+100.00') or comment.startswith('-100.00'):
pass
else:
fen = node.board().fen()
result = game.headers[ 'Result' ]
if result == '1-0' or result == '0-1' or result == '1/2-1/2':
print(f'{fen} {result}')
23 changes: 21 additions & 2 deletions src/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "board.h"
#include "move.h"
#include "movegen.h"
#include "moveexec.h"
#include "zobrist.h"

Expand Down Expand Up @@ -153,7 +152,7 @@ void play_uci_moves(BOARD * board, const char * moves) {
} else if (piece == KING && ((ff - tf) == 2 || (tf - ff) == 2)) {
unsigned index = ((fr & BLACK) << 1) | (ff < tf ? 0 : 1);

castle = castling_rook_from_to(index);
castle = castle_rook_from_to[index];
}

move.from = from;
Expand Down Expand Up @@ -285,3 +284,23 @@ HASH calculate_hash(const BOARD * board) {
return result;
}

CASTLE castle_update(const BOARD * board, PIECE piece, BITBOARD fromto) {
CASTLE castle =
((fromto & ((BITBOARD)1 << 0)) << 1) | ((fromto & ((BITBOARD)1 << 7)) >> 7) |
((fromto & ((BITBOARD)1 << 56)) >> 53) | ((fromto & ((BITBOARD)1 << 63)) >> 61);

if (piece == KING) {
castle |= CASTLES_OF(board->next);
}

return board->castle ^ (board->castle & ~castle);
}

const BITBOARD castle_king_from_to[4] = {
0x0000000000000050, 0x0000000000000014, 0x5000000000000000, 0x1400000000000000
};

const BITBOARD castle_rook_from_to[4] = {
0x00000000000000a0, 0x0000000000000009, 0xa000000000000000, 0x0900000000000000
};

4 changes: 4 additions & 0 deletions src/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@ void print_board(const BOARD* board);
void print_fen(const BOARD* board);
HASH calculate_hash(const BOARD* board);

CASTLE castle_update(const BOARD * board, PIECE piece, BITBOARD fromto);
extern const BITBOARD castle_rook_from_to[4];
extern const BITBOARD castle_king_from_to[4];

#endif /* ifndef _BOARD_H_ */
2 changes: 1 addition & 1 deletion src/chess.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ typedef enum {
NO_PIECE_V = 0,
PAWN_V = 100,
KNIGHT_V = 300,
BISHOP_V = 300,
BISHOP_V = 340,
ROOK_V = 500,
QUEEN_V = 900,
KING_V = 10000 } PIECE_VALUE;
Expand Down
27 changes: 16 additions & 11 deletions src/evaluate.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <assert.h>

#include "evaluate.h"
#include "tuned_values.h"
#include "pawns.h"
#include "board.h"
#include "mat_tables.h"
Expand Down Expand Up @@ -113,6 +115,9 @@ int evaluate(const BOARD * board) {
int dir[] = {1, -1};
const MAT_TABLE_ENTRY * mt = get_mat_table_entry(board);
SQUARE kings[6];
int gp = mt->flags & ENDGAME_MASK;

assert(0 <= gp && gp <= 3);

if (mt->flags & DRAWN) {
return 0;
Expand All @@ -125,7 +130,6 @@ int evaluate(const BOARD * board) {

for (COLOUR colour = WHITE; colour <= BLACK; colour++) {
int pawn_value = 0;
static const int rank_values[] = {0, 30, 35, 45, 65, 105, 185, 270};

BITBOARD my_pawns = board->pawns & COLOUR_BB(board, colour);
BITBOARD their_pawns = board->pawns & COLOUR_BB(board, 1 - colour);
Expand All @@ -138,19 +142,19 @@ int evaluate(const BOARD * board) {
DEBUG_PRINT("%s passer\t\t%8.8lx\n", colour_names[colour], pass);
DEBUG_PRINT("%s weak\t\t%8.8lx\n", colour_names[colour], wk);

pawn_value += piece_values[PAWN] * __builtin_popcountll(my_pawns);
pawn_value -= 20 * __builtin_popcountll(iso);
pawn_value += tuned_values[gp].piece_v_pawn_v * __builtin_popcountll(my_pawns);
pawn_value += tuned_values[gp].pawn_isolated * __builtin_popcountll(iso);
while (pass) {
BITBOARD isolated = pass & -pass;
SQUARE sq = __builtin_ctzll(isolated);
SQUARE rank = sq >> 3;
SQUARE erank = colour == WHITE ? rank : 7 - rank;

pawn_value += rank_values[erank];
pawn_value += *(&tuned_values[gp].pawn_ranks_0 + erank);

pass &= pass - 1;
}
pawn_value -= 10 * __builtin_popcountll(wk);
pawn_value += tuned_values[gp].pawn_weak * __builtin_popcountll(wk);

DEBUG_PRINT("%s pawn\t\t%d\n", colour_names[colour], pawn_value);

Expand All @@ -160,6 +164,7 @@ int evaluate(const BOARD * board) {
for (COLOUR colour = WHITE; colour <= BLACK; colour++) {
for (PIECE piece = PAWN + 1; piece < KING; ++piece) {
BITBOARD pieces = *(&board->pawns + piece - PAWN) & COLOUR_BB(board, colour);
int piece_value = *(&tuned_values[gp].piece_v_pawn_v + piece - PAWN);

while (pieces) {
BITBOARD single = pieces & -pieces;
Expand All @@ -169,13 +174,13 @@ int evaluate(const BOARD * board) {

if (colour == WHITE) {
sq = ((7 - rank) << 3) | file;
value += piece_values[piece] + bonuses[piece][sq];
value += piece_value + bonuses[piece][sq];
}
else {
value -= piece_values[piece] + bonuses[piece][sq];
value -= piece_value + bonuses[piece][sq];
}
DEBUG_PRINT("%s %s\t\t%d\n",
colour_names[colour], piece_names[piece], piece_values[piece] + bonuses[piece][sq]);
colour_names[colour], piece_names[piece], piece_value + bonuses[piece][sq]);

pieces &= pieces - 1;
}
Expand Down Expand Up @@ -237,13 +242,13 @@ static inline int king_evaluate(const MAT_TABLE_ENTRY * mt, COLOUR colour, SQUAR
SQUARE sq = sqs[colour];

/* default - piece square interpolate between middle game - endgame */
endgame_factor = mt->flags & ENDGAME_MASK;
static const int shield_value[] = { -40, -20, 0, 0 };
int gp = mt->flags & ENDGAME_MASK;
int shield_value = tuned_values[gp].king_shield;
int safety = __builtin_popcountll(
shield((board->pawns | board->bishops) & COLOUR_BB(board, colour), /* fianchettoed bishops */
colour,
board->kings & COLOUR_BB(board, colour))
) * shield_value[endgame_factor];
) * shield_value;
DEBUG_PRINT("%s king shield\t%d\n", colour_names[colour], safety);

static const int mdl_psqt_weight[] = { 2, 2, 1, 0};
Expand Down
7 changes: 5 additions & 2 deletions src/mat_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,12 @@ static const RULE rules[] = {
{ "0 0 0 0 0 0 0 0 0 0 a b", { 0, B_CHECKMATING} },
{ NULL, { 0, CONSTRAINT } },

#if 0

/* WP WN WB_LSQ WB_DSQ WR WQ BP BN BB_LSQ BB_DSQ BR BQ V F */
{ "a+1=b ", { 0, CONSTRAINT } },
{ "a 0 1 0 0 0 b 0 0 1 0 0", { PAWN_V, 0} }, /* opposite colour bishop endgames */
{ "b 0 1 0 0 0 a 0 0 1 0 0", { -1*PAWN_V, 0} }, /* 1 pawn diff: take away the pawn */
{ "a 0 1 0 0 0 b 0 0 1 0 0", { 100, 0} }, /* opposite colour bishop endgames */
{ "b 0 1 0 0 0 a 0 0 1 0 0", { -100, 0} }, /* 1 pawn diff: take away the pawn */
{ "a+2=b ", { 0, CONSTRAINT } },
{ "a 0 1 0 0 0 b 0 0 1 0 0", { 80, 0} }, /* 2 pawn diff: take away less than a pawn */
{ "b 0 1 0 0 0 a 0 0 1 0 0", { -80, 0} }, /* 3 pawn diff: should be winning? */
Expand Down Expand Up @@ -201,6 +203,7 @@ static const RULE rules[] = {
{ "b+c+d+e+f=6 ", { 0, CONSTRAINT } },
{ ">a b c d e f a b c d e f", { 5, 0} },
{ NULL, { 0, CONSTRAINT } },
#endif

{ NULL, { 0, 0} }
};
Expand Down
24 changes: 1 addition & 23 deletions src/movegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "board.h"
#include "movelist.h"
#include "attacks.h"
#include "tuned_values.h"

typedef enum {
MOVEGEN_START = 0,
Expand Down Expand Up @@ -74,18 +75,6 @@ static BITBOARD normal_attacks(const BOARD * board, PIECE piece, SQUARE sq, BITB
}
}

CASTLE castle_update(const BOARD * board, PIECE piece, BITBOARD fromto) {
CASTLE castle =
((fromto & ((BITBOARD)1 << 0)) << 1) | ((fromto & ((BITBOARD)1 << 7)) >> 7) |
((fromto & ((BITBOARD)1 << 56)) >> 53) | ((fromto & ((BITBOARD)1 << 63)) >> 61);

if (piece == KING) {
castle |= CASTLES_OF(board->next);
}

return board->castle ^ (board->castle & ~castle);
}

/* knight, bishop, rook, queen and king moves excluding specials like castling */
static void add_normal_moves(const BOARD * board, PIECE piece, BITBOARD allowed_targets) {
BITBOARD colour = NEXT_COLOUR_BB(board);
Expand Down Expand Up @@ -267,17 +256,6 @@ void add_pawn_pushes(const BOARD * board) {
}
}

static const BITBOARD castle_king_from_to[4] = {
0x0000000000000050, 0x0000000000000014, 0x5000000000000000, 0x1400000000000000
};

static const BITBOARD castle_rook_from_to[4] = {
0x00000000000000a0, 0x0000000000000009, 0xa000000000000000, 0x0900000000000000
};

BITBOARD castling_rook_from_to(CASTLE castle) {
return castle_rook_from_to[castle];
}

/* from 0000...010.....010.... you get
* 0000000001111111000000
Expand Down
5 changes: 0 additions & 5 deletions src/movegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#define _MOVEGEN_H_

#include "board.h"
#include "chess.h"
#include "move.h"
#include "killer.h"
#include "pv.h"
Expand Down Expand Up @@ -38,8 +37,4 @@ MOVE * moves(const BOARD * board, int ply, const PV * pv, const KILLER * killer,
/* call if a search returns early - before moves() returning NULL */
void moves_done(int ply);

/* TODO move these */
CASTLE castle_update(const BOARD * board, PIECE piece, BITBOARD fromto);
BITBOARD castling_rook_from_to(CASTLE castle);

#endif /* ifndef _MOVEGEN_H_ */
2 changes: 1 addition & 1 deletion src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "chess.h"

static struct timespec start;
unsigned long long nodes;
extern unsigned long long nodes;

#define STDIN 0
int check_for_input(void) {
Expand Down
2 changes: 2 additions & 0 deletions src/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

extern unsigned long long nodes;

int quiesce(BOARD * board, int ply, int alpha, int beta);

int negascout(BOARD* board,
int ply,
int depth,
Expand Down
8 changes: 1 addition & 7 deletions src/see.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@
#include "see.h"
#include "attacks.h"

/* make bishops worth more because the evaluation gives bonuses to bishop pairs,
* so we have a better chance of getting the order right
* thus beta cutting more
**/
static const int piece_values_mod[] = {NO_PIECE_V, PAWN_V, KNIGHT_V, BISHOP_V + 40, ROOK_V, QUEEN_V, KING_V};

int see(const BOARD * board, const MOVE * move) {
BITBOARD from = move->from;
BITBOARD to = move->to;
Expand Down Expand Up @@ -119,7 +113,7 @@ int see(const BOARD * board, const MOVE * move) {
ply--;
for (ply--; ply >= 0; ply--) {
value = MAX(value, 0);
value = piece_values_mod[captures[ply]] - value;
value = piece_values[captures[ply]] - value;
}

/* THE END */
Expand Down
76 changes: 76 additions & 0 deletions src/tuned_values.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "tuned_values.h"

const TUNED_VALUES tuned_values[4] = {
{
100, /* piece_v_pawn_v */
159, /* piece_v_knight_v */
169, /* piece_v_bishop_v */
367, /* piece_v_rook_v */
728, /* piece_v_queen_v */
0, /* pawn_ranks_0 */
49, /* pawn_ranks_1 */
25, /* pawn_ranks_2 */
1, /* pawn_ranks_3 */
11, /* pawn_ranks_4 */
83, /* pawn_ranks_5 */
186, /* pawn_ranks_6 */
270, /* pawn_ranks_7 */
-8, /* pawn_isolated */
-9, /* pawn_weak */
-2, /* king_shield_0 */
},
{
100, /* piece_v_pawn_v */
159, /* piece_v_knight_v */
169, /* piece_v_bishop_v */
367, /* piece_v_rook_v */
728, /* piece_v_queen_v */
0, /* pawn_ranks_0 */
49, /* pawn_ranks_1 */
25, /* pawn_ranks_2 */
1, /* pawn_ranks_3 */
11, /* pawn_ranks_4 */
83, /* pawn_ranks_5 */
186, /* pawn_ranks_6 */
270, /* pawn_ranks_7 */
-8, /* pawn_isolated */
-9, /* pawn_weak */
-25, /* king_shield_1 */
},
{
100, /* piece_v_pawn_v */
159, /* piece_v_knight_v */
169, /* piece_v_bishop_v */
367, /* piece_v_rook_v */
728, /* piece_v_queen_v */
0, /* pawn_ranks_0 */
49, /* pawn_ranks_1 */
25, /* pawn_ranks_2 */
1, /* pawn_ranks_3 */
11, /* pawn_ranks_4 */
83, /* pawn_ranks_5 */
186, /* pawn_ranks_6 */
270, /* pawn_ranks_7 */
-8, /* pawn_isolated */
-9, /* pawn_weak */
5, /* king_shield_2 */
},
{
100, /* piece_v_pawn_v */
159, /* piece_v_knight_v */
169, /* piece_v_bishop_v */
367, /* piece_v_rook_v */
728, /* piece_v_queen_v */
0, /* pawn_ranks_0 */
49, /* pawn_ranks_1 */
25, /* pawn_ranks_2 */
1, /* pawn_ranks_3 */
11, /* pawn_ranks_4 */
83, /* pawn_ranks_5 */
186, /* pawn_ranks_6 */
270, /* pawn_ranks_7 */
-8, /* pawn_isolated */
-9, /* pawn_weak */
-9, /* king_shield_3 */
},
};
Loading