// File: /workspace/github_cpp_makefile_star2_O3/bjohnsonfl[P]Overhead-Chess-Engine-/position.cpp
// Function: position::do_move(move, returnState&)
void position::do_move(move m, returnState& newState)
{
   //castling
    //capturing
    //promoting
    //enpassent
    //update pieces
    
    if(m == move(86230))
    {
        printBoard();
        
    }

    newState.fiftyMove = state -> fiftyMove;
    newState.enPassent = state -> enPassent;
    newState.castling = state -> castling;
    newState.captured = state -> captured;
    newState.m = state -> m;
    newState.material[0] = state -> material[0];
    newState.material[1] = state -> material[1];
    
    //absolute pinned and pinners will be calculated later
    newState.prev = state;
    state = &newState;
    
    player us = get_sideToPlay();
    player them = player (!us);
    square from = source_sq(m);
    square to = destination_sq(m);
    moveFlag flag = move_flag(m);
    piece movingPiece = board[from];
    
    bool capture = false;
    piece captured =  not_piece;
    if((get_pieces(them) & squareBitMask[to]) && (flag != castling)){
        capture = true;
        captured = board[to];
        if(captured == b_king)
        {
           // std::cout<<"captured king\n";
            //printBoard();
        }
    }
    else{
        state -> captured = not_piece;
    }
    
    
    if(flag == castling)
    {
       
        square a_1 = us == white ? a1 : a8;
        square h_1 = us == white ? h1 : h8;
        piece king = us == white ? w_king : b_king;
        piece rook = us == white ? w_rook : b_rook;
        if(to == a_1)
        {
            square newKingSq =  us == white ? c1 : c8;
            square newRookSq =  us == white ? d1 : d8;
            remove_piece(from, king);
           // printBitboard(pieces[king]);
            remove_piece(to, rook);
            place_piece(newKingSq, king);
          //  printBitboard(pieces[king]);
            place_piece(newRookSq, rook);
            
            
        }
        else
        {
            square newKingSq =  us == white ? g1 : g8;
            square newRookSq =  us == white ? f1 : f8;
            remove_piece(from, king);
            //printBitboard(pieces[king]);
            remove_piece(to, rook);
            place_piece(newKingSq, king);
            //printBitboard(pieces[king]);
            place_piece(newRookSq, rook);
        }
        
        if(us == white) {
            state -> castling &= (~ W_OO);
            state -> castling &= (~ W_OOO);
        }
        else {
            state -> castling &= (~ B_OO);
            state -> castling &= (~ B_OOO);
        }
        state->captured = not_piece;
    }
    
    
    if(capture && (flag != castling))
    {
        //debug
       // printBoard();
        ++count;
       // std::cout <<count <<"\n";
        bitboard pieceColor = 0;
       
        if (us == white)
        {
            pieceColor = allWhitePieces;
        
        }
        else {
             pieceColor = allBlackPieces;
        }
        
        if(m == move(196) || m == move(2281))
        {
           // printBoard();
            //printBitboard(pieceColor);
        }
        ///////////////
        state -> captured = captured;
        remove_piece (to, captured);
        remove_piece (from, movingPiece);
        place_piece(to, movingPiece);
        state->fiftyMove = 0;
        
        bitboard pieceColor2 = 0;
        if (us == white)
        {
            pieceColor2= allWhitePieces;
            
        }
        else {
            pieceColor2 = allBlackPieces;
        }
        if(popcount(pieceColor2) < popcount(pieceColor2))
        {
            printBoard();
            printBitboard(pieceColor2);
            std::cout << "fail\n";
        }
        state->material[them] =  value(state->material[them] - pieceValue[piece_To_Piecetype(captured) + 1]);
    }
    
    if(flag == enPass)
    {
        state -> captured = captured;
        square enPsq = state -> enPassent;
        square capturedPawn = us == white ? square(enPsq + south) : square(enPsq + nort);
        remove_piece(from, movingPiece);
        remove_piece(capturedPawn, board[capturedPawn]);
        place_piece(enPsq, movingPiece);
        state->fiftyMove = 0;
        state->material[them] =  value(state->material[them] - pieceValue[p_pawn + 1]);
    }
    
    if(( flag == regular  || flag == promoting )&& !capture)
    {
        remove_piece(from, movingPiece);
        place_piece(to, movingPiece);
        
    }
    
   //Reset enPassent flag
    state -> enPassent = empty;
    
    if(movingPiece == w_pawn || movingPiece == b_pawn)
    {
        if(flag == promoting)
        {
            remove_piece(to, movingPiece);
            piece promo = piece(promo_pieceType(m));
            if(us == black) promo = piece(promo + 6);
            place_piece(to, promo);
            
            //remove pawn material and add promoting material
            state->material[us] =  value(state->material[us] - pieceValue[piece_To_Piecetype(movingPiece) + 1]);
            state->material[us] =  value(state->material[us] + pieceValue[piece_To_Piecetype(promo) + 1]);
        }
        if((us == white) && ((to - from) == 16)){
            bitboard attacks = attacksFromPawn(square(to + south ), us) & get_pieces(them, p_pawn);
            if(attacks) state -> enPassent = square(to + south );
        }
        if((us == black) && ((from - to) == 16))
        {
            bitboard attacks = attacksFromPawn(square(to + nort ), us) & get_pieces(them, p_pawn);
            if(attacks) state -> enPassent = square(to + nort );
        }
        state->fiftyMove = 0;
    }
    
    
    if(state->castling)
    {
        //KING MOVES
        if(movingPiece == w_king) state->castling = state->castling & (~ W_OO) & ( ~ W_OOO);
        else if (movingPiece == b_king) state->castling = state->castling & (~ B_OO) & ( ~ B_OOO);
        //ROOK MOVES
        else if(movingPiece == w_rook && (from == a1)) state -> castling = state -> castling & ( ~ W_OOO);
        else if(movingPiece == w_rook && (from == h1)) state -> castling = state -> castling & ( ~ W_OO);
        else if(movingPiece == b_rook && (from == a8)) state -> castling = state -> castling & ( ~ B_OOO);
        else if(movingPiece == b_rook && (from == h8)) state -> castling = state -> castling & ( ~ B_OO);
        //ROOK CAPTURED
        else if(captured == w_rook && (to == a1)) state -> castling = state -> castling & ( ~ W_OOO);
        else if(captured == w_rook && (to == h1)) state -> castling = state -> castling & ( ~ W_OO);
        else if(captured == b_rook && (to == a8)) state -> castling = state -> castling & ( ~ B_OOO);
        else if(captured == b_rook && (to == h8)) state -> castling = state -> castling & ( ~ B_OO);
        
    }
    
    ++ply;
    ++nodes;
    sideToPlay = them;
    state->m = m;
    update_check_boards(state);
    
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdx, %r15
movl %esi, %ebx
movq %rdi, %r13
cmpl $0x150d6, %esi          # imm = 0x150D6
jne 0x4d3c
movq %r13, %rdi
callq 0x5298
movq 0x188(%r13), %rax
movups (%rax), %xmm0
movups %xmm0, (%r15)
movl 0x10(%rax), %ecx
movl %ecx, 0x10(%r15)
movl 0x40(%rax), %ecx
movl %ecx, 0x40(%r15)
movl 0x44(%rax), %ecx
movl %ecx, 0x44(%r15)
movq %rax, 0x18(%r15)
movq %r15, 0x188(%r13)
movl 0x17c(%r13), %r12d
xorl %eax, %eax
testq %r12, %r12
sete %al
movl %ebx, %r8d
andl $0x3f, %r8d
movl %ebx, %edx
shrl $0x6, %edx
andl $0x3f, %edx
movl %ebx, %esi
shrl $0xe, %esi
andl $0x3, %esi
movl (%r13,%r8,4), %ecx
movl %ecx, 0xc(%rsp)
leaq 0x7040(%rip), %rcx      # 0xbde0
movq (%rcx,%rdx,8), %rcx
testq %rcx, 0x160(%r13,%rax,8)
setne %al
cmpl $0x2, %esi
setne %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0x4dc7
movl (%r13,%rdx,4), %eax
movl %eax, 0x8(%rsp)
jmp 0x4dd7
movl $0xc, 0xc(%r15)
movl $0xc, 0x8(%rsp)
movq %rdx, 0x10(%rsp)
cmpl $0x2, %esi
movq %r8, 0x28(%rsp)
movl %ebx, 0x24(%rsp)
movl %esi, 0x20(%rsp)
movb %cl, 0x7(%rsp)
jne 0x4eec
xorl %eax, %eax
xorl %edi, %edi
testq %r12, %r12
movl $0x38, %edx
cmovel %eax, %edx
movl %edx, 0x34(%rsp)
movl $0x5, %eax
movl $0xb, %edx
cmovel %eax, %edx
movl %edx, 0x30(%rsp)
movl $0x3, %ecx
movl $0x9, %r9d
cmovel %ecx, %r9d
movl %r9d, 0x1c(%rsp)
movl $0x6, %r9d
movl $0x3e, %ebx
cmovel %r9d, %ebx
movl $0x3d, %r15d
cmovel %eax, %r15d
movl $0x2, %eax
movq %r12, 0x40(%rsp)
movl $0x3a, %r12d
cmovel %eax, %r12d
movq %r13, %r14
movl $0x3b, %r13d
cmovel %ecx, %r13d
sete %dil
movq %rdi, 0x38(%rsp)
movq %r14, %rdi
movl %r8d, %esi
callq 0x5370
movq %r14, %rdi
movq 0x10(%rsp), %rbp
movl %ebp, %esi
movl 0x1c(%rsp), %edx
callq 0x5370
cmpl 0x34(%rsp), %ebp
cmovnel %ebx, %r12d
cmovnel %r15d, %r13d
movq %r14, %rdi
movl %r12d, %esi
movq 0x40(%rsp), %r12
movl 0x30(%rsp), %edx
callq 0x4cb4
movq %r14, %rdi
movl %r13d, %esi
movq %r14, %r13
movl 0x1c(%rsp), %edx
callq 0x4cb4
movb 0x7(%rsp), %cl
movl 0x20(%rsp), %esi
movq 0x28(%rsp), %r8
movq 0x38(%rsp), %rax
leal (%rax,%rax,8), %eax
addl $-0xd, %eax
movq 0x188(%r14), %r15
andl %eax, 0x8(%r15)
movl $0xc, 0xc(%r15)
testb %cl, %cl
je 0x4fe0
xorl %ebx, %ebx
testq %r12, %r12
setne %bl
incl 0xeb62e(%rip)           # 0xf0530
movl 0x8(%rsp), %edx
movl %edx, 0xc(%r15)
movq %r13, %rdi
movq 0x10(%rsp), %r15
movl %r15d, %esi
movq %r8, %rbp
callq 0x5370
movq %r13, %rdi
movl %ebp, %esi
movl 0xc(%rsp), %ebp
movl %ebp, %edx
callq 0x5370
movq %r13, %rdi
movl %r15d, %esi
movl %ebp, %edx
callq 0x4cb4
movq 0x188(%r13), %rax
movl $0x0, (%rax)
movq 0x160(%r13,%rbx,8), %r15
movq %r15, %rdi
callq 0x28c9
movl %eax, %ebp
movq %r15, %rdi
callq 0x28c9
cmpl %eax, %ebp
jge 0x4f8d
movq %r13, %rdi
callq 0x5298
movq %r15, %rdi
callq 0x35f7
movq 0x6044(%rip), %rdi      # 0xafc0
leaq 0x3476(%rip), %rsi      # 0x83f9
movl $0x5, %edx
callq 0x2180
xorl %eax, %eax
testq %r12, %r12
sete %al
movq 0x188(%r13), %r15
movl 0x8(%rsp), %esi
movslq %esi, %rcx
imulq $0x2aaaaaab, %rcx, %rcx # imm = 0x2AAAAAAB
movq %rcx, %rdx
shrq $0x3f, %rdx
shrq $0x20, %rcx
addl %edx, %ecx
addl %ecx, %ecx
leal (%rcx,%rcx,2), %ecx
movl %esi, %edx
subl %ecx, %edx
movslq %edx, %rcx
leaq 0x6196(%rip), %rdx      # 0xb160
movl 0x4(%rdx,%rcx,4), %ecx
subl %ecx, 0x40(%r15,%rax,4)
movq 0x28(%rsp), %r8
movl 0x20(%rsp), %esi
movb 0x7(%rsp), %cl
cmpl $0x1, %esi
jne 0x5069
xorl %r14d, %r14d
xorl %eax, %eax
testq %r12, %r12
sete %r14b
setne %al
movl 0x8(%rsp), %ecx
movl %ecx, 0xc(%r15)
movl 0x4(%r15), %r15d
shll $0x4, %eax
movq %r12, %rbp
leal (%rax,%r15), %r12d
addl $-0x8, %r12d
movq %r13, %rdi
movl %r8d, %esi
movl 0xc(%rsp), %ebx
movl %ebx, %edx
callq 0x5370
movl (%r13,%r12,4), %edx
movq %r13, %rdi
movl %r12d, %esi
movq %rbp, %r12
callq 0x5370
movq %r13, %rdi
movl %r15d, %esi
movl %ebx, %edx
callq 0x4cb4
movq 0x188(%r13), %r15
movl $0x0, (%r15)
leaq 0x6108(%rip), %rax      # 0xb160
movl 0x4(%rax), %eax
subl %eax, 0x40(%r15,%r14,4)
xorl %ebp, %ebp
movq 0x10(%rsp), %r14
jmp 0x50af
cmpl $0x3, %esi
sete %bpl
je 0x5076
testl %esi, %esi
jne 0x50a6
testb %cl, %cl
movq 0x10(%rsp), %r14
jne 0x50ab
movq %r13, %rdi
movl %r8d, %esi
movl 0xc(%rsp), %ebx
movl %ebx, %edx
callq 0x5370
movq %r13, %rdi
movl %r14d, %esi
movl %ebx, %edx
callq 0x4cb4
movq 0x188(%r13), %r15
jmp 0x50af
movq 0x10(%rsp), %r14
movl 0xc(%rsp), %ebx
movl $0x40, 0x4(%r15)
cmpl $0x6, %ebx
movl %ebx, %edx
je 0x50c6
testl %edx, %edx
jne 0x519f
testb %bpl, %bpl
movl 0x24(%rsp), %ebx
je 0x5138
movq %r13, %rdi
movl %r14d, %esi
callq 0x5370
movl %ebx, %ebp
shrl $0xc, %ebp
andl $0x3, %ebp
leal 0x1(%rbp), %eax
addl $0x7, %ebp
cmpq $0x1, %r12
cmovnel %eax, %ebp
movq %r13, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x4cb4
movl 0xc(%rsp), %edx
movq 0x188(%r13), %r15
movl 0x40(%r15,%r12,4), %eax
movl %edx, %ecx
subl $0x6, %ecx
cmovbl %edx, %ecx
movslq %ecx, %rcx
leaq 0x6042(%rip), %rsi      # 0xb160
subl 0x4(%rsi,%rcx,4), %eax
movl %ebp, %ecx
subl $0x6, %ecx
cmovbl %ebp, %ecx
movl %eax, 0x40(%r15,%r12,4)
addl 0x4(%rsi,%rcx,4), %eax
movl %eax, 0x40(%r15,%r12,4)
testq %r12, %r12
movq 0x28(%rsp), %rdi
jne 0x5166
movl %r14d, %eax
subl %edi, %eax
cmpl $0x10, %eax
jne 0x5166
leal -0x8(%r14), %eax
leaq 0x7f89(%rip), %rcx      # 0xd0e0
movq 0x130(%r13), %rsi
testq %rsi, (%rcx,%rax,8)
jne 0x5192
jmp 0x5196
cmpl $0x1, %r12d
jne 0x5196
movl %edi, %eax
subl %r14d, %eax
cmpl $0x10, %eax
jne 0x5196
leal 0x8(%r14), %eax
leaq 0x7f5f(%rip), %rcx      # 0xd0e0
movq 0x100(%r13), %rsi
testq %rsi, 0x200(%rcx,%rax,8)
je 0x5196
movl %eax, 0x4(%r15)
movl $0x0, (%r15)
jmp 0x51a8
movq 0x28(%rsp), %rdi
movl 0x24(%rsp), %ebx
movl 0x8(%r15), %eax
testl %eax, %eax
je 0x525e
cmpl $0x5, %edx
je 0x51c8
cmpl $0xb, %edx
jne 0x51d2
movl $0xfffffff3, %ecx       # imm = 0xFFFFFFF3
jmp 0x5258
movl $0xfffffffc, %ecx       # imm = 0xFFFFFFFC
jmp 0x5258
movl %edx, %r8d
xorl $0x3, %r8d
movl $0xfffffffd, %ecx       # imm = 0xFFFFFFFD
movl %edi, %esi
orl %r8d, %esi
je 0x5258
movl %edi, %esi
xorl $0x7, %esi
orl %r8d, %esi
jne 0x51f6
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
jmp 0x5258
xorl $0x9, %edx
movl %edi, %esi
xorl $0x38, %esi
orl %edx, %esi
jne 0x5209
movl $0xfffffff7, %ecx       # imm = 0xFFFFFFF7
jmp 0x5258
xorl $0x3f, %edi
orl %edx, %edi
jne 0x5217
movl $0xfffffffb, %ecx       # imm = 0xFFFFFFFB
jmp 0x5258
movl 0x8(%rsp), %edx
xorl $0x3, %edx
movl %r14d, %esi
orl %edx, %esi
je 0x5258
movl %r14d, %ecx
xorl $0x7, %ecx
orl %edx, %ecx
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
je 0x5258
movl 0x8(%rsp), %esi
xorl $0x9, %esi
movl %r14d, %ecx
xorl $0x38, %ecx
orl %esi, %ecx
movl $0xfffffff7, %ecx       # imm = 0xFFFFFFF7
je 0x5258
xorl $0x3f, %r14d
orl %esi, %r14d
movl $0xfffffffb, %ecx       # imm = 0xFFFFFFFB
jne 0x525e
andl %ecx, %eax
movl %eax, 0x8(%r15)
xorl %eax, %eax
testq %r12, %r12
sete %al
incl 0x178(%r13)
incq 0x180(%r13)
movl %eax, 0x17c(%r13)
movl %ebx, 0x10(%r15)
movq %r13, %rdi
movq %r15, %rsi
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4b9c