// File: SethKasmann[P]clever-girl/src/state.cpp
// Function: operator<<(std::ostream&, State const&)
std::ostream & operator << (std::ostream & o, const State & s)
{
    const char * W_pawn   = "\u2659";
    const char * W_knight = "\u2658";
    const char * W_bishop = "\u2657";
    const char * W_rook   = "\u2656";
    const char * W_queen  = "\u2655";
    const char * W_king   = "\u2654";
    const char * B_pawn   = "\u265F";
    const char * B_knight = "\u265E";
    const char * B_bishop = "\u265D";
    const char * B_rook   = "\u265C";
    const char * B_queen  = "\u265B";
    const char * B_king   = "\u265A";
    const char * Empty    = " ";

    std::string nums[8] = {"1", "2", "3", "4", "5", "6", "7", "8"};
    const std::string bar = " +-+-+-+-+-+-+-+-+";

    o << bar << std::endl;
    for (int i = 63; i >= 0; --i)
    {
        U64 bit = square_bb[i];
        if (i % 8 == 7)
            o << nums[i / 8] << "|";

        o << (bit & s.getPieceBB<pawn>(white)   ? W_pawn
            : bit & s.getPieceBB<knight>(white) ? W_knight
            : bit & s.getPieceBB<bishop>(white) ? W_bishop
            : bit & s.getPieceBB<rook>(white)   ? W_rook
            : bit & s.getPieceBB<queen>(white)  ? W_queen
            : bit & s.getPieceBB<king>(white)   ? W_king
            : bit & s.getPieceBB<pawn>(black)   ? B_pawn
            : bit & s.getPieceBB<knight>(black) ? B_knight
            : bit & s.getPieceBB<bishop>(black) ? B_bishop
            : bit & s.getPieceBB<rook>(black)   ? B_rook
            : bit & s.getPieceBB<queen>(black)  ? B_queen
            : bit & s.getPieceBB<king>(black)   ? B_king
            : Empty) << "|";

        if (i % 8 == 0)
            o << '\n' << bar << '\n';
    }

    o << "  A B C D E F G H\n";

    if (s.mUs == white)
        o << "White to move.\n";
    else 
        o << "Black to move.\n";
    
    //o << "Color(mUs)" << s.mUs << '\n';
    //o << "Color(mThem)" << s.mThem << '\n';

    /*
    print_bb(s.getOccupancyBB(white));
    print_bb(s.getOccupancyBB(black));
    */
    //std::cout << s.getKey() << '\n';

    return o;
}

// Assembly:
subq $0x3f8, %rsp            # imm = 0x3F8
movq %rdi, 0x3e8(%rsp)
movq %rsi, 0x3e0(%rsp)
leaq 0xc282(%rip), %rax      # 0x44d80
movq %rax, 0x3d8(%rsp)
leaq 0xc277(%rip), %rax      # 0x44d84
movq %rax, 0x3d0(%rsp)
leaq 0xc26c(%rip), %rax      # 0x44d88
movq %rax, 0x3c8(%rsp)
leaq 0xc261(%rip), %rax      # 0x44d8c
movq %rax, 0x3c0(%rsp)
leaq 0xc256(%rip), %rax      # 0x44d90
movq %rax, 0x3b8(%rsp)
leaq 0xc24b(%rip), %rax      # 0x44d94
movq %rax, 0x3b0(%rsp)
leaq 0xc240(%rip), %rax      # 0x44d98
movq %rax, 0x3a8(%rsp)
leaq 0xc235(%rip), %rax      # 0x44d9c
movq %rax, 0x3a0(%rsp)
leaq 0xc22a(%rip), %rax      # 0x44da0
movq %rax, 0x398(%rsp)
leaq 0xc21f(%rip), %rax      # 0x44da4
movq %rax, 0x390(%rsp)
leaq 0xc214(%rip), %rax      # 0x44da8
movq %rax, 0x388(%rsp)
leaq 0xc209(%rip), %rax      # 0x44dac
movq %rax, 0x380(%rsp)
leaq 0x84b1(%rip), %rax      # 0x41063
movq %rax, 0x378(%rsp)
movb $0x1, 0x24c(%rsp)
leaq 0x270(%rsp), %rax
movq %rax, 0x208(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x267(%rsp), %rdi
movq %rdi, 0x210(%rsp)
callq 0x54c0
movq 0x208(%rsp), %rdi
movq 0x210(%rsp), %rdx
leaq 0x7414(%rip), %rsi      # 0x4001a
callq 0x5370
jmp 0x38c0d
leaq 0x290(%rsp), %rax
movq %rax, 0x1f8(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x253(%rsp), %rdi
movq %rdi, 0x200(%rsp)
callq 0x54c0
movq 0x1f8(%rsp), %rdi
movq 0x200(%rsp), %rdx
leaq 0x73e1(%rip), %rsi      # 0x40032
callq 0x5370
jmp 0x38c58
leaq 0x2b0(%rsp), %rax
movq %rax, 0x1e8(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x252(%rsp), %rdi
movq %rdi, 0x1f0(%rsp)
callq 0x54c0
movq 0x1e8(%rsp), %rdi
movq 0x1f0(%rsp), %rdx
leaq 0x73a5(%rip), %rsi      # 0x40041
callq 0x5370
jmp 0x38ca3
leaq 0x2d0(%rsp), %rax
movq %rax, 0x1d8(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x251(%rsp), %rdi
movq %rdi, 0x1e0(%rsp)
callq 0x54c0
movq 0x1d8(%rsp), %rdi
movq 0x1e0(%rsp), %rdx
leaq 0xc733(%rip), %rsi      # 0x4541a
callq 0x5370
jmp 0x38cee
leaq 0x2f0(%rsp), %rax
movq %rax, 0x1c8(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x250(%rsp), %rdi
movq %rdi, 0x1d0(%rsp)
callq 0x54c0
movq 0x1c8(%rsp), %rdi
movq 0x1d0(%rsp), %rdx
leaq 0x7324(%rip), %rsi      # 0x40056
callq 0x5370
jmp 0x38d39
leaq 0x310(%rsp), %rax
movq %rax, 0x1b8(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x24f(%rsp), %rdi
movq %rdi, 0x1c0(%rsp)
callq 0x54c0
movq 0x1b8(%rsp), %rdi
movq 0x1c0(%rsp), %rdx
leaq 0x72e8(%rip), %rsi      # 0x40065
callq 0x5370
jmp 0x38d84
leaq 0x330(%rsp), %rax
movq %rax, 0x1a8(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x24e(%rsp), %rdi
movq %rdi, 0x1b0(%rsp)
callq 0x54c0
movq 0x1a8(%rsp), %rdi
movq 0x1b0(%rsp), %rdx
leaq 0x72b5(%rip), %rsi      # 0x4007d
callq 0x5370
jmp 0x38dcf
leaq 0x350(%rsp), %rax
movq %rax, 0x198(%rsp)
movq %rax, 0x268(%rsp)
leaq 0x24d(%rsp), %rdi
movq %rdi, 0x1a0(%rsp)
callq 0x54c0
movq 0x198(%rsp), %rdi
movq 0x1a0(%rsp), %rdx
leaq 0xc79c(%rip), %rsi      # 0x455af
callq 0x5370
jmp 0x38e1a
movb $0x0, 0x24c(%rsp)
leaq 0x24d(%rsp), %rdi
callq 0x52e0
leaq 0x24e(%rsp), %rdi
callq 0x52e0
leaq 0x24f(%rsp), %rdi
callq 0x52e0
leaq 0x250(%rsp), %rdi
callq 0x52e0
leaq 0x251(%rsp), %rdi
callq 0x52e0
leaq 0x252(%rsp), %rdi
callq 0x52e0
leaq 0x253(%rsp), %rdi
callq 0x52e0
leaq 0x267(%rsp), %rdi
callq 0x52e0
leaq 0x227(%rsp), %rdi
movq %rdi, 0x190(%rsp)
callq 0x54c0
movq 0x190(%rsp), %rdx
leaq 0xbf02(%rip), %rsi      # 0x44db0
leaq 0x228(%rsp), %rdi
callq 0x5370
jmp 0x38ebd
leaq 0x227(%rsp), %rdi
callq 0x52e0
movq 0x3e8(%rsp), %rdi
leaq 0x228(%rsp), %rsi
callq 0x5220
movq %rax, 0x188(%rsp)
jmp 0x38ee9
movq 0x188(%rsp), %rdi
movq 0x18098(%rip), %rsi     # 0x50f90
callq 0x52c0
jmp 0x38eff
movl $0x3f, 0x220(%rsp)
cmpl $0x0, 0x220(%rsp)
jl 0x396d0
movslq 0x220(%rsp), %rcx
leaq 0x11bbe9(%rip), %rax    # 0x154b10
movq (%rax,%rcx,8), %rax
movq %rax, 0x218(%rsp)
movl 0x220(%rsp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
cmpl $0x7, %edx
jne 0x39173
movq 0x3e8(%rsp), %rdi
movl 0x220(%rsp), %eax
movl %eax, %ecx
addl $0x7, %ecx
testl %eax, %eax
cmovsl %ecx, %eax
sarl $0x3, %eax
cltq
shlq $0x5, %rax
leaq 0x270(%rsp,%rax), %rsi
callq 0x5220
movq %rax, 0x180(%rsp)
jmp 0x38f84
movq 0x180(%rsp), %rdi
leaq 0x7c52(%rip), %rsi      # 0x40be5
callq 0x5290
jmp 0x38f9a
jmp 0x39173
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
jmp 0x390b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
jmp 0x390a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
jmp 0x3909a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
jmp 0x3908d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
jmp 0x39080
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
jmp 0x39073
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
jmp 0x39066
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
leaq 0x24d(%rsp), %rdi
callq 0x52e0
leaq 0x24e(%rsp), %rdi
callq 0x52e0
leaq 0x24f(%rsp), %rdi
callq 0x52e0
leaq 0x250(%rsp), %rdi
callq 0x52e0
leaq 0x251(%rsp), %rdi
callq 0x52e0
leaq 0x252(%rsp), %rdi
callq 0x52e0
leaq 0x253(%rsp), %rdi
callq 0x52e0
leaq 0x267(%rsp), %rdi
callq 0x52e0
testb $0x1, 0x24c(%rsp)
jne 0x390cd
jmp 0x39122
movq 0x268(%rsp), %rax
leaq 0x270(%rsp), %rcx
cmpq %rax, %rcx
movq %rax, 0x178(%rsp)
je 0x39120
movq 0x178(%rsp), %rdi
addq $-0x20, %rdi
movq %rdi, 0x170(%rsp)
callq 0x5538
movq 0x170(%rsp), %rax
leaq 0x270(%rsp), %rcx
cmpq %rcx, %rax
movq %rax, 0x178(%rsp)
jne 0x390ea
jmp 0x39122
jmp 0x397ce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
leaq 0x227(%rsp), %rdi
callq 0x52e0
jmp 0x3978f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x258(%rsp)
movl %eax, 0x254(%rsp)
leaq 0x228(%rsp), %rdi
callq 0x5538
jmp 0x3978f
movq 0x3e8(%rsp), %rax
movq %rax, 0x158(%rsp)
movq 0x218(%rsp), %rax
movq %rax, 0x160(%rsp)
movq 0x3e0(%rsp), %rdi
xorl %esi, %esi
callq 0x24b80
movq %rax, 0x168(%rsp)
jmp 0x391ac
movq 0x168(%rsp), %rcx
movq 0x160(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x391da
movq 0x3d8(%rsp), %rax
movq %rax, 0x150(%rsp)
jmp 0x39630
movq 0x218(%rsp), %rax
movq %rax, 0x140(%rsp)
movq 0x3e0(%rsp), %rdi
xorl %esi, %esi
callq 0x25bb0
movq %rax, 0x148(%rsp)
jmp 0x39203
movq 0x148(%rsp), %rcx
movq 0x140(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x39231
movq 0x3d0(%rsp), %rax
movq %rax, 0x138(%rsp)
jmp 0x39620
movq 0x218(%rsp), %rax
movq %rax, 0x128(%rsp)
movq 0x3e0(%rsp), %rdi
xorl %esi, %esi
callq 0x25bf0
movq %rax, 0x130(%rsp)
jmp 0x3925a
movq 0x130(%rsp), %rcx
movq 0x128(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x39288
movq 0x3c8(%rsp), %rax
movq %rax, 0x120(%rsp)
jmp 0x39610
movq 0x218(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0x3e0(%rsp), %rdi
xorl %esi, %esi
callq 0x2b410
movq %rax, 0x118(%rsp)
jmp 0x392b1
movq 0x118(%rsp), %rcx
movq 0x110(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x392df
movq 0x3c0(%rsp), %rax
movq %rax, 0x108(%rsp)
jmp 0x39600
movq 0x218(%rsp), %rax
movq %rax, 0xf8(%rsp)
movq 0x3e0(%rsp), %rdi
xorl %esi, %esi
callq 0x2b3d0
movq %rax, 0x100(%rsp)
jmp 0x39308
movq 0x100(%rsp), %rcx
movq 0xf8(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x39336
movq 0x3b8(%rsp), %rax
movq %rax, 0xf0(%rsp)
jmp 0x395f0
movq 0x218(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0x3e0(%rsp), %rdi
xorl %esi, %esi
callq 0x25510
movq %rax, 0xe8(%rsp)
jmp 0x3935f
movq 0xe8(%rsp), %rcx
movq 0xe0(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x3938d
movq 0x3b0(%rsp), %rax
movq %rax, 0xd8(%rsp)
jmp 0x395e0
movq 0x218(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0x3e0(%rsp), %rdi
movl $0x1, %esi
callq 0x24b80
movq %rax, 0xd0(%rsp)
jmp 0x393b9
movq 0xd0(%rsp), %rcx
movq 0xc8(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x393e7
movq 0x3a8(%rsp), %rax
movq %rax, 0xc0(%rsp)
jmp 0x395d0
movq 0x218(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0x3e0(%rsp), %rdi
movl $0x1, %esi
callq 0x25bb0
movq %rax, 0xb8(%rsp)
jmp 0x39413
movq 0xb8(%rsp), %rcx
movq 0xb0(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x39441
movq 0x3a0(%rsp), %rax
movq %rax, 0xa8(%rsp)
jmp 0x395c0
movq 0x218(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x3e0(%rsp), %rdi
movl $0x1, %esi
callq 0x25bf0
movq %rax, 0xa0(%rsp)
jmp 0x3946d
movq 0xa0(%rsp), %rcx
movq 0x98(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x3949b
movq 0x398(%rsp), %rax
movq %rax, 0x90(%rsp)
jmp 0x395b0
movq 0x218(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x3e0(%rsp), %rdi
movl $0x1, %esi
callq 0x2b410
movq %rax, 0x88(%rsp)
jmp 0x394c7
movq 0x88(%rsp), %rcx
movq 0x80(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x394f2
movq 0x390(%rsp), %rax
movq %rax, 0x78(%rsp)
jmp 0x395a3
movq 0x218(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x3e0(%rsp), %rdi
movl $0x1, %esi
callq 0x2b3d0
movq %rax, 0x70(%rsp)
jmp 0x39518
movq 0x70(%rsp), %rcx
movq 0x68(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x3953a
movq 0x388(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0x39599
movq 0x218(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x3e0(%rsp), %rdi
movl $0x1, %esi
callq 0x25510
movq %rax, 0x58(%rsp)
jmp 0x39560
movq 0x58(%rsp), %rcx
movq 0x50(%rsp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0x39582
movq 0x380(%rsp), %rax
movq %rax, 0x48(%rsp)
jmp 0x3958f
movq 0x378(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0xf0(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0x138(%rsp)
movq 0x138(%rsp), %rax
movq %rax, 0x150(%rsp)
movq 0x158(%rsp), %rdi
movq 0x150(%rsp), %rsi
callq 0x5290
movq %rax, 0x40(%rsp)
jmp 0x3964c
movq 0x40(%rsp), %rdi
leaq 0x758d(%rip), %rsi      # 0x40be5
callq 0x5290
jmp 0x3965f
movl 0x220(%rsp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x396b8
movq 0x3e8(%rsp), %rdi
movl $0xa, %esi
callq 0x5300
movq %rax, 0x38(%rsp)
jmp 0x3968c
movq 0x38(%rsp), %rdi
leaq 0x228(%rsp), %rsi
callq 0x5220
movq %rax, 0x30(%rsp)
jmp 0x396a5
movq 0x30(%rsp), %rdi
movl $0xa, %esi
callq 0x5300
jmp 0x396b6
jmp 0x396b8
jmp 0x396ba
movl 0x220(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x220(%rsp)
jmp 0x38f0a
movq 0x3e8(%rsp), %rdi
leaq 0xb6e4(%rip), %rsi      # 0x44dc3
callq 0x5290
jmp 0x396e6
movq 0x3e0(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x3970b
movq 0x3e8(%rsp), %rdi
leaq 0xb6d4(%rip), %rsi      # 0x44dd6
callq 0x5290
jmp 0x39709
jmp 0x39723
movq 0x3e8(%rsp), %rdi
leaq 0xb6cc(%rip), %rsi      # 0x44de6
callq 0x5290
jmp 0x39721
jmp 0x39723
movq 0x3e8(%rsp), %rax
movq %rax, 0x3f0(%rsp)
leaq 0x228(%rsp), %rdi
callq 0x5538
leaq 0x270(%rsp), %rax
movq %rax, 0x20(%rsp)
addq $0x100, %rax            # imm = 0x100
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rdi
addq $-0x20, %rdi
movq %rdi, 0x18(%rsp)
callq 0x5538
movq 0x20(%rsp), %rcx
movq 0x18(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x28(%rsp)
jne 0x39758
movq 0x3f0(%rsp), %rax
addq $0x3f8, %rsp            # imm = 0x3F8
retq
leaq 0x270(%rsp), %rax
movq %rax, 0x8(%rsp)
addq $0x100, %rax            # imm = 0x100
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
addq $-0x20, %rdi
movq %rdi, (%rsp)
callq 0x5538
movq 0x8(%rsp), %rcx
movq (%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x10(%rsp)
jne 0x397a7
jmp 0x397ce
movq 0x258(%rsp), %rdi
callq 0x54b0
nopl (%rax,%rax)