// File: /workspace/github_cpp_makefile_star2_O1/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, %ebp
movq %rdi, %rbx
cmpl $0x150d6, %esi          # imm = 0x150D6
jne 0x4c86
movq %rbx, %rdi
callq 0x5244
movq 0x188(%rbx), %rax
movl (%rax), %ecx
movl %ecx, (%r15)
movl 0x4(%rax), %ecx
movl %ecx, 0x4(%r15)
movl 0x8(%rax), %ecx
movl %ecx, 0x8(%r15)
movl 0xc(%rax), %ecx
movl %ecx, 0xc(%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(%rbx)
movl 0x17c(%rbx), %r14d
xorl %eax, %eax
testq %r14, %r14
sete %al
movl %ebp, %edx
andl $0x3f, %edx
movl %ebp, %r12d
shrl $0x6, %r12d
andl $0x3f, %r12d
movl %ebp, %esi
shrl $0xe, %esi
andl $0x3, %esi
movl (%rbx,%rdx,4), %ecx
movl %ecx, 0x10(%rsp)
leaq 0x70e4(%rip), %rcx      # 0xbde0
movq (%rcx,%r12,8), %rcx
testq %rcx, 0x160(%rbx,%rax,8)
setne %al
cmpl $0x2, %esi
setne %cl
andb %al, %cl
movb %cl, 0xb(%rsp)
cmpb $0x1, %cl
jne 0x4d26
movl (%rbx,%r12,4), %eax
movl %eax, 0xc(%rsp)
jmp 0x4d36
movl $0xc, 0xc(%r15)
movl $0xc, 0xc(%rsp)
movq %rdx, 0x28(%rsp)
cmpl $0x2, %esi
movq %r12, 0x18(%rsp)
movl %esi, 0x14(%rsp)
movq %r14, 0x38(%rsp)
jne 0x4e3c
xorl %eax, %eax
xorl %esi, %esi
testq %r14, %r14
movl $0x38, %ecx
cmovel %eax, %ecx
movl %ecx, 0x30(%rsp)
movl $0x5, %eax
movl %ebp, 0x34(%rsp)
movl $0xb, %ebp
cmovel %eax, %ebp
movl $0x3, %ecx
movl $0x9, %edx
cmovel %ecx, %edx
movl %edx, 0x24(%rsp)
movl $0x6, %edx
movl $0x3e, %r14d
cmovel %edx, %r14d
movl $0x3d, %r15d
cmovel %eax, %r15d
movl $0x2, %eax
movl $0x3a, %r12d
cmovel %eax, %r12d
movl $0x3b, %r13d
cmovel %ecx, %r13d
sete %sil
movq %rsi, 0x40(%rsp)
movq %rbx, %rdi
movq 0x28(%rsp), %rsi
movl %ebp, %edx
callq 0x531c
movq %rbx, %rdi
movq 0x18(%rsp), %rsi
movl 0x24(%rsp), %edx
callq 0x531c
movl 0x30(%rsp), %eax
cmpl %eax, 0x18(%rsp)
cmovnel %r14d, %r12d
movq 0x38(%rsp), %r14
cmovnel %r15d, %r13d
movq %rbx, %rdi
movl %r12d, %esi
movq 0x18(%rsp), %r12
movl %ebp, %edx
movl 0x34(%rsp), %ebp
callq 0x4c16
movq %rbx, %rdi
movl %r13d, %esi
movl 0x24(%rsp), %edx
callq 0x4c16
movl 0x14(%rsp), %esi
movq 0x40(%rsp), %rax
leal (%rax,%rax,8), %eax
addl $-0xd, %eax
movq 0x188(%rbx), %rcx
andl %eax, 0x8(%rcx)
movl $0xc, 0xc(%rcx)
cmpb $0x0, 0xb(%rsp)
je 0x4f43
movq %r12, %r15
movl %ebp, %r12d
movq %r14, %rax
xorl %r14d, %r14d
movq %rax, %r13
testq %rax, %rax
setne %r14b
incl 0xeb6cd(%rip)           # 0xf0530
movq 0x188(%rbx), %rax
movl 0xc(%rsp), %edx
movl %edx, 0xc(%rax)
movq %rbx, %rdi
movl %r15d, %esi
callq 0x531c
movq %rbx, %rdi
movq 0x28(%rsp), %rsi
movl 0x10(%rsp), %ebp
movl %ebp, %edx
callq 0x531c
movq %rbx, %rdi
movl %r15d, %esi
movl %ebp, %edx
callq 0x4c16
movq 0x188(%rbx), %rax
movl $0x0, (%rax)
movq 0x160(%rbx,%r14,8), %r15
movq %r15, %rdi
callq 0x28c9
movl %eax, %ebp
movq %r15, %rdi
callq 0x28c9
cmpl %eax, %ebp
jge 0x4eef
movq %rbx, %rdi
callq 0x5244
movq %r15, %rdi
callq 0x3532
movq 0x60e2(%rip), %rdi      # 0xafc0
leaq 0x347c(%rip), %rsi      # 0x8361
movl $0x5, %edx
callq 0x2180
xorl %eax, %eax
movq %r13, %r14
testq %r13, %r13
sete %al
movq 0x188(%rbx), %rcx
movl 0xc(%rsp), %edi
movslq %edi, %rdx
imulq $0x2aaaaaab, %rdx, %rdx # imm = 0x2AAAAAAB
movq %rdx, %rsi
shrq $0x3f, %rsi
shrq $0x20, %rdx
addl %esi, %edx
addl %edx, %edx
leal (%rdx,%rdx,2), %edx
movl %edi, %esi
subl %edx, %esi
movslq %esi, %rdx
leaq 0x6231(%rip), %rsi      # 0xb160
movl 0x4(%rsi,%rdx,4), %edx
subl %edx, 0x40(%rcx,%rax,4)
movl %r12d, %ebp
movq 0x18(%rsp), %r12
movl 0x14(%rsp), %esi
cmpl $0x1, %esi
jne 0x4fd7
xorl %r13d, %r13d
xorl %eax, %eax
testq %r14, %r14
sete %r13b
setne %al
movq 0x188(%rbx), %rcx
movl 0xc(%rsp), %edx
movl %edx, 0xc(%rcx)
movl 0x4(%rcx), %r15d
shll $0x4, %eax
leal (%rax,%r15), %r12d
addl $-0x8, %r12d
movq %rbx, %rdi
movq 0x28(%rsp), %rsi
movl %ebp, %r14d
movl 0x10(%rsp), %ebp
movl %ebp, %edx
callq 0x531c
movl (%rbx,%r12,4), %edx
movq %rbx, %rdi
movl %r12d, %esi
movq 0x18(%rsp), %r12
callq 0x531c
movq %rbx, %rdi
movl %r15d, %esi
movl %ebp, %edx
movl %r14d, %ebp
movq 0x38(%rsp), %r14
callq 0x4c16
movl 0x14(%rsp), %esi
movq 0x188(%rbx), %rax
movl $0x0, (%rax)
leaq 0x6191(%rip), %rcx      # 0xb160
movl 0x4(%rcx), %ecx
subl %ecx, 0x40(%rax,%r13,4)
cmpl $0x3, %esi
movq 0x28(%rsp), %r13
movl 0x10(%rsp), %r15d
je 0x4fea
testl %esi, %esi
jne 0x5011
cmpb $0x0, 0xb(%rsp)
jne 0x5011
movq %rbx, %rdi
movl %r13d, %esi
movl %r15d, %edx
callq 0x531c
movq %rbx, %rdi
movl %r12d, %esi
movl %r15d, %edx
callq 0x4c16
movl 0x14(%rsp), %esi
movq 0x188(%rbx), %rax
movl $0x40, 0x4(%rax)
cmpl $0x6, %r15d
je 0x502e
testl %r15d, %r15d
jne 0x514f
cmpl $0x3, %esi
jne 0x50d7
movq %rbx, %rdi
movl %r12d, %esi
movl %r15d, %edx
callq 0x531c
movl %ebp, %r15d
shrl $0xc, %r15d
andl $0x3, %r15d
leal 0x1(%r15), %eax
addl $0x7, %r15d
cmpq $0x1, %r14
cmovnel %eax, %r15d
movq %rbx, %rdi
movl %r12d, %esi
movl %r15d, %edx
callq 0x4c16
movq 0x188(%rbx), %rax
movl 0x40(%rax,%r14,4), %ecx
movslq 0x10(%rsp), %rdx
imulq $0x2aaaaaab, %rdx, %rdx # imm = 0x2AAAAAAB
movq %rdx, %rsi
shrq $0x3f, %rsi
shrq $0x20, %rdx
addl %esi, %edx
addl %edx, %edx
leal (%rdx,%rdx,2), %edx
movl 0x10(%rsp), %esi
subl %edx, %esi
movslq %esi, %rdx
leaq 0x60b8(%rip), %rsi      # 0xb160
subl 0x4(%rsi,%rdx,4), %ecx
movl %ecx, 0x40(%rax,%r14,4)
imulq $0x2aaaaaab, %r15, %rdx # imm = 0x2AAAAAAB
shrq $0x20, %rdx
addl %edx, %edx
leal (%rdx,%rdx,2), %edx
subl %edx, %r15d
shll $0x2, %r15d
addl 0x4(%r15,%rsi), %ecx
movl 0x10(%rsp), %r15d
movl %ecx, 0x40(%rax,%r14,4)
testq %r14, %r14
jne 0x510a
movl %r12d, %eax
subl %r13d, %eax
cmpl $0x10, %eax
jne 0x510a
leal -0x8(%r12), %eax
leaq 0x7fed(%rip), %rcx      # 0xd0e0
movq 0x130(%rbx), %rdx
testq %rdx, (%rcx,%rax,8)
je 0x510a
movq 0x188(%rbx), %rcx
movl %eax, 0x4(%rcx)
cmpl $0x1, %r14d
jne 0x5142
movl %r13d, %eax
subl %r12d, %eax
cmpl $0x10, %eax
jne 0x5142
leal 0x8(%r12), %eax
leaq 0x7fb9(%rip), %rcx      # 0xd0e0
movq 0x100(%rbx), %rdx
testq %rdx, 0x200(%rcx,%rax,8)
je 0x5142
movq 0x188(%rbx), %rcx
movl %eax, 0x4(%rcx)
movq 0x188(%rbx), %rax
movl $0x0, (%rax)
movq 0x188(%rbx), %rsi
movl 0x8(%rsi), %eax
testl %eax, %eax
je 0x5210
cmpl $0x5, %r15d
je 0x5177
cmpl $0xb, %r15d
jne 0x5181
movl $0xfffffff3, %ecx       # imm = 0xFFFFFFF3
jmp 0x520b
movl $0xfffffffc, %ecx       # imm = 0xFFFFFFFC
jmp 0x520b
movl %r15d, %edx
xorl $0x3, %edx
movl $0xfffffffd, %ecx       # imm = 0xFFFFFFFD
movl %r13d, %edi
orl %edx, %edi
je 0x520b
movl %r13d, %edi
xorl $0x7, %edi
orl %edx, %edi
jne 0x51a4
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
jmp 0x520b
xorl $0x9, %r15d
movl %r13d, %edx
xorl $0x38, %edx
orl %r15d, %edx
jne 0x51ba
movl $0xfffffff7, %ecx       # imm = 0xFFFFFFF7
jmp 0x520b
xorl $0x3f, %r13d
orl %r15d, %r13d
jne 0x51ca
movl $0xfffffffb, %ecx       # imm = 0xFFFFFFFB
jmp 0x520b
movl 0xc(%rsp), %edx
xorl $0x3, %edx
movl %r12d, %edi
orl %edx, %edi
je 0x520b
movl %r12d, %ecx
xorl $0x7, %ecx
orl %edx, %ecx
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
je 0x520b
movl 0xc(%rsp), %edi
xorl $0x9, %edi
movl %r12d, %ecx
xorl $0x38, %ecx
orl %edi, %ecx
movl $0xfffffff7, %ecx       # imm = 0xFFFFFFF7
je 0x520b
xorl $0x3f, %r12d
orl %edi, %r12d
movl $0xfffffffb, %ecx       # imm = 0xFFFFFFFB
jne 0x5210
andl %ecx, %eax
movl %eax, 0x8(%rsi)
xorl %eax, %eax
testq %r14, %r14
sete %al
incl 0x178(%rbx)
incq 0x180(%rbx)
movl %eax, 0x17c(%rbx)
movl %ebp, 0x10(%rsi)
movq %rbx, %rdi
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4b02