// File: jswaff[P]prophet3/src/perft.cpp
// Function: perft_test_slow(int)
void perft_test_slow(int32 depth) {
    print("perft_test_slow, depth=%d\n",depth);
    if (depth < 1 || depth > 6) {
        error("valid perft_test_slow depths are 1-6.\n");
        return;
    }

    static const char filename[] = "../data/perft-random.epd";
    FILE *file = fopen (filename,"r");
    if (file == NULL) {
        perror (filename); // why didn't the file open?
        return;
    }

    char id_line[255],epd_line[255],node_count_line[6][255];

    position pos;
    uint64 total_nps = 0;
    int32 num_probs = 0;
    while (get_line(id_line,"id ",file) && get_line(epd_line,"epd ",file)
        && get_line(node_count_line[0],"perft 1",file) && get_line(node_count_line[1],"perft 2",file)
        && get_line(node_count_line[2],"perft 3",file) && get_line(node_count_line[3],"perft 4",file)
        && get_line(node_count_line[4],"perft 5",file) && get_line(node_count_line[5],"perft 6",file)
        && num_probs < 100)
    {
        print("======================================================================\n");
        print("%s\n",id_line+3);
        print("%s\n",epd_line+4);
        print("======================================================================\n");

        // remove newline from epd
        char *p=strchr(epd_line,'\n');
        if (p != NULL) *p = '\0';

        set_pos(&pos,epd_line+4);
        draw_board(&pos);
        uint64 expected = strtoull(node_count_line[depth-1]+8,NULL,10);

        int32 start_time = milli_timer();
        uint64 actual = perft(&pos,depth);
        int32 elapsed = milli_timer() - start_time + 1; // div by 0

        print("\nexpected (%d): %llu, actual: %llu\n",depth,expected,actual);
        if (actual != expected) {
            exit(1);
        }

        uint64 nps = actual * 1000 / elapsed;
        total_nps += nps;
        print("nps: %lu\n\n",nps);

        num_probs++;
    }
    fclose (file);

    print("average NPS: %lu\n",total_nps / num_probs);
    print("... perft_test_slow complete!\n");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa20, %rsp            # imm = 0xA20
movl %edi, -0x4(%rbp)
movl -0x4(%rbp), %esi
leaq 0x29507(%rip), %rdi     # 0x36faf
movb $0x0, %al
callq 0x8c60
cmpl $0x1, -0x4(%rbp)
jl 0xdabb
cmpl $0x6, -0x4(%rbp)
jle 0xdace
leaq 0x29508(%rip), %rdi     # 0x36fca
movb $0x0, %al
callq 0x8f00
jmp 0xde77
leaq 0x29b6b(%rip), %rdi     # 0x37640
leaq 0x36fa2(%rip), %rsi     # 0x44a7e
callq 0x21d0
movq %rax, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xdafd
leaq 0x29b4d(%rip), %rdi     # 0x37640
callq 0x2100
jmp 0xde77
movq $0x0, -0x9e0(%rbp)
movl $0x0, -0x9e4(%rbp)
leaq -0x110(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x294cd(%rip), %rsi     # 0x36ff1
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdb3d
jmp 0xdc94
leaq -0x210(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x294a6(%rip), %rsi     # 0x36ff5
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdb68
jmp 0xdc94
leaq -0x810(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x29480(%rip), %rsi     # 0x36ffa
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdb93
jmp 0xdc94
leaq -0x810(%rbp), %rdi
addq $0xff, %rdi
movq -0x10(%rbp), %rdx
leaq 0x29456(%rip), %rsi     # 0x37002
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdbc5
jmp 0xdc94
leaq -0x810(%rbp), %rdi
addq $0x1fe, %rdi            # imm = 0x1FE
movq -0x10(%rbp), %rdx
leaq 0x2942c(%rip), %rsi     # 0x3700a
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdbf7
jmp 0xdc94
leaq -0x810(%rbp), %rdi
addq $0x2fd, %rdi            # imm = 0x2FD
movq -0x10(%rbp), %rdx
leaq 0x29402(%rip), %rsi     # 0x37012
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdc26
jmp 0xdc94
leaq -0x810(%rbp), %rdi
addq $0x3fc, %rdi            # imm = 0x3FC
movq -0x10(%rbp), %rdx
leaq 0x293db(%rip), %rsi     # 0x3701a
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdc55
jmp 0xdc94
leaq -0x810(%rbp), %rdi
addq $0x4fb, %rdi            # imm = 0x4FB
movq -0x10(%rbp), %rdx
leaq 0x293b4(%rip), %rsi     # 0x37022
callq 0xda30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xa19(%rbp)
jne 0xdc84
jmp 0xdc94
cmpl $0x64, -0x9e4(%rbp)
setl %al
movb %al, -0xa19(%rbp)
movb -0xa19(%rbp), %al
testb $0x1, %al
jne 0xdca3
jmp 0xde3c
leaq 0x29380(%rip), %rdi     # 0x3702a
movb $0x0, %al
callq 0x8c60
leaq -0x110(%rbp), %rsi
addq $0x3, %rsi
leaq 0x2b624(%rip), %rdi     # 0x392e7
movb $0x0, %al
callq 0x8c60
leaq -0x210(%rbp), %rsi
addq $0x4, %rsi
leaq 0x2b60b(%rip), %rdi     # 0x392e7
movb $0x0, %al
callq 0x8c60
leaq 0x29340(%rip), %rdi     # 0x3702a
movb $0x0, %al
callq 0x8c60
leaq -0x210(%rbp), %rdi
movl $0xa, %esi
callq 0x2070
movq %rax, -0x9f0(%rbp)
cmpq $0x0, -0x9f0(%rbp)
je 0xdd1d
movq -0x9f0(%rbp), %rax
movb $0x0, (%rax)
leaq -0x210(%rbp), %rsi
addq $0x4, %rsi
leaq -0x9d8(%rbp), %rdi
callq 0xf3e0
leaq -0x9d8(%rbp), %rdi
callq 0x64e0
movl -0x4(%rbp), %eax
subl $0x1, %eax
cltq
leaq -0x810(%rbp), %rdi
imulq $0xff, %rax, %rax
addq %rax, %rdi
addq $0x8, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x2240
movq %rax, -0x9f8(%rbp)
callq 0x14080
movl %eax, -0x9fc(%rbp)
movl -0x4(%rbp), %esi
leaq -0x9d8(%rbp), %rdi
callq 0xd8a0
movq %rax, -0xa08(%rbp)
callq 0x14080
subl -0x9fc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0c(%rbp)
movl -0x4(%rbp), %esi
movq -0x9f8(%rbp), %rdx
movq -0xa08(%rbp), %rcx
leaq 0x292b3(%rip), %rdi     # 0x37072
movb $0x0, %al
callq 0x8c60
movq -0xa08(%rbp), %rax
cmpq -0x9f8(%rbp), %rax
je 0xdde0
movl $0x1, %edi
callq 0x21f0
imulq $0x3e8, -0xa08(%rbp), %rax # imm = 0x3E8
movslq -0xa0c(%rbp), %rcx
xorl %edx, %edx
divq %rcx
movq %rax, -0xa18(%rbp)
movq -0xa18(%rbp), %rax
addq -0x9e0(%rbp), %rax
movq %rax, -0x9e0(%rbp)
movq -0xa18(%rbp), %rsi
leaq 0x297ee(%rip), %rdi     # 0x3760f
movb $0x0, %al
callq 0x8c60
movl -0x9e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9e4(%rbp)
jmp 0xdb12
movq -0x10(%rbp), %rdi
callq 0x2170
movq -0x9e0(%rbp), %rax
movslq -0x9e4(%rbp), %rcx
xorl %edx, %edx
divq %rcx
movq %rax, %rsi
leaq 0x29234(%rip), %rdi     # 0x37096
movb $0x0, %al
callq 0x8c60
leaq 0x29238(%rip), %rdi     # 0x370a8
movb $0x0, %al
callq 0x8c60
addq $0xa20, %rsp            # imm = 0xA20
popq %rbp
retq