// File: bjohnsonfl[P]Overhead-Chess-Engine-/bitboard.cpp
// Function: initMagicBishop()
void initMagicBishop ()
{
    bitboard blockers[4096], attackers[4096], b, magic;
    bitboard used[4096];
    int size = 0;
    bitboard * idx;
    for ( square sq = a1; sq < numOfSq; sq++)
    {
        magicBishopIndex[sq] = sq == a1 ? magicBishopAttacks : magicBishopIndex[sq - 1] + (size );
        b = 0;
        size = 0;
        do {
            
            blockers[size] = b;
            attackers[size] = squareBitMask[sq]^(diagMasks(sq, b) | antidiagMasks(sq, b));
            size++;
            b = (b - magicBishopMask[sq]) & magicBishopMask[sq];
        } while(b);
        
        int n = bishopShifts [sq];
        int fail = 0;
        unsigned index = 0;
        
        for(int k = 0; k < 1000000000; k++) {
            
            magic = randomU64_fewbits();
            if(popcount((magicBishopMask[sq] * magic) & 0xFF00000000000000ULL) < 6) continue;
           // std::cout<< "k: " << k <<" sq: "<<sq << "\n";
            for(int i = 0; i < 4096; i++) used[i] = 0;
            fail = 0;
            for(int i = 0; !fail && i < size; i++) {
                index = magicIndex(blockers[i], magic, n);
                if(used[index] == 0){
                    used[index] = attackers[i];
                }
                else if(used[index] != attackers[i]){
                    fail = 1;
                }
            }
            if(!fail) {
               // return magic;
              //  std::cout<< "magic: " << magic << " sq: " << sq  << "\n";
              idx = magicBishopIndex[sq];
                for(int i = 0; i < size; i++) {
                    idx[i] = used[i];
                }
                magicBishopNumbers[sq] = magic;
                /*////////////////
                //TEST
               b = 0;
                do {
                    
                   // printBitboard(b);
                  //  printBitboard( *(magicBishopIndex[sq] + magicIndex(b, magic, bishopShifts[sq])));
                   // printBitboard(squareBitMask[sq]^(diagMasks(sq, b) | antidiagMasks(sq, b)));
                    if(( *(magicBishopIndex[sq] + magicIndex(b, magic, bishopShifts[sq]))) != (squareBitMask[sq]^(diagMasks(sq, b) | antidiagMasks(sq, b)))) std::cout << "MAGIC DOESNT WORK \n";
               
                    b = (b - magicBishopMask[sq]) & magicBishopMask[sq];
                } while(b);
                ///////////////////
                //////////////////
                 */
                break;
            }
            }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x18060, %rsp          # imm = 0x18060
movl $0x0, -0x18014(%rbp)
movl $0x0, -0x18024(%rbp)
cmpl $0x40, -0x18024(%rbp)
jge 0x4fbe
cmpl $0x0, -0x18024(%rbp)
jne 0x4c35
leaq 0xe8574(%rip), %rax     # 0xed1a0
movq %rax, -0x18048(%rbp)
jmp 0x4c61
movl -0x18024(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rcx
leaq 0xe8358(%rip), %rax     # 0xecfa0
movq (%rax,%rcx,8), %rax
movslq -0x18014(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x18048(%rbp)
movq -0x18048(%rbp), %rdx
movl -0x18024(%rbp), %eax
movl %eax, %ecx
leaq 0xe8329(%rip), %rax     # 0xecfa0
movq %rdx, (%rax,%rcx,8)
movq $0x0, -0x10008(%rbp)
movl $0x0, -0x18014(%rbp)
movq -0x10008(%rbp), %rcx
movslq -0x18014(%rbp), %rax
movq %rcx, -0x8000(%rbp,%rax,8)
movl -0x18024(%rbp), %eax
movl %eax, %ecx
leaq 0xe1eb(%rip), %rax      # 0x12ea0
movq (%rax,%rcx,8), %rax
movq %rax, -0x18058(%rbp)
movl -0x18024(%rbp), %edi
movq -0x10008(%rbp), %rsi
callq 0x4160
movq %rax, -0x18050(%rbp)
movl -0x18024(%rbp), %edi
movq -0x10008(%rbp), %rsi
callq 0x4280
movq -0x18058(%rbp), %rcx
movq %rax, %rdx
movq -0x18050(%rbp), %rax
orq %rdx, %rax
xorq %rax, %rcx
movslq -0x18014(%rbp), %rax
movq %rcx, -0x10000(%rbp,%rax,8)
movl -0x18014(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18014(%rbp)
movq -0x10008(%rbp), %rax
movl -0x18024(%rbp), %ecx
movl %ecx, %edx
leaq 0xe7e6a(%rip), %rcx     # 0xecba0
subq (%rcx,%rdx,8), %rax
movl -0x18024(%rbp), %ecx
movl %ecx, %edx
leaq 0xe7e57(%rip), %rcx     # 0xecba0
andq (%rcx,%rdx,8), %rax
movq %rax, -0x10008(%rbp)
cmpq $0x0, -0x10008(%rbp)
jne 0x4c90
movl -0x18024(%rbp), %eax
movl %eax, %ecx
leaq 0x93ef(%rip), %rax      # 0xe160
movl (%rax,%rcx,4), %eax
movl %eax, -0x18028(%rbp)
movl $0x0, -0x1802c(%rbp)
movl $0x0, -0x18030(%rbp)
movl $0x0, -0x18034(%rbp)
cmpl $0x3b9aca00, -0x18034(%rbp) # imm = 0x3B9ACA00
jge 0x4fa9
callq 0x3f60
movq %rax, -0x10010(%rbp)
movl -0x18024(%rbp), %eax
movl %eax, %ecx
leaq 0xe7ddd(%rip), %rax     # 0xecba0
movq (%rax,%rcx,8), %rdi
imulq -0x10010(%rbp), %rdi
movabsq $-0x100000000000000, %rax # imm = 0xFF00000000000000
andq %rax, %rdi
callq 0x3fa0
cmpl $0x6, %eax
jge 0x4deb
jmp 0x4f95
movl $0x0, -0x18038(%rbp)
cmpl $0x1000, -0x18038(%rbp) # imm = 0x1000
jge 0x4e25
movslq -0x18038(%rbp), %rax
movq $0x0, -0x18010(%rbp,%rax,8)
movl -0x18038(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18038(%rbp)
jmp 0x4df5
movl $0x0, -0x1802c(%rbp)
movl $0x0, -0x1803c(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x1802c(%rbp)
movb %al, -0x18059(%rbp)
jne 0x4e5f
movl -0x1803c(%rbp), %eax
cmpl -0x18014(%rbp), %eax
setl %al
movb %al, -0x18059(%rbp)
movb -0x18059(%rbp), %al
testb $0x1, %al
jne 0x4e6e
jmp 0x4f06
movslq -0x1803c(%rbp), %rax
movq -0x8000(%rbp,%rax,8), %rdi
movq -0x10010(%rbp), %rsi
movl -0x18028(%rbp), %edx
callq 0x58c0
movl %eax, -0x18030(%rbp)
movl -0x18030(%rbp), %eax
cmpq $0x0, -0x18010(%rbp,%rax,8)
jne 0x4ec5
movslq -0x1803c(%rbp), %rax
movq -0x10000(%rbp,%rax,8), %rcx
movl -0x18030(%rbp), %eax
movq %rcx, -0x18010(%rbp,%rax,8)
jmp 0x4ef0
movl -0x18030(%rbp), %eax
movq -0x18010(%rbp,%rax,8), %rax
movslq -0x1803c(%rbp), %rcx
cmpq -0x10000(%rbp,%rcx,8), %rax
je 0x4eee
movl $0x1, -0x1802c(%rbp)
jmp 0x4ef0
jmp 0x4ef2
movl -0x1803c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1803c(%rbp)
jmp 0x4e39
cmpl $0x0, -0x1802c(%rbp)
jne 0x4f93
movl -0x18024(%rbp), %eax
movl %eax, %ecx
leaq 0xe807e(%rip), %rax     # 0xecfa0
movq (%rax,%rcx,8), %rax
movq %rax, -0x18020(%rbp)
movl $0x0, -0x18040(%rbp)
movl -0x18040(%rbp), %eax
cmpl -0x18014(%rbp), %eax
jge 0x4f77
movslq -0x18040(%rbp), %rax
movq -0x18010(%rbp,%rax,8), %rdx
movq -0x18020(%rbp), %rax
movslq -0x18040(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x18040(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18040(%rbp)
jmp 0x4f37
movq -0x10010(%rbp), %rdx
movl -0x18024(%rbp), %eax
movl %eax, %ecx
leaq 0xe7e13(%rip), %rax     # 0xecda0
movq %rdx, (%rax,%rcx,8)
jmp 0x4fa9
jmp 0x4f95
movl -0x18034(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18034(%rbp)
jmp 0x4d98
jmp 0x4fab
leaq -0x18024(%rbp), %rdi
xorl %esi, %esi
callq 0x5a80
jmp 0x4c0f
addq $0x18060, %rsp          # imm = 0x18060
popq %rbp
retq
nopw (%rax,%rax)