add info in pos_print, start perft TT testing
This commit is contained in:
10
Makefile
10
Makefile
@@ -70,7 +70,7 @@ CPPFLAGS += -DBUG_ON # brlib bug.h
|
||||
#CPPFLAGS += -DDEBUG_FEN # FEN decoding
|
||||
|
||||
# hash.c
|
||||
#CPPFLAGS += -HASH_VERIFY # chk zobrist consistency
|
||||
CPPFLAGS += -DZOBRIST_VERIFY # chk zobrist consistency
|
||||
|
||||
# attack.c
|
||||
#CPPFLAGS += -DDEBUG_ATTACK_ATTACKERS # sq_attackers
|
||||
@@ -339,7 +339,7 @@ memcheck: targets
|
||||
.PHONY: testing test
|
||||
|
||||
TEST := piece-test fen-test bitboard-test movegen-test attack-test
|
||||
TEST += movedo-test perft-test
|
||||
TEST += movedo-test perft-test tt-test
|
||||
|
||||
PIECE_OBJS := piece.o
|
||||
FEN_OBJS := $(PIECE_OBJS) fen.o position.o bitboard.o board.o \
|
||||
@@ -349,6 +349,7 @@ MOVEGEN_OBJS := $(BB_OBJS) move.o move-gen.o
|
||||
ATTACK_OBJS := $(MOVEGEN_OBJS)
|
||||
MOVEDO_OBJS := $(ATTACK_OBJS) move-do.o misc.o
|
||||
PERFT_OBJS := $(MOVEDO_OBJS) search.o
|
||||
TT_OBJS := $(MOVEDO_OBJS)
|
||||
|
||||
TEST := $(addprefix $(BINDIR)/,$(TEST))
|
||||
|
||||
@@ -359,6 +360,7 @@ MOVEGEN_OBJS := $(addprefix $(OBJDIR)/,$(MOVEGEN_OBJS))
|
||||
ATTACK_OBJS := $(addprefix $(OBJDIR)/,$(ATTACK_OBJS))
|
||||
MOVEDO_OBJS := $(addprefix $(OBJDIR)/,$(MOVEDO_OBJS))
|
||||
PERFT_OBJS := $(addprefix $(OBJDIR)/,$(PERFT_OBJS))
|
||||
TT_OBJS := $(addprefix $(OBJDIR)/,$(TT_OBJS))
|
||||
|
||||
test:
|
||||
echo TEST=$(TEST)
|
||||
@@ -394,6 +396,10 @@ bin/perft-test: test/perft-test.c test/common-test.h $(PERFT_OBJS)
|
||||
@echo compiling $@ test executable.
|
||||
@$(CC) $(ALL_CFLAGS) $< $(PERFT_OBJS) $(ALL_LDFLAGS) -o $@
|
||||
|
||||
bin/tt-test: test/tt-test.c test/common-test.h $(TT_OBJS)
|
||||
@echo compiling $@ test executable.
|
||||
@$(CC) $(ALL_CFLAGS) $< $(TT_OBJS) $(ALL_LDFLAGS) -o $@
|
||||
|
||||
##################################### Makefile debug
|
||||
.PHONY: showflags wft
|
||||
|
||||
|
75
src/hash.c
75
src/hash.c
@@ -206,7 +206,7 @@ int tt_create(s32 sizemb)
|
||||
hash_tt.nbits = nbits;
|
||||
|
||||
hash_tt.nbuckets = BIT(hash_tt.nbits);
|
||||
hash_tt.nkeys = hash_tt.nbuckets * NBUCKETS;
|
||||
hash_tt.nkeys = hash_tt.nbuckets * ENTRIES_PER_BUCKET;
|
||||
|
||||
hash_tt.bytes = hash_tt.nbuckets * sizeof(bucket_t);
|
||||
hash_tt.mb = hash_tt.bytes / 1024 / 1024;
|
||||
@@ -238,9 +238,10 @@ void tt_clear()
|
||||
if (hash_tt.keys)
|
||||
memset(hash_tt.keys, 0, hash_tt.bytes);
|
||||
|
||||
hash_tt.used_buckets = 0;
|
||||
hash_tt.used_keys = 0;
|
||||
hash_tt.collisions = 0;
|
||||
hash_tt.hits = 0;
|
||||
hash_tt.misses = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,12 +271,12 @@ hentry_t *tt_probe(hkey_t key)
|
||||
bucket = hash_tt.keys + (key & hash_tt.mask);
|
||||
|
||||
/* find key in buckets */
|
||||
for (i = 0; i < NBUCKETS; ++i) {
|
||||
for (i = 0; i < ENTRIES_PER_BUCKET; ++i) {
|
||||
entry = bucket->entry + i;
|
||||
if (key == entry->key)
|
||||
break;
|
||||
}
|
||||
if (i < NBUCKETS)
|
||||
if (i < ENTRIES_PER_BUCKET)
|
||||
return entry;
|
||||
return NULL;
|
||||
}
|
||||
@@ -299,18 +300,18 @@ hentry_t *tt_probe_perft(const hkey_t key, const u16 depth)
|
||||
bucket = hash_tt.keys + (key & hash_tt.mask);
|
||||
|
||||
/* find key in buckets */
|
||||
for (i = 0; i < NBUCKETS; ++i) {
|
||||
for (i = 0; i < ENTRIES_PER_BUCKET; ++i) {
|
||||
entry = bucket->entry + i;
|
||||
if (key == entry->key && HASH_PERFT_DEPTH(entry->data) == depth) {
|
||||
printf("tt hit: key=%lx bucket=%lu entry=%d!\n",
|
||||
key, bucket - hash_tt.keys, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < NBUCKETS)
|
||||
hash_tt.hits++;
|
||||
//printf("tt hit: key=%lx bucket=%lu entry=%d!\n",
|
||||
// key, bucket - hash_tt.keys, i);
|
||||
return entry;
|
||||
printf("tt miss: key=%lx bucket=%lu\n",
|
||||
key, bucket - hash_tt.keys);
|
||||
}
|
||||
}
|
||||
//printf("tt miss: key=%lx bucket=%lu\n",
|
||||
// key, bucket - hash_tt.keys);
|
||||
hash_tt.misses++;
|
||||
return TT_MISS;
|
||||
}
|
||||
|
||||
@@ -325,24 +326,36 @@ hentry_t *tt_store_perft(const hkey_t key, const u16 depth, const u64 nodes)
|
||||
{
|
||||
bucket_t *bucket;
|
||||
hentry_t *entry;
|
||||
int replace = -1, i;
|
||||
// uint mindepth = 0;
|
||||
int replace = -1, newkey = 0;
|
||||
uint mindepth = 1024;
|
||||
u64 data = HASH_PERFT(depth, nodes);
|
||||
printf("tt_store: key=%lx data=%lx depth=%d=%d nodes=%lu=%lu\n",
|
||||
key, data, depth, HASH_PERFT_DEPTH(data), nodes, HASH_PERFT_VAL(data));
|
||||
|
||||
//printf("tt_store: key=%lx data=%lx depth=%d=%d nodes=%lu=%lu\n",
|
||||
// key, data, depth, HASH_PERFT_DEPTH(data), nodes, HASH_PERFT_VAL(data));
|
||||
printf("tt_store: key=%lx depth=%d nodes=%lu ",
|
||||
key, depth, nodes);
|
||||
bug_on(!hash_tt.keys);
|
||||
bucket = hash_tt.keys + (key & hash_tt.mask);
|
||||
|
||||
/* find key in buckets */
|
||||
for (i = 0; i < NBUCKETS; ++i) {
|
||||
for (int i = 0; i < ENTRIES_PER_BUCKET; ++i) {
|
||||
entry = bucket->entry + i;
|
||||
if (key == entry->key && HASH_PERFT_DEPTH(entry->data)) {
|
||||
printf("tt_store: sup key/depth, this should not happen!\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!entry->key) {
|
||||
replace = i;
|
||||
break;
|
||||
}
|
||||
/* we replace hash if we are higher in tree */
|
||||
if (HASH_PERFT_DEPTH(entry->data) < mindepth) {
|
||||
mindepth = HASH_PERFT_DEPTH(entry->data);
|
||||
replace = i;
|
||||
}
|
||||
/*
|
||||
* else {
|
||||
* /\* we replace hash if we are higher in tree *\/
|
||||
*
|
||||
* if (key == entry->key && HASH_PERFT_DEPTH(entry->data) > mindepth) {
|
||||
* mindepth = HASH_PERFT_DEPTH(entry->data);
|
||||
* replace = i;
|
||||
@@ -351,12 +364,32 @@ hentry_t *tt_store_perft(const hkey_t key, const u16 depth, const u64 nodes)
|
||||
*/
|
||||
}
|
||||
if (replace >= 0) {
|
||||
printf("replacing key=%lx=%lx bucket=%lu idx=%d val=%lu\n",
|
||||
key, entry->key, bucket - hash_tt.keys, replace, nodes);
|
||||
entry = bucket->entry + replace;
|
||||
if (HASH_PERFT_VAL(entry->data)) {
|
||||
printf("REPL entry=%lu[%d] key=%lx->%lx val=%lu->%lu\n",
|
||||
bucket - hash_tt.keys, replace,
|
||||
entry->key, key,
|
||||
HASH_PERFT_VAL(entry->data), nodes);
|
||||
} else {
|
||||
printf("NEW entry=%lu[%d] key=%lx val=%lu\n",
|
||||
bucket - hash_tt.keys, replace,
|
||||
entry->key, nodes);
|
||||
}
|
||||
entry->key = key;
|
||||
entry->data = data;
|
||||
return entry;
|
||||
} else {
|
||||
printf("TT full, skip\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void tt_stats()
|
||||
{
|
||||
printf("TT: sz=%u bits=%u bcks=%'lu entries=%'lu mask=%10x"
|
||||
"used=%lu hits/miss=%'lu/%'lu\n",
|
||||
hash_tt.mb, hash_tt.nbits, hash_tt.nbuckets, hash_tt.nkeys, hash_tt.mask,
|
||||
hash_tt.used_keys, hash_tt.hits, hash_tt.misses);
|
||||
//printf("\tused=%lu hits/miss=%lu/%lu\n",
|
||||
// hash_tt.used_keys, hash_tt.hits, hash_tt.misses);
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "chessdefs.h"
|
||||
|
||||
#define NBUCKETS 4 /* buckets per hash table entry */
|
||||
#define ENTRIES_PER_BUCKET 4 /* buckets per hash table entry */
|
||||
|
||||
#define HASH_SIZE_DEFAULT 32 /* default: 32Mb */
|
||||
#define HASH_SIZE_MIN 4
|
||||
@@ -59,7 +59,7 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
hentry_t entry[NBUCKETS];
|
||||
hentry_t entry[ENTRIES_PER_BUCKET];
|
||||
} bucket_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -78,9 +78,11 @@ typedef struct {
|
||||
u32 mask; /* nbuckets - 1, key mask */
|
||||
|
||||
/* stats - unsure about usage */
|
||||
size_t used_buckets;
|
||||
//size_t used_buckets;
|
||||
size_t used_keys;
|
||||
u64 collisions;
|
||||
u64 hits;
|
||||
u64 misses;
|
||||
} hasht_t;
|
||||
|
||||
/* hack:
|
||||
@@ -128,5 +130,6 @@ void tt_delete(void);
|
||||
hentry_t *tt_probe(hkey_t key);
|
||||
hentry_t *tt_probe_perft(const hkey_t key, const u16 depth);
|
||||
hentry_t *tt_store_perft(const hkey_t key, const u16 depth, const u64 nodes);
|
||||
void tt_stats(void);
|
||||
|
||||
#endif /* HASH_H */
|
||||
|
@@ -108,7 +108,8 @@ pos_t *move_do(pos_t *pos, const move_t move, state_t *state)
|
||||
}
|
||||
} else if (is_enpassant(move)) { /* clear grabbed pawn */
|
||||
square_t grabbed = to - up;
|
||||
key ^= zobrist_pieces[pos->board[grabbed]][grabbed];
|
||||
piece_t pc = pos->board[grabbed];
|
||||
key ^= zobrist_pieces[pc][grabbed];
|
||||
pos_clr_sq(pos, grabbed);
|
||||
}
|
||||
}
|
||||
|
@@ -429,9 +429,10 @@ void pos_print(const pos_t *pos)
|
||||
char str[128];
|
||||
|
||||
board_print(pos->board);
|
||||
printf("fen %s\n", pos2fen(pos, str));
|
||||
printf("checkers: %s\n", pos_checkers2str(pos, str, sizeof(str)));
|
||||
printf("pinners : %s\n", pos_pinners2str(pos, str, sizeof(str)));
|
||||
printf("key:%lx ", pos->key);
|
||||
printf("fen: %s\n", pos2fen(pos, str));
|
||||
printf("checkers:%s ", pos_checkers2str(pos, str, sizeof(str)));
|
||||
printf("pinners: %s ", pos_pinners2str(pos, str, sizeof(str)));
|
||||
printf("blockers: %s\n", pos_blockers2str(pos, str, sizeof(str)));
|
||||
}
|
||||
|
||||
|
42
src/search.c
42
src/search.c
@@ -43,13 +43,16 @@
|
||||
*/
|
||||
u64 perft(pos_t *pos, int depth, int ply, bool output)
|
||||
{
|
||||
int subnodes;
|
||||
u64 nodes = 0;
|
||||
static movelist_t stack;
|
||||
//int subnodes;
|
||||
u64 subnodes, nodes = 0;
|
||||
movelist_t movelist;
|
||||
move_t *move, *last;
|
||||
state_t state;
|
||||
|
||||
movelist.nmoves = 0;
|
||||
if (ply == 1)
|
||||
stack.nmoves = 0;
|
||||
|
||||
pos_set_checkers_pinners_blockers(pos);
|
||||
|
||||
pos_legal(pos, pos_gen_pseudo(pos, &movelist));
|
||||
@@ -59,19 +62,46 @@ u64 perft(pos_t *pos, int depth, int ply, bool output)
|
||||
nodes++;
|
||||
} else {
|
||||
move_do(pos, *move, &state);
|
||||
stack.move[stack.nmoves++] = *move;
|
||||
if (ply == 2 &&
|
||||
//move_from(*move) == F7 &&
|
||||
//move_to(*move) == F5 &&
|
||||
move_from(stack.move[stack.nmoves-2]) == B2 &&
|
||||
move_to(stack.move[stack.nmoves-2]) == B4 &&
|
||||
move_from(stack.move[stack.nmoves-1]) == F7 &&
|
||||
move_to(stack.move[stack.nmoves-1]) == F5
|
||||
) {
|
||||
//&& pos->board[F5] == B_PAWN) {
|
||||
moves_print(&stack, 0);
|
||||
pos_print(pos);
|
||||
}
|
||||
if (depth == 2) {
|
||||
movelist_t movelist2;
|
||||
pos_set_checkers_pinners_blockers(pos);
|
||||
subnodes = pos_legal(pos, pos_gen_pseudo(pos, &movelist2))->nmoves;
|
||||
} else {
|
||||
hentry_t *entry;
|
||||
//if (ply >= 4 && ply <= 8) {
|
||||
if (ply == 4) {
|
||||
if ((entry = tt_probe_perft(pos->key, depth))) {
|
||||
subnodes = HASH_PERFT_VAL(entry->data);
|
||||
printf("tt hit key=%lx ply=%d depth=%d nodes=%lu\n",
|
||||
pos->key, ply, depth, subnodes);
|
||||
} else {
|
||||
subnodes = perft(pos, depth - 1, ply + 1, output);
|
||||
tt_store_perft(pos->key, depth, subnodes);
|
||||
}
|
||||
} else {
|
||||
subnodes = perft(pos, depth - 1, ply + 1, output);
|
||||
}
|
||||
}
|
||||
if (output && ply == 1) {
|
||||
char movestr[8];
|
||||
printf("%s: %d\n", move_str(movestr, *move, 0), subnodes);
|
||||
printf("%s: %lu\n", move_to_str(movestr, *move, 0), subnodes);
|
||||
}
|
||||
nodes += subnodes;
|
||||
move_undo(pos, *move, &state);
|
||||
stack.nmoves--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +129,7 @@ u64 perft_alt(pos_t *pos, int depth, int ply, bool output)
|
||||
move_t *move, *last;
|
||||
state_t state;
|
||||
|
||||
movelist.nmoves = 0;
|
||||
//movelist.nmoves = 0;
|
||||
pos_set_checkers_pinners_blockers(pos);
|
||||
state = pos->state;
|
||||
|
||||
@@ -119,7 +149,7 @@ u64 perft_alt(pos_t *pos, int depth, int ply, bool output)
|
||||
}
|
||||
if (output && ply == 1) {
|
||||
char movestr[8];
|
||||
printf("%s: %d\n", move_str(movestr, *move, 0), subnodes);
|
||||
printf("%s: %d\n", move_to_str(movestr, *move, 0), subnodes);
|
||||
}
|
||||
nodes += subnodes;
|
||||
move_undo_alt(pos, *move);
|
||||
|
@@ -28,14 +28,30 @@ struct fentest {
|
||||
char *comment;
|
||||
char *fen;
|
||||
} fentest[] = {
|
||||
/******************* TEMP TESTS BELOW *******************/
|
||||
|
||||
/*
|
||||
{ __LINE__, 1,
|
||||
"",
|
||||
""
|
||||
},
|
||||
* { __LINE__, MOVEGEN | MOVEDO | PERFT,
|
||||
* "bug perft TT après 1.b4 f5",
|
||||
* "1nbqkbn1/ppp1p1pp/8/r1rpPpK1/1P6/8/P1PP1PPP/RNBQ1BNR w - f6 0 2"
|
||||
* },
|
||||
*/
|
||||
|
||||
/* ***************** TEMP TESTS ABOVE ************************** */
|
||||
/*
|
||||
* { __LINE__, MOVEGEN | MOVEDO | PERFT,
|
||||
* "bug perft TT après 1.b4",
|
||||
* "1nbqkbn1/ppp1pppp/8/r1rpP1K1/1P6/8/P1PP1PPP/RNBQ1BNR b - - 0 1",
|
||||
* },
|
||||
*/
|
||||
|
||||
{ __LINE__, MOVEGEN | MOVEDO | PERFT,
|
||||
"bug perft TT",
|
||||
"1nbqkbn1/ppp1pppp/8/r1rpP1K1/8/8/PPPP1PPP/RNBQ1BNR w - d6 0 1",
|
||||
},
|
||||
|
||||
/* ***************** END of TEMP TESTS ******************/
|
||||
/* below line ignored if first test */
|
||||
{ __LINE__, 0, NULL, NULL },
|
||||
|
||||
{ __LINE__, MOVEGEN | MOVEDO | PERFT,
|
||||
"illegal white e.p.",
|
||||
@@ -425,6 +441,10 @@ static int fentest_cur = -1;
|
||||
static char *next_fen(uint module)
|
||||
{
|
||||
fentest_cur++;
|
||||
|
||||
/* skip first entry if NULL - for special testing, see */
|
||||
if (fentest_cur == 0 && fentest[fentest_cur].fen == NULL)
|
||||
fentest_cur++;
|
||||
while (fentest[fentest_cur].fen && !(fentest[fentest_cur].modules & module))
|
||||
fentest_cur++;
|
||||
return fentest[fentest_cur].fen;
|
||||
|
@@ -255,8 +255,8 @@ static __unused void compare_moves(movelist_t *fish, movelist_t *me)
|
||||
|
||||
static int usage(char *prg)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d depth] [-p pertf-modules] [-n][-v]\n", prg);
|
||||
fprintf(stderr, "\t-d: depth, -p: 1-3, -n: no SF res check, -v: output moves\n");
|
||||
fprintf(stderr, "Usage: %s [-cmv][-d depth] [-p perft-version] \n", prg);
|
||||
fprintf(stderr, "\t-c/m: print comments/moves, -n: no SF check, -d: depth, -p: 1-3, \n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -264,6 +264,7 @@ int main(int ac, char**av)
|
||||
{
|
||||
int test_line;
|
||||
u64 sf_count = 0, my_count;
|
||||
bool comment = false;
|
||||
char *fen;
|
||||
pos_t *pos = NULL, *fenpos;
|
||||
pos_t *fishpos = pos_new();
|
||||
@@ -283,8 +284,11 @@ int main(int ac, char**av)
|
||||
int opt, depth = 6, run = 3;
|
||||
bool sf_run = true, perft_output = false;
|
||||
|
||||
while ((opt = getopt(ac, av, "vnd:p:")) != -1) {
|
||||
while ((opt = getopt(ac, av, "cmnd:p:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
comment = true;
|
||||
break;
|
||||
case 'd':
|
||||
depth = atoi(optarg);
|
||||
break;
|
||||
@@ -294,7 +298,7 @@ int main(int ac, char**av)
|
||||
case 'n':
|
||||
sf_run = false;
|
||||
break;
|
||||
case 'v':
|
||||
case 'm':
|
||||
perft_output = true;
|
||||
break;
|
||||
default:
|
||||
@@ -315,7 +319,10 @@ int main(int ac, char**av)
|
||||
|
||||
CLOCK_DEFINE(clock, CLOCK_MONOTONIC);
|
||||
while ((fen = next_fen(PERFT | MOVEDO))) {
|
||||
if (comment)
|
||||
printf("%s\n", *cur_comment()? cur_comment(): "<FIXME>");
|
||||
test_line = cur_line();
|
||||
tt_clear();
|
||||
if (!(fenpos = fen2pos(pos, fen))) {
|
||||
printf("wrong fen line = %d: [%s]\n", test_line, fen);
|
||||
continue;
|
||||
@@ -370,6 +377,7 @@ int main(int ac, char**av)
|
||||
printf("pt1 ERR: line=%3d sf=%'lu me=%'lu \"%s\"\n",
|
||||
test_line, sf_count, my_count, fen);
|
||||
}
|
||||
tt_stats();
|
||||
}
|
||||
|
||||
if (run & 2) {
|
||||
|
159
test/tt-test.c
Normal file
159
test/tt-test.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/* tt-test.c - transposition table test.
|
||||
*
|
||||
* Copyright (C) 2024 Bruno Raoult ("br")
|
||||
* Licensed under the GNU General Public License v3.0 or later.
|
||||
* Some rights reserved. See COPYING.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this
|
||||
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <locale.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <brlib.h>
|
||||
|
||||
#include "chessdefs.h"
|
||||
#include "fen.h"
|
||||
#include "position.h"
|
||||
#include "move.h"
|
||||
#include "move-do.h"
|
||||
#include "move-gen.h"
|
||||
#include "search.h"
|
||||
|
||||
// #include "common-test.h"
|
||||
|
||||
static move_t move_in_movelist(movelist_t *ml, square_t from, square_t to, piece_type_t pt)
|
||||
{
|
||||
const int nmoves = ml->nmoves;
|
||||
const move_t *moves = ml->move;
|
||||
int movenum = 0;
|
||||
move_t move;
|
||||
for (movenum = 0; movenum < nmoves; ++movenum) {
|
||||
move = moves[movenum];
|
||||
printf("compare %s%s to %s%s pt=%d ",
|
||||
sq_to_string(from), sq_to_string(to),
|
||||
sq_to_string(move_from(move)),
|
||||
sq_to_string(move_to(move)),
|
||||
pt
|
||||
);
|
||||
if (move_from(move) == from && move_to(move) == to) {
|
||||
printf("HIT!\n");
|
||||
if (pt != NO_PIECE_TYPE && move_promoted(move) != pt)
|
||||
continue;
|
||||
printf("move_in_movelist(%s%s) found from=%s to=%s\n",
|
||||
sq_to_string(from), sq_to_string(to),
|
||||
sq_to_string(move_from(move)),
|
||||
sq_to_string(move_to(move)));
|
||||
return move;
|
||||
} else
|
||||
puts("");
|
||||
}
|
||||
return MOVE_NONE;
|
||||
}
|
||||
|
||||
static move_t move_from_str(pos_t *pos, const char *move)
|
||||
{
|
||||
movelist_t movelist;
|
||||
square_t from = sq_from_string(move);
|
||||
square_t to = sq_from_string(move + 2);
|
||||
piece_type_t promoted = piece_t_from_char(*(move + 4));
|
||||
printf("from=%o to=%o promoted=%d\n", from, to, promoted);
|
||||
|
||||
pos_set_checkers_pinners_blockers(pos);
|
||||
pos_legal(pos, pos_gen_pseudo(pos, &movelist));
|
||||
return move_in_movelist(&movelist, from, to, promoted);
|
||||
}
|
||||
|
||||
static void pr_entry(hentry_t *entry)
|
||||
{
|
||||
if (!entry)
|
||||
printf("entry: NULL\n");
|
||||
else {
|
||||
printf("entry: key=%lx depth=%d n=%lu\n",
|
||||
entry->key, HASH_PERFT_DEPTH(entry->data),
|
||||
HASH_PERFT_VAL(entry->data));
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
pos_t *pos = NULL;
|
||||
char *token, *str, buf[128];
|
||||
hentry_t *entry;
|
||||
move_t move;
|
||||
state_t state;
|
||||
//movelist_t movelist;
|
||||
|
||||
const char *moves_array[] = {
|
||||
"e2e4 e7e5 g1f3 b8c6",
|
||||
"e2e4 b8c6 g1f3 e7e5"
|
||||
};
|
||||
|
||||
init_all();
|
||||
|
||||
for (uint i = 0; i < ARRAY_SIZE(moves_array); ++i) {
|
||||
int depth = 0;
|
||||
str = strdup(moves_array[i]);
|
||||
printf("%2d: ", i + 1);
|
||||
|
||||
pos = startpos(pos);
|
||||
entry = tt_store_perft(pos->key, 0, 123 + depth);
|
||||
pr_entry(entry);
|
||||
token = strtok(str, " \t");
|
||||
while (token) {
|
||||
depth++;
|
||||
printf("%s ", token);
|
||||
|
||||
//pos_set_checkers_pinners_blockers(pos);
|
||||
//pos_legal(pos, pos_gen_pseudo(pos, &movelist));
|
||||
move = move_from_str(pos, token);
|
||||
printf("move: %s\n", move_to_str(buf, move, 0));
|
||||
move_do(pos, move, &state);
|
||||
if ((entry = tt_probe_perft(pos->key, depth))) {
|
||||
printf("tt hit: depth=%d val=%lu",
|
||||
HASH_PERFT_DEPTH(entry->data),
|
||||
HASH_PERFT_VAL(entry->data));
|
||||
} else {
|
||||
tt_store_perft(pos->key, i + 1, depth);
|
||||
printf("tt store: depth=%d val=%lu", depth, (u64)i * 123);
|
||||
};
|
||||
|
||||
token = strtok(NULL, " \t");
|
||||
}
|
||||
printf("\n");
|
||||
free(str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ccls bug report: https://github.com/emacs-lsp/emacs-ccls/issues/126
|
||||
*/
|
||||
/*
|
||||
* int called(int), caller();
|
||||
*
|
||||
* /\**
|
||||
* * called() - test ccls.
|
||||
* * @x: int, the test value
|
||||
* *
|
||||
* * @called() description.
|
||||
* *
|
||||
* * @return: int, a very interesting value.
|
||||
* *\/
|
||||
* int called(int x) { return x; }
|
||||
*
|
||||
* int caller()
|
||||
* {
|
||||
* int i = 0;
|
||||
* called(int x)
|
||||
* return i;
|
||||
* }
|
||||
*/
|
Reference in New Issue
Block a user