// File: /workspace/github_cpp_makefile_star2_O3/jswaff[P]prophet3/test/hash__test.cpp
// Function: test_hash_keys2()
void test_hash_keys2() {
    position pos;
    reset_pos(&pos);

    position pos2;
    reset_pos(&pos2);

    uint64 keys[20]; int nkeys=0;
    uint64 keys2[20]; int nkeys2=0;

    assert(build_hash_key(&pos)==build_hash_key(&pos2));

    // step through French Defense with pos1
    apply_move(&pos,to_move(PAWN,E2,E4),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_move(PAWN,E7,E6),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_move(PAWN,D2,D4),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_move(PAWN,D7,D5),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_capture(PAWN,E4,D5,PAWN),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_capture(PAWN,E6,D5,PAWN),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_move(KNIGHT,G1,F3),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_move(KNIGHT,G8,F6),gundos);
    keys[nkeys++] = build_hash_key(&pos);

    // step through the Petrov Defense with pos2
    apply_move(&pos2,to_move(PAWN,E2,E4),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,E7,E5),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(KNIGHT,G1,F3),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(KNIGHT,G8,F6),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_capture(KNIGHT,F3,E5,PAWN),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,D7,D6),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(KNIGHT,E5,F3),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_capture(KNIGHT,F6,E4,PAWN),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,D2,D3),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(KNIGHT,E4,F6),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,D3,D4),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,D6,D5),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);

    // Positions would be equal at this point, except for move history and fifty counter
    assert(!equal_pos(&pos,&pos2,true));
    assert(build_hash_key(&pos)==build_hash_key(&pos2));

    // by adding a pawn move we should be equal except move history and number of moves
    apply_move(&pos,to_move(PAWN,G2,G3),gundos);
    apply_move(&pos2,to_move(PAWN,G2,G3),gundos);

    assert(!equal_pos(&pos,&pos2,true));
    assert(build_hash_key(&pos)==build_hash_key(&pos2));

    // hash codes should be equal at beginning, move 1, move 7 and end only.
    for (int i=0;i<nkeys;i++) {
        if (i==0) {
            assert(keys2[i]==keys[i]);
            assert(!contains_key(keys[i],keys2,nkeys2,1));
        } else if (i==7) {
            assert(keys2[11]==keys[i]);
            assert(!contains_key(keys[i],keys2,nkeys2-1,0));
        } else {
            assert(!contains_key(keys[i],keys2,nkeys2));
        }
    }

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4e8, %rsp            # imm = 0x4E8
leaq 0x158(%rsp), %rbx
movq %rbx, %rdi
callq 0xaa51
leaq 0x320(%rsp), %r14
movq %r14, %rdi
callq 0xaa51
movq %rbx, %rdi
callq 0x5ee8
movq %rax, %rbx
movq %r14, %rdi
callq 0x5ee8
cmpq %rax, %rbx
jne 0x168ef
movl $0x1, %edi
movl $0x34, %esi
movl $0x24, %edx
callq 0x775c
leaq 0xb281b(%rip), %r13     # 0xc8af0
leaq 0x158(%rsp), %rbp
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, %rbx
movq %rax, 0xb0(%rsp)
movl $0x1, %edi
movl $0xc, %esi
movl $0x14, %edx
callq 0x775c
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, 0xb8(%rsp)
movl $0x1, %edi
movl $0x33, %esi
movl $0x23, %edx
callq 0x775c
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, 0xc0(%rsp)
movl $0x1, %edi
movl $0xb, %esi
movl $0x1b, %edx
callq 0x775c
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, 0xc8(%rsp)
movl $0x1, %edi
movl $0x24, %esi
movl $0x1b, %edx
movl $0x1, %ecx
callq 0x777b
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, 0xd0(%rsp)
movl $0x1, %edi
movl $0x14, %esi
movl $0x1b, %edx
movl $0x1, %ecx
callq 0x777b
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, 0xd8(%rsp)
movl $0x2, %edi
movl $0x3e, %esi
movl $0x2d, %edx
callq 0x775c
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, 0xe0(%rsp)
movl $0x2, %edi
movl $0x6, %esi
movl $0x15, %edx
callq 0x775c
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %rbp, %rdi
callq 0x5ee8
movq %rax, %r14
movq %rax, 0xe8(%rsp)
movl $0x1, %edi
movl $0x34, %esi
movl $0x24, %edx
callq 0x775c
leaq 0x320(%rsp), %r12
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, %r15
movq %rax, 0x10(%rsp)
movl $0x1, %edi
movl $0xc, %esi
movl $0x1c, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x8(%rsp)
movq %rax, 0x18(%rsp)
movl $0x2, %edi
movl $0x3e, %esi
movl $0x2d, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x20(%rsp)
movl $0x2, %edi
movl $0x6, %esi
movl $0x15, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x28(%rsp)
movl $0x2, %edi
movl $0x2d, %esi
movl $0x1c, %edx
movl $0x1, %ecx
callq 0x777b
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x30(%rsp)
movl $0x1, %edi
movl $0xb, %esi
movl $0x13, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x38(%rsp)
movl $0x2, %edi
movl $0x1c, %esi
movl $0x2d, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x40(%rsp)
movl $0x2, %edi
movl $0x15, %esi
movl $0x24, %edx
movl $0x1, %ecx
callq 0x777b
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x48(%rsp)
movl $0x1, %edi
movl $0x33, %esi
movl $0x2b, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x50(%rsp)
movl $0x2, %edi
movl $0x24, %esi
movl $0x15, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x58(%rsp)
movl $0x1, %edi
movl $0x2b, %esi
movl $0x23, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, 0x60(%rsp)
movl $0x1, %edi
movl $0x13, %esi
movl $0x1b, %edx
callq 0x775c
movq %r12, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x30e1
movq %r12, %rdi
callq 0x5ee8
movq %rax, %r13
movq %rax, 0x68(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0xa0b8
testb %al, %al
jne 0x1690e
leaq 0x158(%rsp), %rdi
callq 0x5ee8
movq %rax, %r12
leaq 0x320(%rsp), %rdi
callq 0x5ee8
cmpq %rax, %r12
jne 0x1692d
movl $0x1, %edi
movl $0x36, %esi
movl $0x2e, %edx
callq 0x775c
leaq 0xb23dd(%rip), %r12     # 0xc8af0
leaq 0x158(%rsp), %rdi
movq %rax, %rsi
movq %r12, %rdx
callq 0x30e1
movl $0x1, %edi
movl $0x36, %esi
movl $0x2e, %edx
callq 0x775c
leaq 0x320(%rsp), %rbp
movq %rbp, %rdi
movq %rax, %rsi
movq %r12, %rdx
callq 0x30e1
leaq 0x158(%rsp), %rdi
movq %rbp, %rsi
movl $0x1, %edx
callq 0xa0b8
testb %al, %al
jne 0x1694c
leaq 0x158(%rsp), %rdi
callq 0x5ee8
movq %rax, %r12
leaq 0x320(%rsp), %rdi
callq 0x5ee8
cmpq %rax, %r12
jne 0x1696b
xorl %eax, %eax
movq 0x8(%rsp), %rdi
cmpl $0x7, %eax
je 0x167d6
testl %eax, %eax
jne 0x16807
cmpq %rbx, %r15
jne 0x168b1
cmpq %rbx, %rdi
je 0x16873
xorl %ecx, %ecx
cmpq $0xa, %rcx
je 0x16835
leaq 0x1(%rcx), %rdx
cmpq %rbx, 0x20(%rsp,%rcx,8)
movq %rdx, %rcx
jne 0x167b7
cmpq $0xa, %rdx
ja 0x16835
jmp 0x16873
cmpq %r14, %r13
jne 0x168d0
cmpq %r14, %r15
je 0x16854
movq $-0x1, %rcx
cmpq $0x9, %rcx
je 0x16835
leaq 0x1(%rcx), %rdx
cmpq %r14, 0x20(%rsp,%rcx,8)
movq %rdx, %rcx
jne 0x167eb
cmpq $0x9, %rdx
ja 0x16835
jmp 0x16854
movq 0xb0(%rsp,%rax,8), %rcx
cmpq %rcx, %r15
je 0x16892
movq $-0x1, %rdx
cmpq $0xa, %rdx
je 0x16835
leaq 0x1(%rdx), %rsi
cmpq %rcx, 0x20(%rsp,%rdx,8)
movq %rsi, %rdx
jne 0x1681b
cmpq $0xa, %rsi
jbe 0x16892
incq %rax
cmpq $0x8, %rax
jne 0x1679a
addq $0x4e8, %rsp            # imm = 0x4E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1b43d(%rip), %rdi     # 0x31c98
leaq 0x1b343(%rip), %rsi     # 0x31ba5
leaq 0x1b3b1(%rip), %rcx     # 0x31c1a
movl $0xe3, %edx
callq 0x20d0
leaq 0x1b3e5(%rip), %rdi     # 0x31c5f
leaq 0x1b324(%rip), %rsi     # 0x31ba5
leaq 0x1b392(%rip), %rcx     # 0x31c1a
movl $0xe0, %edx
callq 0x20d0
leaq 0x1b427(%rip), %rdi     # 0x31cc0
leaq 0x1b305(%rip), %rsi     # 0x31ba5
leaq 0x1b373(%rip), %rcx     # 0x31c1a
movl $0xe5, %edx
callq 0x20d0
leaq 0x1b395(%rip), %rdi     # 0x31c4d
leaq 0x1b2e6(%rip), %rsi     # 0x31ba5
leaq 0x1b354(%rip), %rcx     # 0x31c1a
movl $0xdf, %edx
callq 0x20d0
leaq 0x1b3ae(%rip), %rdi     # 0x31c85
leaq 0x1b2c7(%rip), %rsi     # 0x31ba5
leaq 0x1b335(%rip), %rcx     # 0x31c1a
movl $0xe2, %edx
callq 0x20d0
leaq 0x1b2f8(%rip), %rdi     # 0x31bee
leaq 0x1b2a8(%rip), %rsi     # 0x31ba5
leaq 0x1b316(%rip), %rcx     # 0x31c1a
movl $0xa3, %edx
callq 0x20d0
leaq 0x1b31c(%rip), %rdi     # 0x31c31
leaq 0x1b289(%rip), %rsi     # 0x31ba5
leaq 0x1b2f7(%rip), %rcx     # 0x31c1a
movl $0xd2, %edx
callq 0x20d0
leaq 0x1b2ba(%rip), %rdi     # 0x31bee
leaq 0x1b26a(%rip), %rsi     # 0x31ba5
leaq 0x1b2d8(%rip), %rcx     # 0x31c1a
movl $0xd3, %edx
callq 0x20d0
leaq 0x1b2de(%rip), %rdi     # 0x31c31
leaq 0x1b24b(%rip), %rsi     # 0x31ba5
leaq 0x1b2b9(%rip), %rcx     # 0x31c1a
movl $0xd9, %edx
callq 0x20d0
leaq 0x1b27c(%rip), %rdi     # 0x31bee
leaq 0x1b22c(%rip), %rsi     # 0x31ba5
leaq 0x1b29a(%rip), %rcx     # 0x31c1a
movl $0xda, %edx
callq 0x20d0