// File: jswaff[P]prophet3/test/hash__test.cpp
// Function: test_hash_keys3()
void test_hash_keys3() {
    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));

    // Go through Queen's Gambit with b1
    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_move(PAWN,C2,C4),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(KNIGHT,B1,C3),gundos);
    keys[nkeys++] = build_hash_key(&pos);
    apply_move(&pos,to_move(KNIGHT,G8,F6),gundos);
    keys[nkeys++] = build_hash_key(&pos);

    // Step through English Opening with b2
    apply_move(&pos2,to_move(PAWN,C2,C4),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_move(KNIGHT,B1,C3),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,E7,E6),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,D2,D4),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);
    apply_move(&pos2,to_move(PAWN,D7,D5),gundos);
    keys2[nkeys2++] = build_hash_key(&pos2);

    // Positions would be equal at this point, except for move history, fifty counter and ep square
    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
    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));

    // keys should be equal at beginning and end only.  Neither were
    // saved in list so lists should contain completely different codes
    for (int i=0;i<nkeys;i++) {
        assert(!contains_key(keys[i],keys2,nkeys2));
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x500, %rsp            # imm = 0x500
leaq -0x1c8(%rbp), %rdi
callq 0xf390
leaq -0x390(%rbp), %rdi
callq 0xf390
movl $0x0, -0x434(%rbp)
movl $0x0, -0x4e4(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, -0x4f0(%rbp)
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movq -0x4f0(%rbp), %rax
cmpq %rcx, %rax
jne 0x1f447
jmp 0x1f466
leaq 0x1eef6(%rip), %rdi     # 0x3e344
leaq 0x1eea6(%rip), %rsi     # 0x3e2fb
movl $0xf9, %edx
leaq 0x1efd9(%rip), %rcx     # 0x3e43a
callq 0x20c0
movl $0x1, %edi
movl $0x33, %esi
movl $0x23, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x1c8(%rbp), %rdi
leaq 0xb4825(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x434(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x434(%rbp)
cltq
movq %rcx, -0x430(%rbp,%rax,8)
movl $0x1, %edi
movl $0xb, %esi
movl $0x1b, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x1c8(%rbp), %rdi
leaq 0xb47d1(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x434(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x434(%rbp)
cltq
movq %rcx, -0x430(%rbp,%rax,8)
movl $0x1, %edi
movl $0x32, %esi
movl $0x22, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x1c8(%rbp), %rdi
leaq 0xb477d(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x434(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x434(%rbp)
cltq
movq %rcx, -0x430(%rbp,%rax,8)
movl $0x1, %edi
movl $0xc, %esi
movl $0x14, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x1c8(%rbp), %rdi
leaq 0xb4729(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x434(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x434(%rbp)
cltq
movq %rcx, -0x430(%rbp,%rax,8)
movl $0x2, %edi
movl $0x39, %esi
movl $0x2a, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x1c8(%rbp), %rdi
leaq 0xb46d5(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x434(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x434(%rbp)
cltq
movq %rcx, -0x430(%rbp,%rax,8)
movl $0x2, %edi
movl $0x6, %esi
movl $0x15, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x1c8(%rbp), %rdi
leaq 0xb4681(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x434(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x434(%rbp)
cltq
movq %rcx, -0x430(%rbp,%rax,8)
movl $0x1, %edi
movl $0x32, %esi
movl $0x22, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
leaq 0xb462d(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x4e4(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x4e4(%rbp)
cltq
movq %rcx, -0x4e0(%rbp,%rax,8)
movl $0x2, %edi
movl $0x6, %esi
movl $0x15, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
leaq 0xb45d9(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x4e4(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x4e4(%rbp)
cltq
movq %rcx, -0x4e0(%rbp,%rax,8)
movl $0x2, %edi
movl $0x39, %esi
movl $0x2a, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
leaq 0xb4585(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x4e4(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x4e4(%rbp)
cltq
movq %rcx, -0x4e0(%rbp,%rax,8)
movl $0x1, %edi
movl $0xc, %esi
movl $0x14, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
leaq 0xb4531(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x4e4(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x4e4(%rbp)
cltq
movq %rcx, -0x4e0(%rbp,%rax,8)
movl $0x1, %edi
movl $0x33, %esi
movl $0x23, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
leaq 0xb44dd(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x4e4(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x4e4(%rbp)
cltq
movq %rcx, -0x4e0(%rbp,%rax,8)
movl $0x1, %edi
movl $0xb, %esi
movl $0x1b, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
leaq 0xb4489(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movl -0x4e4(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x4e4(%rbp)
cltq
movq %rcx, -0x4e0(%rbp,%rax,8)
leaq -0x1c8(%rbp), %rdi
leaq -0x390(%rbp), %rsi
movl $0x1, %edx
callq 0xe490
xorb $-0x1, %al
testb $0x1, %al
jne 0x1f876
jmp 0x1f878
jmp 0x1f897
leaq 0x1eb08(%rip), %rdi     # 0x3e387
leaq 0x1ea75(%rip), %rsi     # 0x3e2fb
movl $0x118, %edx            # imm = 0x118
leaq 0x1eba8(%rip), %rcx     # 0x3e43a
callq 0x20c0
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, -0x4f8(%rbp)
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movq -0x4f8(%rbp), %rax
cmpq %rcx, %rax
je 0x1f8c7
jmp 0x1f8e6
leaq 0x1eb83(%rip), %rdi     # 0x3e451
leaq 0x1ea26(%rip), %rsi     # 0x3e2fb
movl $0x119, %edx            # imm = 0x119
leaq 0x1eb59(%rip), %rcx     # 0x3e43a
callq 0x20c0
movl $0x1, %edi
movl $0x36, %esi
movl $0x2e, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x1c8(%rbp), %rdi
leaq 0xb43a5(%rip), %rdx     # 0xd3cb0
callq 0x3620
movl $0x1, %edi
movl $0x36, %esi
movl $0x2e, %edx
callq 0xa830
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
leaq 0xb437b(%rip), %rdx     # 0xd3cb0
callq 0x3620
leaq -0x1c8(%rbp), %rdi
leaq -0x390(%rbp), %rsi
movl $0x1, %edx
callq 0xe490
testb $0x1, %al
jne 0x1f958
jmp 0x1f95a
jmp 0x1f979
leaq 0x1ea27(%rip), %rdi     # 0x3e388
leaq 0x1e993(%rip), %rsi     # 0x3e2fb
movl $0x11e, %edx            # imm = 0x11E
leaq 0x1eac6(%rip), %rcx     # 0x3e43a
callq 0x20c0
leaq -0x1c8(%rbp), %rdi
callq 0x81f0
movq %rax, -0x500(%rbp)
leaq -0x390(%rbp), %rdi
callq 0x81f0
movq %rax, %rcx
movq -0x500(%rbp), %rax
cmpq %rcx, %rax
jne 0x1f9a9
jmp 0x1f9c8
leaq 0x1e994(%rip), %rdi     # 0x3e344
leaq 0x1e944(%rip), %rsi     # 0x3e2fb
movl $0x11f, %edx            # imm = 0x11F
leaq 0x1ea77(%rip), %rcx     # 0x3e43a
callq 0x20c0
movl $0x0, -0x4e8(%rbp)
movl -0x4e8(%rbp), %eax
cmpl -0x434(%rbp), %eax
jge 0x1fa3d
movslq -0x4e8(%rbp), %rax
movq -0x430(%rbp,%rax,8), %rdi
leaq -0x4e0(%rbp), %rsi
movl -0x4e4(%rbp), %edx
callq 0x1d950
xorb $-0x1, %al
testb $0x1, %al
jne 0x1fa09
jmp 0x1fa0b
jmp 0x1fa2a
leaq 0x1ea04(%rip), %rdi     # 0x3e416
leaq 0x1e8e2(%rip), %rsi     # 0x3e2fb
movl $0x124, %edx            # imm = 0x124
leaq 0x1ea15(%rip), %rcx     # 0x3e43a
callq 0x20c0
jmp 0x1fa2c
movl -0x4e8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4e8(%rbp)
jmp 0x1f9d2
addq $0x500, %rsp            # imm = 0x500
popq %rbp
retq
nopw %cs:(%rax,%rax)