int generate_move(network net, int player, float *board, int multi, float thresh, float temp, char *ko, int print) { int i, j; for(i = 0; i < net.n; ++i) net.layers[i].temperature = temp; float move[361]; if (player < 0) flip_board(board); predict_move(net, board, move, multi); if (player < 0) flip_board(board); for(i = 0; i < 19; ++i){ for(j = 0; j < 19; ++j){ if (!legal_go(board, ko, player, i, j)) move[i*19 + j] = 0; } } int indexes[nind]; top_k(move, 19*19, nind, indexes); if(thresh > move[indexes[0]]) thresh = move[indexes[nind-1]]; for(i = 0; i < 19; ++i){ for(j = 0; j < 19; ++j){ if (move[i*19 + j] < thresh) move[i*19 + j] = 0; } } int max = max_index(move, 19*19); int row = max / 19; int col = max % 19; int index = sample_array(move, 19*19); if(print){ top_k(move, 19*19, nind, indexes); for(i = 0; i < nind; ++i){ if (!move[indexes[i]]) indexes[i] = -1; } print_board(board, player, indexes); for(i = 0; i < nind; ++i){ fprintf(stderr, "%d: %f\n", i+1, move[indexes[i]]); } } if(suicide_go(board, player, row, col)){ return -1; } if(suicide_go(board, player, index/19, index%19)) index = max; return index; }
BOOL test_alt_move_gen() { BOOL ok = TRUE; struct t_move_list moves[1], xmoves[2]; set_fen(position, "5rN1/4P3/1B6/1B3k2/8/4P3/6PP/2RQK2R w K -"); generate_captures(position, moves); generate_quiet_checks(position, moves); generate_no_capture_no_checks(position, moves); generate_moves(position, xmoves); ok &= (equal_move_lists(xmoves, moves)); flip_board(position); generate_captures(position, moves); generate_quiet_checks(position, moves); generate_no_capture_no_checks(position, moves); generate_moves(position, xmoves); ok &= (equal_move_lists(xmoves, moves)); return ok; }
BOOL test_make_unmake() { BOOL ok = TRUE; int i, j; struct t_move_list moves[1]; struct t_undo undo[1]; set_fen(position, "rnbqkb1r/ppppp1pp/7n/5p2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -"); assert(integrity(position)); for (j = WHITE; j <= BLACK; j++) { generate_moves(position, moves); for (i = 0; i < moves->count; i++) { assert(integrity(position)); if (make_move(position, moves->pinned_pieces, moves->move[i], undo)) { assert(integrity(position)); unmake_move(position, undo); assert(integrity(position)); } } flip_board(position); } ok = integrity(position); set_fen(position, "r3Rbk1/2p2p1p/p2p4/1p1P2q1/8/PBPQ2pP/1P3P1P/3R2K1 b - -"); assert(integrity(position)); for (j = WHITE; j <= BLACK; j++) { generate_moves(position, moves); for (i = 0; i < moves->count; i++) { assert(integrity(position)); if (make_move(position, moves->pinned_pieces, moves->move[i], undo)) { assert(integrity(position)); unmake_move(position, undo); assert(integrity(position)); } } flip_board(position); } ok &= integrity(position); return ok; }
BOOL test_capture_gen() { BOOL ok = TRUE; struct t_move_list moves[1]; set_fen(position, "8/pppr2pp/3pKp2/2Q3bn/8/b6k/PPP1P2P/3R2n1 w - -"); generate_captures(position, moves); ok &= (moves->count == 12); flip_board(position); generate_captures(position, moves); ok &= (moves->count == 12); return ok; }
BOOL test_check_gen() { BOOL ok = TRUE; struct t_move_list moves[1]; set_fen(position, "8/8/2K5/4k1PQ/8/5P2/1N1P4/2R3B1 w - -"); moves->count = 0; generate_quiet_checks(position, moves); ok &= (moves->count == 11); flip_board(position); moves->count = 0; generate_quiet_checks(position, moves); ok &= (moves->count == 11); return ok; }
void test_go(char *filename, char *weightfile, int multi) { network net = parse_network_cfg(filename); if(weightfile){ load_weights(&net, weightfile); } srand(time(0)); set_batch_network(&net, 1); float *board = calloc(19*19, sizeof(float)); float *move = calloc(19*19, sizeof(float)); int color = 1; while(1){ float *output = network_predict(net, board); fltcpy(move, output, 19 * 19); int i; if(multi){ image bim = float_to_image(19, 19, 1, board); for(i = 1; i < 8; ++i){ rotate_image_cw(bim, i); if(i >= 4) flip_image(bim); float *output = network_predict(net, board); image oim = float_to_image(19, 19, 1, output); if(i >= 4) flip_image(oim); rotate_image_cw(oim, -i); fltadd(move, output, 19 * 19); if(i >= 4) flip_image(bim); rotate_image_cw(bim, -i); } scal_cpu(19*19, 1./8., move, 1); } for(i = 0; i < 19*19; ++i){ if(board[i]) move[i] = 0; } int indexes[nind]; int row, col; top_k(move, 19*19, nind, indexes); print_board(board, color, indexes); for(i = 0; i < nind; ++i){ int index = indexes[i]; row = index / 19; col = index % 19; printf("%d: %c %d, %.2f%%\n", i+1, col + 'A' + 1*(col > 7 && noi), (inverted)?19 - row : row+1, move[index]*100); } if(color == 1) printf("\u25EF Enter move: "); else printf("\u25C9 Enter move: "); char c; char *line = fgetl(stdin); int picked = 1; int dnum = sscanf(line, "%d", &picked); int cnum = sscanf(line, "%c", &c); if (strlen(line) == 0 || dnum) { --picked; if (picked < nind){ int index = indexes[picked]; row = index / 19; col = index % 19; board[row*19 + col] = 1; } } else if (cnum){ if (c <= 'T' && c >= 'A'){ int num = sscanf(line, "%c %d", &c, &row); row = (inverted)?19 - row : row-1; col = c - 'A'; if (col > 7 && noi) col -= 1; if (num == 2) board[row*19 + col] = 1; } else if (c == 'p') { // Pass } else if(c=='b' || c == 'w'){ char g; int num = sscanf(line, "%c %c %d", &g, &c, &row); row = (inverted)?19 - row : row-1; col = c - 'A'; if (col > 7 && noi) col -= 1; if (num == 3) board[row*19 + col] = (g == 'b') ? color : -color; } else if(c == 'c'){ char g; int num = sscanf(line, "%c %c %d", &g, &c, &row); row = (inverted)?19 - row : row-1; col = c - 'A'; if (col > 7 && noi) col -= 1; if (num == 3) board[row*19 + col] = 0; } } free(line); update_board(board); flip_board(board); color = -color; } }
void self_go(char *filename, char *weightfile, char *f2, char *w2, int multi) { network net = parse_network_cfg(filename); if(weightfile){ load_weights(&net, weightfile); } network net2 = net; if(f2){ net2 = parse_network_cfg(f2); if(w2){ load_weights(&net2, w2); } } srand(time(0)); char boards[300][93]; int count = 0; set_batch_network(&net, 1); set_batch_network(&net2, 1); float *board = calloc(19*19, sizeof(float)); char *one = calloc(91, sizeof(char)); char *two = calloc(91, sizeof(char)); int done = 0; int player = 1; int p1 = 0; int p2 = 0; int total = 0; while(1){ if (done || count >= 300){ float score = score_game(board); int i = (score > 0)? 0 : 1; if((score > 0) == (total%2==0)) ++p1; else ++p2; ++total; fprintf(stderr, "Total: %d, Player 1: %f, Player 2: %f\n", total, (float)p1/total, (float)p2/total); int j; for(; i < count; i += 2){ for(j = 0; j < 93; ++j){ printf("%c", boards[i][j]); } printf("\n"); } memset(board, 0, 19*19*sizeof(float)); player = 1; done = 0; count = 0; fflush(stdout); fflush(stderr); } //print_board(board, 1, 0); //sleep(1); network use = ((total%2==0) == (player==1)) ? net : net2; int index = generate_move(use, player, board, multi, .1, .7, two, 0); if(index < 0){ done = 1; continue; } int row = index / 19; int col = index % 19; char *swap = two; two = one; one = swap; if(player < 0) flip_board(board); boards[count][0] = row; boards[count][1] = col; board_to_string(boards[count] + 2, board); if(player < 0) flip_board(board); ++count; move_go(board, player, row, col); board_to_string(one, board); player = -player; } }
BOOL test_genmove() { BOOL ok = TRUE; struct t_move_list moves[1]; set_fen(position, "r5r1/n1q1pP1k/3pPppp/P1pP4/2P4N/R1B5/2Q3PP/7K w - -"); assert(integrity(position)); assert(is_square_attacked(position, E4, WHITE)); assert(!is_square_attacked(position, A7, WHITE)); assert(!is_square_attacked(position, F4, BLACK)); assert(is_square_attacked(position, D8, BLACK)); generate_moves(position, moves); ok = ok && (moves->count == 42); flip_board(position); generate_moves(position, moves); //write_move_list(moves, "movelist.txt"); ok = ok && (moves->count == 42); set_fen(position, "1r2k2r/p1ppqpb1/b3pnp1/3PN3/1pn1P3/2N2Q1p/PPPBBPPP/R4K1R w - -"); assert(integrity(position)); generate_moves(position, moves); assert(move_list_integrity(position, moves)); ok = ok && (moves->count == 44); set_fen(position, "4q3/3P1P2/b4N2/8/3Q2Bb/2p3B1/1k4N1/4K1Nr w - -"); assert(integrity(position)); generate_evade_check(position, moves); ok = ok && (moves->count == 18); flip_board(position); generate_evade_check(position, moves); ok = ok && (moves->count == 18); set_fen(position, "1r2k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R4K1R w --k- -"); assert(integrity(position)); generate_moves(position, moves); //write_move_list(moves, "movelist.txt"); assert(move_list_integrity(position, moves)); ok = ok && (moves->count == 46); flip_board(position); generate_moves(position, moves); ok = ok && (moves->count == 46); // Chess960 Examples set_fen(position, "Rr4kr/8/8/8/8/8/PPPP4/R1K5 w Ahb -"); assert(integrity(position)); generate_moves(position, moves); assert(move_list_integrity(position, moves)); ok = ok && (moves->count == 18); flip_board(position); generate_moves(position, moves); ok = ok && (moves->count == 18); set_fen(position, "1r1kbb1r/1pp2ppp/3npn2/3pN3/1Q3P2/4PN2/2PP2PP/qR1KBB1R w HBhb -"); assert(integrity(position)); generate_legal_moves(position, moves); assert(move_list_integrity(position, moves)); ok = ok && (moves->count == 48); set_fen(position, "rkrbqnb1/pp2p2p/3p1pp1/2p1nP2/2P1P3/3P2N1/PP4PP/RKRBQNB1 w CAca -"); assert(integrity(position)); generate_legal_moves(position, moves); write_move_list(moves, "movelist.txt"); assert(move_list_integrity(position, moves)); ok = ok && (moves->count == 34); flip_board(position); generate_legal_moves(position, moves); ok = ok && (moves->count == 34); return ok; }
BOOL test_see() { t_move_record *move; BOOL ok = TRUE; set_fen(position, "2k1K3/7p/6p1/1p2RrR1/8/8/8/8 w - -"); move = lookup_move(position, "e5b5"); ok &= see(position, move, 0); move = lookup_move(position, "g5f5"); ok &= see(position, move, 0); move = lookup_move(position, "g5g6"); ok &= !see(position, move, 0); flip_board(position); move = lookup_move(position, "e4b4"); ok &= see(position, move, 0); move = lookup_move(position, "g4f4"); ok &= see(position, move, 0); move = lookup_move(position, "g4g3"); ok &= !see(position, move, 0); set_fen(position, "k7/4n3/5n2/3p4/8/2N5/6B1/K6Q w - -"); move = lookup_move(position, "c3d5"); ok &= see(position, move, 0); set_fen(position, "k7/4n3/5n2/3p4/8/2N5/6B1/K7 w - -"); move = lookup_move(position, "c3d5"); ok &= !see(position, move, 0); set_fen(position, "3k4/b7/1q6/8/3pK1RR/8/2N5/8 w - -"); move = lookup_move(position, "c2d4"); ok &= !see(position, move, 0); set_fen(position, "3k4/8/1q6/8/3p2R1/7K/2N5/8 w - -"); move = lookup_move(position, "c2d4"); ok &= see(position, move, 0); set_fen(position, "Q7/p2k4/2pq4/3B4/8/8/6PP/n2Kb3 w - -"); move = lookup_move(position, "a8c6"); ok &= !see(position, move, 0); ////-- Test SEE on a square set_fen(position, "4k3/1ppn4/p5rr/1B3p2/2p1p3/1b3P2/PPP1P1BR/3K3R w - -"); ok &= (see_safe(position, H6, 0) == FALSE); ok &= (see_safe(position, E4, 0) == FALSE); ok &= (see_safe(position, A6, 0) == TRUE); ok &= (see_safe(position, C4, 0) == TRUE); ok &= (see_safe(position, B3, 0) == FALSE); ok &= (see_safe(position, F5, 0) == TRUE); set_fen(position, "2k1K3/7p/6p1/1p2RrR1/8/8/8/8 w - -"); ok &= (see_safe(position, F5, 0) == FALSE); ok &= (see_safe(position, G6, 0) == TRUE); ok &= (see_safe(position, B5, 0) == FALSE); set_fen(position, "4k3/1ppn4/p5rr/1B3p2/2p1p3/1b3P2/PPP1P2R/3K3R w - -"); ok &= (see_safe(position, E4, 50) == FALSE); return ok; }
BOOL test_eval() { struct t_chess_eval eval[1]; t_chess_value v; BOOL ok = TRUE; init_eval(eval); set_fen(position, "1k6/8/8/5PP1/3Pp2p/P7/8/4K3 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "1k6/8/8/4b3/8/3B4/K7/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "4r3/pbrq1p1k/1p3Bpp/3p1n2/3PPPQ1/P6R/1P4PP/1B3RK1 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "4r3/pbrq1p1k/1p2pBpp/3p1n2/3PPPQ1/P6R/1P4PP/1B3RK1 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/5p1k/6p1/8/2PK4/p7/P5P1/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/8/7k/2R1Q1n1/1pRp4/8/2B5/5K2 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "3K4/6p1/2P5/3P4/7k/8/1B4B1/5N2 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/6k1/2p5/7K/N7/2N5/PPPP1PPP/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "3b2k1/ppp4p/4P1p1/2n1p2b/2B4B/2PP4/PP2N1PP/4K3 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "5k2/p1pK3p/1p2Q1p1/5Pq1/4P3/8/P5P1/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "4rbk1/pp3ppp/2p5/q1n2P2/2PRn2P/2N2Q2/PP2B1P1/1K5R b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "2kr1b1r/pppbqpp1/2n5/1B1pP2p/P2Pn3/5N2/1PN2PPP/R1BQ1RK1 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "r1bq1b1r/ppp3pp/4k3/3Np3/2B5/P4Q2/1P1P1PPP/n1BK3R b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "r2q1rk1/2pb1p1p/pp1bpPp1/4n1P1/1n2P3/2N1BN1Q/P1P4P/2KR1B1R b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/6pp/6p1/Pp6/1P6/1PK5/4P1k1/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); //-- Pawn Chain set_fen(position, "r7/5pp1/5p1k/2pPp3/1pP4P/pP1B1KPN/P4P2/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/2k5/1pP5/1P6/K7/8/8/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "5k2/8/8/7P/8/7K/8/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "6k1/8/7K/7P/8/8/8/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/6k1/8/3P4/1K6/8/8/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "2k5/2P1K3/1p6/1P6/8/8/8/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "r2r2k1/ppp4p/4p1p1/2B1Nb2/1PN2P2/3P2P1/P1P4P/5K2 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "1NQ5/k1p1p3/7p/pP2P1P1/2P5/2pq4/1n6/6K1 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "r1b1k3/1pq2pp1/p3p3/4p1Q1/3N2p1/1NP3Pr/PPP3Pb/R1BR3K w q -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "7k/6p1/K3p3/2P5/1P3r2/8/2R5/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); //-- B & P Endgame set_fen(position, "8/4k3/8/8/6KP/8/5B2/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/4k3/8/8/6KP/8/4B3/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/2k5/8/8/6KP/8/4B3/8 b - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/2k5/8/8/7P/8/4B3/6K1 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/3k4/8/8/6P1/8/4B3/6K1 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "8/8/8/k7/6P1/8/4B3/6K1 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); set_fen(position, "7k/8/8/7P/4B3/5K2/7P/8 w - -"); v = evaluate(position, eval); flip_board(position); ok &= (v == evaluate(position, eval)); return ok; }
BOOL test_perft() { BOOL ok = TRUE; int i; t_nodes n = 0; if (!uci.engine_initialized) init_engine(position); global_nodes = 0; perft_start_time = time_now(); //--Position 1 for (i = 0; i <= 1; i++) { set_fen(position, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); n = perft(position, 6); ok &= (n == 119060324); global_nodes += n; flip_board(position); } //--Position 2 for (i = 0; i <= 1; i++) { set_fen(position, "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -"); n = perft(position, 5); ok &= (n == 193690690); global_nodes += n; flip_board(position); } //--Position 3 for (i = 0; i <= 1; i++) { set_fen(position, "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - -"); n = perft(position, 7); ok &= (n == 178633661); global_nodes += n; flip_board(position); } //--Position 4 for (i = 0; i <= 1; i++) { set_fen(position, "r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1"); n = perft(position, 6); ok &= (n == 706045033); global_nodes += n; flip_board(position); } perft_end_time = time_now(); //--Position 5 for (i = 0; i <= 1; i++) { set_fen(position, "1k6/1b6/8/8/7R/8/8/4K2R b K - 0 1"); ok &= (perft(position, 5) == 1063513); flip_board(position); } //--Illegal ep move #1 for (i = 0; i <= 1; i++) { set_fen(position, "3k4/3p4/8/K1P4r/8/8/8/8 b - - 0 1"); ok &= (perft(position, 6) == 1134888); flip_board(position); } //--Illegal ep move #2 for (i = 0; i <= 1; i++) { set_fen(position, "8/8/4k3/8/2p5/8/B2P2K1/8 w - - 0 1"); ok &= (perft(position, 6) == 1015133); flip_board(position); } //--EP Capture Checks Opponent for (i = 0; i <= 1; i++) { set_fen(position, "8/8/1k6/2b5/2pP4/8/5K2/8 b - d3 0 1"); ok &= (perft(position, 6) == 1440467); flip_board(position); } //--Short Castling Gives Check for (i = 0; i <= 1; i++) { set_fen(position, "5k2/8/8/8/8/8/8/4K2R w K - 0 1"); ok &= (perft(position, 6) == 661072); flip_board(position); } //--Long Castling Gives Check for (i = 0; i <= 1; i++) { set_fen(position, "3k4/8/8/8/8/8/8/R3K3 w Q - 0 1"); ok &= (perft(position, 6) == 803711); flip_board(position); } //--Castle Rights for (i = 0; i <= 1; i++) { set_fen(position, "r3k2r/1b4bq/8/8/8/8/7B/R3K2R w KQkq - 0 1"); ok &= (perft(position, 4) == 1274206); flip_board(position); } //--Castling Prevented for (i = 0; i <= 1; i++) { set_fen(position, "r3k2r/8/3Q4/8/8/5q2/8/R3K2R b KQkq - 0 1"); ok &= (perft(position, 4) == 1720476); flip_board(position); } //--Promote out of Check for (i = 0; i <= 1; i++) { set_fen(position, "2K2r2/4P3/8/8/8/8/8/3k4 w - - 0 1"); ok &= (perft(position, 6) == 3821001); flip_board(position); } //--Discovered Check for (i = 0; i <= 1; i++) { set_fen(position, "8/8/1P2K3/8/2n5/1q6/8/5k2 b - - 0 1"); ok &= (perft(position, 5) == 1004658); flip_board(position); } //--Promote to give check for (i = 0; i <= 1; i++) { set_fen(position, "4k3/1P6/8/8/8/8/K7/8 w - - 0 1"); ok &= (perft(position, 6) == 217342); flip_board(position); } //--Under Promote to give check for (i = 0; i <= 1; i++) { set_fen(position, "8/P1k5/K7/8/8/8/8/8 w - - 0 1"); ok &= (perft(position, 6) == 92683); flip_board(position); } //--Self Stalemate for (i = 0; i <= 1; i++) { set_fen(position, "K1k5/8/P7/8/8/8/8/8 w - - 0 1"); ok &= (perft(position, 6) == 2217); flip_board(position); } //--Stalemate & Checkmate for (i = 0; i <= 1; i++) { set_fen(position, "8/k1P5/8/1K6/8/8/8/8 w - - 0 1"); ok &= (perft(position, 7) == 567584); flip_board(position); } //--Stalemate & Checkmate for (i = 0; i <= 1; i++) { set_fen(position, "8/8/2k5/5q2/5n2/8/5K2/8 b - - 0 1"); ok &= (perft(position, 4) == 23527); flip_board(position); } if (ok) printf("Everything seems Fine - all PERFT scores are correct\n"); else printf("**ERROR** with PERFT scores\n"); printf(INFO_STRING_PERFT_SPEED, global_nodes, perft_end_time - perft_start_time, 1000 * global_nodes / (perft_end_time - perft_start_time)); return ok; }