예제 #1
0
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;
}
예제 #2
0
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;

}
예제 #3
0
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;
}
예제 #4
0
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;

}
예제 #5
0
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;

}
예제 #6
0
파일: go.c 프로젝트: imaami/darknet
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;
    }

}
예제 #7
0
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;
    }
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;

}
예제 #11
0
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;
}