Esempio n. 1
0
void
bench(void)
{
	Chess chess;
	SearchData sd;
	S64 timer;
	int npos = 0;
	int nfen = (int)(sizeof(bench_fen) / sizeof(char*));
	
	double avg_bfactor;
	double t_elapsed;
	double hhit_rate;
	U64 nnodes_all;	/* num. of all nodes (main + qs) */
	int nps;	/* nodes (all types) per second */
	int i;
	
	init_chess(&chess);
	init_search_data(&sd);
	chess.max_depth = 8;
	chess.increment = 60000;

	printf("Running benchmark at search depth %d...\n", chess.max_depth);
	timer = get_ms();
	progressbar(nfen, 0);
	for (i = 0; i < nfen; i++) {
		const char *fen = bench_fen[i];
		if (strlen(fen) <= 1)
			continue;
		if (!fen_to_board(&chess.board, fen)) {
			id_search(&chess, NULLMOVE);
			if (chess.sd.cmd_type != CMDT_CONTINUE) {
				printf("Benchmark cancelled by user\n");
				return;
			}

			sd.nnodes += chess.sd.nnodes;
			sd.nqs_nodes += chess.sd.nqs_nodes;
			sd.nhash_probes += chess.sd.nhash_probes;
			sd.nhash_hits += chess.sd.nhash_hits;
			sd.bfactor += chess.sd.bfactor;
			npos++;
			progressbar(nfen, npos);
		} else
			printf("\nInvalid FEN string: %s\n", fen);
	}

	timer = get_ms() - timer;
	t_elapsed = timer / 1000.0;
	avg_bfactor = sd.bfactor / npos;
	hhit_rate = (sd.nhash_hits * 100.0) / sd.nhash_probes;
	nnodes_all = sd.nnodes + sd.nqs_nodes;
	nps = (double)nnodes_all / ((double)timer / 1000.0);
	printf("\n\nBenchmark finished in %.2f seconds.\n", t_elapsed);
	printf("Main nodes searched: %" PRIu64 "\n", sd.nnodes);
	printf("Quiescence nodes searched: %" PRIu64 "\n", sd.nqs_nodes);
	printf("Total nodes per second: %d\n", nps);
	printf("Average branching factor: %.2f\n", avg_bfactor);
	printf("Hash table hit rate: %.2f%%\n", hhit_rate);
}
Esempio n. 2
0
/* Choose the best move (by searching or using the book), and make it.  */
static void
cpu_move(Chess *chess)
{
	bool book_used = false;
	char san_move[MAX_BUF];
	char str_move[MAX_BUF];
	U32 move = NULLMOVE;
	int score = 0;
	S64 timer;
	Board *board;

	ASSERT(1, chess != NULL);

	board = &chess->board;
	timer = get_ms();
	
	chess->sd.cmd_type = CMDT_CONTINUE;
	if (settings.book_type != BOOK_OFF)
		move = get_book_move(board, chess->show_pv, chess->book);
	if (move != NULLMOVE) {
		book_used = true;
		chess->in_book = true;
	} else {
		score = id_search(chess, NULLMOVE);
		if (chess->sd.cmd_type == CMDT_CANCEL) {
			chess->cpu_color = COLOR_NONE;
			return;
		}
		move = chess->sd.move;
		chess->in_book = false;
	}
	timer = get_ms() - timer;

	ASSERT(1, move != NULLMOVE);
	move_to_str(move, str_move);

	if (SIGN(board->color)*score < VAL_RESIGN) {
		if (board->color == WHITE)
			printf("0-1 {White resigns}\n");
		else
			printf("1-0 {Black resigns}\n");
		chess->game_over = true;
		return;
	}

	printf("move %s\n", str_move);
	if (chess->debug && chess->sd.nnodes > 0) {
		print_search_data(&chess->sd, (int)timer);
		printf("Score: %d\n", score);
	}

	move_to_san(san_move, board, move);
	update_game_log(board, san_move, score, book_used);
	update_game(chess, move);
}
Esempio n. 3
0
PRIVATE struct id_rec *expand_getid()
{
	struct id_rec *id;
	char *s = expand_getstr2(SQ_ID);

	if (s) {
		id = id_search(s);
		mem_free(s);
	} else
		id = NULL;

	return id;
}
Esempio n. 4
0
/* Run a test position (eg. WAC, ECM, WCSAC).

   Format of pos: <FEN> <"bm" or "am"> <move>; <position id>;
   - "bm" means <move> is the best move, "am" means <move> should be avoided
   - the move is in SAN notation
   - position id can be omitted
   - example: R7/P4k2/8/8/8/8/r7/6K1 w - - bm Rg8; id "WAC.018";
   
   The time limit must be defined in <chess> before running the test.

   Returns -1 on error
            0 for unsolved test
            1 for solved test
            2 for cancelled test  */
int
test_pos(Chess *chess, const char *pos)
{
	char tmp_pos[MAX_BUF];
	char *pos_item = NULL;
	char *svptr = NULL;
	U32 move;
	bool find_best;

	strlcpy(tmp_pos, pos, MAX_BUF);
	
	/* See if we're looking for the best move or avoiding a move.
	   By doing that we'll also get to the end of the FEN string.  */
	if ((pos_item = strstr(tmp_pos, " bm ")) != NULL)
		find_best = true;
	else if ((pos_item = strstr(tmp_pos, " am ")) != NULL) {
		find_best = false;
		my_error("'Avoid move' positions not currently allowed");
		return -1;
	} else
		return -1;

	*pos_item = 0; /* end of FEN string */
	pos_item += 4; /* best move or move to avoid */
	
	if (fen_to_board(&chess->board, tmp_pos))
		return -1;

	/* Get the move string.  */
	if ((pos_item = strtok_r(pos_item, ";", &svptr)) == NULL)
		return -1;
	/* Some positions have a series of moves (a pv) as the solution. We
	   only care about the first one, so make sure to pick just one.  */
	svptr = strchr(pos_item, ' ');
	if (svptr != NULL)
		*svptr = '\0';
	
	move = san_to_move(&chess->board, pos_item);
	if (move == NULLMOVE) {
		printf("Illegal test solution: %s\n", pos_item);
		return -1;
	}
	id_search(chess, move);
	if (chess->sd.cmd_type != CMDT_CONTINUE)
		return 2;
	if (chess->sd.move == move)
		return 1;

	return 0;
}
Esempio n. 5
0
PUBLIC int lex_id(int sym)
{
	register int i;

	strupr(yytext);

	for (i = 0; lexemetab[i].sym; i++)
		if (strcmp(yytext, lexemetab[i].txt) == 0) {
			yylval.inum = lexemetab[i].func;
			return lexemetab[i].sym;
		}

	yylval.id = id_search(yytext);

	return sym;
}
Esempio n. 6
0
/* Analyze mode for any supported chess protocol.  */
void
analyze_mode(Chess *chess)
{
	CmdType *cmd_type;

	ASSERT(1, chess != NULL);
	
	cmd_type = &chess->sd.cmd_type;
	chess->cpu_color = COLOR_NONE;
	*cmd_type = CMDT_CONTINUE;
	while (chess->analyze) {
		if (!chess->game_over && *cmd_type != CMDT_CANCEL) {
			id_search(chess, NULLMOVE);
			/* If the maximum search depth is reached, there's no
			   reason to search again until something changes. */
			if (*cmd_type == CMDT_CONTINUE)
				*cmd_type = CMDT_CANCEL;
		} else {
			read_input(chess);
			*cmd_type = CMDT_CONTINUE;
		}
	}
}