Ejemplo n.º 1
0
int test_move(char *fen, int side, char *move, int move_correct)
{
	IS_CHECKMATE = IS_DRAW = 0;
	B b = fen_to_board(fen);
	print_board(b);
	printf("\n");
	Move m = find_move(b, side, 180);
	if(m == atomove(move, b) && move_correct) {
		printf("CORRECT\n\n");
		goto SUCESS;
	} else if(m != atomove(move, b) && !move_correct) {
		printf("CORRECT\n\n");
		print_move(m);
		printf("\n%s\n", movetoa(m));
		goto SUCESS;
	} else goto FAILURE;
	SUCESS:
		printf("\n\n#############################\n");
		free(b);
		return 1;
	FAILURE:
		printf("FAILURE: ");
		print_move(m);
		printf("\n%s\n", movetoa(m));
		printf("\n\n#############################\n");
        free(b);
        return 0;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/* Starts a new game in position <fen>.  */
void
new_game(Chess *chess, const char *fen, int new_cpu_color)
{
	ASSERT(1, chess != NULL);
	ASSERT(1, fen != NULL);

	if (fen_to_board(&chess->board, fen)) {
		printf("Invalid FEN string: %s\n", fen);
		return;
	}
	chess->game_over = false;
	chess->in_book = false;
	chess->cpu_color = new_cpu_color;

	/* Delete the (possibly) existing GAME_LOG file.  */
	if (remove(GAME_LOG) && errno != ENOENT)
		my_perror("Can't delete file %s", GAME_LOG);
}
Ejemplo n.º 5
0
int checkmate_puzzle(char *fen)
{
	B b = fen_to_board(fen);
  printf("\n");
  printf("-----------------");
	print_board(b);
  Move m = find_move(b, b->side_to_move, 60);
	if(IS_CHECKMATE) {
    printf("\nSUCESS: %s", movetoa(m));
    return 1;
  } else if(CHECKSTALEMATE_IN_X) {
    printf("SUCESS IN %d MOVES: %s\n", CHECKSTALEMATE_IN_X, movetoa(m));
    CHECKSTALEMATE_IN_X = 0;
    return 1;
  } else {
    printf("\nFAILURE: %s", movetoa(m));
    return 0;
  }
}
Ejemplo n.º 6
0
/* Read a PGN file (a collection of one or more games in PGN format) and store
   the positions and their win/loss ratios in an AVL tree (**tree).
   The AVL tree can later be written in an opening book file (book.bin).
   
   Returns the number of new positions added to the tree, or -1 on error.  */
int
pgn_to_tree(const char *filename, AvlNode **tree)
{
	PgnResult result;
	int prev_progress;
	int npos = 0;
	long file_len;
	FILE *fp;
	Board board;

	ASSERT(1, filename != NULL);

	if ((fp = fopen(filename, "r")) == NULL) {
		my_perror("Can't open PGN file %s", filename);
		return -1;
	}

	if (settings.book_type != BOOK_MEM) {
		settings.book_type = BOOK_MEM;
		printf("Changed book mode to \"book in memory\"\n");
	}
	if (*tree == NULL && file_exists(settings.book_file)) {
		printf("Loading opening book to memory...\n");
		book_to_tree(settings.book_file, tree);
	} else if (*tree == NULL)
		printf("Creating a new opening book...\n");

	/* Find out how big the file is.  */
	fseek(fp, 0, SEEK_END);
	file_len = ftell(fp);
	rewind(fp);

	printf("Reading PGN file %s...\n", filename);
	prev_progress = 0;
	progressbar(50, 0);
	while ((result = get_pgn_result(fp)) != RESULT_ERROR) {
		int depth;
		int progress;
		int len;
		char san_move[MAX_BUF];

		/* Games with an unknown result are ignored.  */
		ASSERT(1, result != RESULT_ERROR);
		if (result == NO_RESULT || result == DRAWN_GAME)
			continue;

		depth = 0;
		fen_to_board(&board, START_FEN);

		while ((len = read_move(san_move, MAX_BUF, fp)) >= 0) {
			int points = 0;
			U32 move;

			/* break out of the loop when a new game begins */
			if (depth > 0 && san_move[0] == '[')
				break;
			if (len < 2)
				continue;

			move = san_to_move(&board, san_move);
			if (move == NULLMOVE) {
				#if DEBUG_LEVEL > 0
				update_log("Illegal move in %s: %s, line: %d\n",
				          filename, san_move, get_line_num(fp));
				#endif /* DEBUG_LEVEL > 0 */
				break;
			}

			if ((result == WHITE_WINS && board.color == WHITE)
			||  (result == BLACK_WINS && board.color == BLACK))
				points = 2;

			make_move(&board, move);
			if (save_book_pos(board.posp->key, points, tree))
				npos++;

			if (++depth >= MAX_BOOK_PLIES)
				break;
		}
		progress = (ftell(fp) * 50) / file_len;
		if (progress > prev_progress) {
			progressbar(50, progress);
			prev_progress = progress;
		}
	}
	progressbar(50, 50);
	my_close(fp, filename);
	printf("\n");

	return npos;
}