// File: bjohnsonfl[P]Overhead-Chess-Engine-/search.cpp
// Function: perft(int, position&)
bitboard perft (int depth, position& pos)
{
    
    candMoveList moves ;
   
    
    bitboard nodes=0;
    returnState state = returnState();
    if(depth == 0) return 1;
  //  std::cout<<"Depth: "<<depth << "\n";
   // std::cout<<"====================\n";
    if(depth == 1 ){
     // std::cout<<"Depth: "<<depth << "\n";
       // pos.printBoard();
    }
   
  /// moves.end = generateCapture(pos, moves.end);
    moves.end = generateAllLegal(pos, moves.end);
    while(moves.start != moves.end)
    {
        if(pos.legal(moves.start -> mv)){
            
            
           // pos.printBoard();
            //printmove(moves.start -> mv);
            //std::cout<<pos.get_enPassent()  <<"\n";
            if(moves.start -> mv == move(919))// && state.prev->m == move(324))
            {
               // std::cout<<"this move\n";
              //  printBitboard(pos.get_pinned(pos.get_sideToPlay()));
               // pos.printBoard();
               // pos.printAllBitboards();
                
            }
            if(state.captured == b_king || state.captured == w_king)
            {
                //std::cout<<"this move\n";
                //printmove(state.m);
                //printmove(state.prev->m);
                //printmove(moves.start -> mv);
                //pos.printBoard();
            }
            bitboard newBoards [12] ;
            for(int i=0; i<12; i++) newBoards[i] = pos.get_pieces(piece(i));
           
            int whiteCount = popcount(pos.get_pieces(white));
            int blackCount =  popcount(pos.get_pieces(black));
            
            
            //pos.printBoard();
            pos.do_move(moves.start -> mv, state);
            if(pos.get_pieces(pos.get_sideToPlay()) & pos.squareAttackedBy(pos.get_king_sq(player(!pos.get_sideToPlay()))))
            {
                printmove(moves.start -> mv);
                pos.printBoard();
            }
            
            
            if((popcount(pos.get_pieces(white)) < whiteCount) && pos.get_sideToPlay() != white)
            {
                pos.printBoard();
                printmove(moves.start -> mv);
            }
            
            if((popcount(pos.get_pieces(black)) < blackCount) && pos.get_sideToPlay() != black)
            {
                pos.printBoard();
                printmove(moves.start -> mv);
            }
           // printmove(moves.start -> mv);
           // pos.printBoard();
            if( popcount(pos.get_pieces(p_king)) < 2)
            {
                
             //   pos.printAllBitboards();
            }
            nodes += perft(depth -1, pos);
            pos.undo_move(moves.start -> mv);
            
            if(popcount(pos.get_pieces(white)) != whiteCount || popcount(pos.get_pieces(black)) != blackCount)
            {
                pos.printBoard();
            }
            
            
          //  pos.printBoard();
            for(int i=0; i<12; i++) {
              if(  newBoards[i] != pos.get_pieces(piece(i)))
              {
                  pos.printBoard();
              }
            }
            
           // pos.printBoard();
            if( popcount(pos.get_pieces(p_king)) < 2)
            {
               
              //  pos.printAllBitboards();
            }
            if(pos.numberOfPieces() > 32)  {
                std::cout<<"Number oF Pieces: "<< pos.numberOfPieces() << " Depth: " << depth <<"\n";
                std::cout<<"Number oF white: "<< popcount(pos.get_pieces(white)) << "\n";
                std::cout<<"Number oF black: "<< popcount(pos.get_pieces(black)) << "\n";
                std::cout<<"Number oF black Pawns: "<< popcount(pos.get_pieces(black, p_pawn)) << "\n";
                
                std::cout<<pos.get_sideToPlay() << "\n";
                printmove(moves.start -> mv);
                pos.printBoard();
                pos.printAllBitboards();
                printBitboard(pos.get_pieces());
                
            }
           // pos.printBoard();
           // std::cout<< "LEGALLLLLLL\n";
        }
        
        moves.start++;
    }
    return nodes;
    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x940, %rsp            # imm = 0x940
movl %edi, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
leaq -0x828(%rbp), %rdi
callq 0xad00
movq $0x0, -0x830(%rbp)
leaq -0x878(%rbp), %rdi
callq 0x9f10
cmpl $0x0, -0xc(%rbp)
jne 0xa318
movq $0x1, -0x8(%rbp)
jmp 0xa815
cmpl $0x1, -0xc(%rbp)
jne 0xa320
jmp 0xa320
movq -0x18(%rbp), %rdi
movq -0x828(%rbp), %rsi
callq 0x66f0
movq %rax, -0x828(%rbp)
movq -0x820(%rbp), %rax
cmpq -0x828(%rbp), %rax
je 0xa80a
movq -0x18(%rbp), %rdi
movq -0x820(%rbp), %rax
movl (%rax), %esi
callq 0x9b10
testb $0x1, %al
jne 0xa366
jmp 0xa7f3
movq -0x820(%rbp), %rax
cmpl $0x397, (%rax)          # imm = 0x397
jne 0xa377
jmp 0xa377
cmpl $0xb, -0x86c(%rbp)
je 0xa389
cmpl $0x5, -0x86c(%rbp)
jne 0xa38b
jmp 0xa38b
movl $0x0, -0x8e4(%rbp)
cmpl $0xc, -0x8e4(%rbp)
jge 0xa3d0
movq -0x18(%rbp), %rdi
movl -0x8e4(%rbp), %esi
callq 0xa140
movq %rax, %rcx
movslq -0x8e4(%rbp), %rax
movq %rcx, -0x8e0(%rbp,%rax,8)
movl -0x8e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8e4(%rbp)
jmp 0xa395
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
movl %eax, -0x8e8(%rbp)
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
movl %eax, -0x8ec(%rbp)
movq -0x18(%rbp), %rdi
movq -0x820(%rbp), %rax
movl (%rax), %esi
leaq -0x878(%rbp), %rdx
callq 0x86f0
movq -0x18(%rbp), %rax
movq %rax, -0x910(%rbp)
movq -0x18(%rbp), %rdi
callq 0x75c0
movq -0x910(%rbp), %rdi
movl %eax, %esi
callq 0x7600
movq %rax, -0x8f8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x900(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x908(%rbp)
movq -0x18(%rbp), %rdi
callq 0x75c0
movq -0x908(%rbp), %rdi
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %esi
callq 0x7640
movq -0x900(%rbp), %rdi
movl %eax, %esi
callq 0x98b0
movq %rax, %rcx
movq -0x8f8(%rbp), %rax
andq %rcx, %rax
cmpq $0x0, %rax
je 0xa4b7
movq -0x820(%rbp), %rax
movl (%rax), %edi
callq 0x6fc0
movq -0x18(%rbp), %rdi
callq 0x9120
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
cmpl -0x8e8(%rbp), %eax
jge 0xa4f7
movq -0x18(%rbp), %rdi
callq 0x75c0
cmpl $0x0, %eax
je 0xa4f7
movq -0x18(%rbp), %rdi
callq 0x9120
movq -0x820(%rbp), %rax
movl (%rax), %edi
callq 0x6fc0
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
cmpl -0x8ec(%rbp), %eax
jge 0xa53a
movq -0x18(%rbp), %rdi
callq 0x75c0
cmpl $0x1, %eax
je 0xa53a
movq -0x18(%rbp), %rdi
callq 0x9120
movq -0x820(%rbp), %rax
movl (%rax), %edi
callq 0x6fc0
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x7750
movq %rax, %rdi
callq 0x3fa0
cmpl $0x2, %eax
jge 0xa557
jmp 0xa557
movl -0xc(%rbp), %edi
subl $0x1, %edi
movq -0x18(%rbp), %rsi
callq 0xa2d0
addq -0x830(%rbp), %rax
movq %rax, -0x830(%rbp)
movq -0x18(%rbp), %rdi
movq -0x820(%rbp), %rax
movl (%rax), %esi
callq 0x92f0
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
cmpl -0x8e8(%rbp), %eax
jne 0xa5bf
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
cmpl -0x8ec(%rbp), %eax
je 0xa5c8
movq -0x18(%rbp), %rdi
callq 0x9120
movl $0x0, -0x8f0(%rbp)
cmpl $0xc, -0x8f0(%rbp)
jge 0xa62b
movslq -0x8f0(%rbp), %rax
movq -0x8e0(%rbp,%rax,8), %rax
movq %rax, -0x918(%rbp)
movq -0x18(%rbp), %rdi
movl -0x8f0(%rbp), %esi
callq 0xa140
movq %rax, %rcx
movq -0x918(%rbp), %rax
cmpq %rcx, %rax
je 0xa618
movq -0x18(%rbp), %rdi
callq 0x9120
jmp 0xa61a
movl -0x8f0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8f0(%rbp)
jmp 0xa5d2
movq -0x18(%rbp), %rdi
movl $0x5, %esi
callq 0x7750
movq %rax, %rdi
callq 0x3fa0
cmpl $0x2, %eax
jge 0xa648
jmp 0xa648
movq -0x18(%rbp), %rdi
callq 0xad30
cmpl $0x20, %eax
jle 0xa7f1
movq 0x7967(%rip), %rdi      # 0x11fc8
leaq 0x3da6(%rip), %rsi      # 0xe40e
callq 0x31e0
movq %rax, -0x938(%rbp)
movq -0x18(%rbp), %rdi
callq 0xad30
movq -0x938(%rbp), %rdi
movl %eax, %esi
callq 0x3380
movq %rax, %rdi
leaq 0x3d8c(%rip), %rsi      # 0xe421
callq 0x31e0
movq %rax, %rdi
movl -0xc(%rbp), %esi
callq 0x3380
movq %rax, %rdi
leaq 0x3d16(%rip), %rsi      # 0xe3c5
callq 0x31e0
movq 0x790d(%rip), %rdi      # 0x11fc8
leaq 0x3d68(%rip), %rsi      # 0xe42a
callq 0x31e0
movq %rax, -0x930(%rbp)
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
movq -0x930(%rbp), %rdi
movl %eax, %esi
callq 0x3380
movq %rax, %rdi
leaq 0x3ccc(%rip), %rsi      # 0xe3c5
callq 0x31e0
movq 0x78c3(%rip), %rdi      # 0x11fc8
leaq 0x3d30(%rip), %rsi      # 0xe43c
callq 0x31e0
movq %rax, -0x928(%rbp)
movq -0x18(%rbp), %rdi
movl $0x1, %esi
callq 0x7600
movq %rax, %rdi
callq 0x3fa0
movq -0x928(%rbp), %rdi
movl %eax, %esi
callq 0x3380
movq %rax, %rdi
leaq 0x3c7f(%rip), %rsi      # 0xe3c5
callq 0x31e0
movq 0x7876(%rip), %rdi      # 0x11fc8
leaq 0x3cf5(%rip), %rsi      # 0xe44e
callq 0x31e0
movq %rax, -0x920(%rbp)
movq -0x18(%rbp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x76b0
movq %rax, %rdi
callq 0x3fa0
movq -0x920(%rbp), %rdi
movl %eax, %esi
callq 0x3380
movq %rax, %rdi
leaq 0x3c30(%rip), %rsi      # 0xe3c5
callq 0x31e0
movq -0x18(%rbp), %rdi
callq 0x75c0
movl %eax, %esi
movq 0x781c(%rip), %rdi      # 0x11fc8
callq 0x3380
movq %rax, %rdi
leaq 0x3c0a(%rip), %rsi      # 0xe3c5
callq 0x31e0
movq -0x820(%rbp), %rax
movl (%rax), %edi
callq 0x6fc0
movq -0x18(%rbp), %rdi
callq 0x9120
movq -0x18(%rbp), %rdi
callq 0x9dd0
movq -0x18(%rbp), %rdi
callq 0x7690
movq %rax, %rdi
callq 0x58f0
jmp 0xa7f3
movq -0x820(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x820(%rbp)
jmp 0xa337
movq -0x830(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x940, %rsp            # imm = 0x940
popq %rbp
retq
nopw %cs:(%rax,%rax)