// File: /workspace/github_cpp_makefile_star2_O2/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, %r14d
movq %rdi, %r13
cmpl $0x150d6, %esi          # imm = 0x150D6
jne 0x4867
movq %r13, %rdi
callq 0x4db0
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), %ecx
xorl %eax, %eax
movq %rcx, 0x18(%rsp)
testq %rcx, %rcx
sete %al
movl %r14d, %ebp
andl $0x3f, %ebp
movl %r14d, %edx
shrl $0x6, %edx
andl $0x3f, %edx
movl %r14d, 0x14(%rsp)
shrl $0xe, %r14d
andl $0x3, %r14d
movl (%r13,%rbp,4), %r9d
leaq 0x750f(%rip), %rcx      # 0xbde0
movq (%rcx,%rdx,8), %rcx
testq %rcx, 0x160(%r13,%rax,8)
setne %al
cmpl $0x2, %r14d
setne %cl
andb %al, %cl
cmpb $0x1, %cl
movq %rdx, 0x20(%rsp)
jne 0x48fa
movl (%r13,%rdx,4), %eax
jmp 0x4905
movl $0xc, 0xc(%r15)
pushq $0xc
popq %rax
movl %eax, 0x10(%rsp)
cmpl $0x2, %r14d
movq %rbp, 0x28(%rsp)
movl %r9d, 0xc(%rsp)
movb %cl, 0xb(%rsp)
jne 0x49ff
xorl %eax, %eax
xorl %esi, %esi
cmpq $0x0, 0x18(%rsp)
pushq $0x38
popq %rdx
cmovel %eax, %edx
movl %edx, 0x3c(%rsp)
pushq $0x5
popq %rax
pushq $0xb
popq %r8
cmovel %eax, %r8d
movl %r8d, 0x34(%rsp)
pushq $0x3
popq %rcx
pushq $0x9
popq %rdx
cmovel %ecx, %edx
movl %edx, 0x30(%rsp)
pushq $0x3e
popq %rdi
pushq $0x6
popq %rdx
cmovel %edx, %edi
movl %edi, 0x38(%rsp)
pushq $0x3d
popq %rbx
cmovel %eax, %ebx
pushq $0x2
popq %rax
pushq $0x3a
popq %r12
cmovel %eax, %r12d
movq %r13, %r15
pushq $0x3b
popq %r13
cmovel %ecx, %r13d
sete %sil
movq %rsi, 0x40(%rsp)
movq %r15, %rdi
movl %ebp, %esi
movl %r8d, %edx
callq 0x4e68
movq %r15, %rdi
movq 0x20(%rsp), %rbp
movl %ebp, %esi
movl 0x30(%rsp), %edx
callq 0x4e68
cmpl 0x3c(%rsp), %ebp
movq 0x28(%rsp), %rbp
cmovnel 0x38(%rsp), %r12d
cmovnel %ebx, %r13d
movq %r15, %rdi
movl %r12d, %esi
movl 0x34(%rsp), %edx
callq 0x47de
movq %r15, %rdi
movl %r13d, %esi
movq %r15, %r13
movl 0x30(%rsp), %edx
callq 0x47de
movb 0xb(%rsp), %cl
movl 0xc(%rsp), %r9d
movq 0x40(%rsp), %rax
leal (%rax,%rax,8), %eax
addl $-0xd, %eax
movq 0x188(%r15), %r15
andl %eax, 0x8(%r15)
movl $0xc, 0xc(%r15)
testb %cl, %cl
je 0x4ad6
xorl %ebx, %ebx
cmpq $0x0, 0x18(%rsp)
setne %bl
incl 0xebb18(%rip)           # 0xf0530
movl 0x10(%rsp), %edx
movl %edx, 0xc(%r15)
movq %r13, %rdi
movq 0x20(%rsp), %r15
movl %r15d, %esi
movl %r9d, %r12d
callq 0x4e68
movq %r13, %rdi
movl %ebp, %esi
movl %r12d, %edx
callq 0x4e68
movq %r13, %rdi
movl %r15d, %esi
movl %r12d, %edx
callq 0x47de
movq 0x188(%r13), %rax
andl $0x0, (%rax)
movq 0x160(%r13,%rbx,8), %r15
movq %r15, %rdi
callq 0x2801
movl %eax, %ebp
movq %r15, %rdi
callq 0x2801
cmpl %eax, %ebp
jge 0x4a99
movq %r13, %rdi
callq 0x4db0
movq %r15, %rdi
callq 0x341d
movq 0x6523(%rip), %rdi      # 0xafb0
leaq 0x28f9(%rip), %rsi      # 0x738d
callq 0x2170
xorl %ecx, %ecx
cmpq $0x0, 0x18(%rsp)
sete %cl
movq 0x188(%r13), %r15
movl 0x10(%rsp), %eax
cltd
pushq $0x6
popq %rsi
idivl %esi
movslq %edx, %rax
leaq 0x66a1(%rip), %rdx      # 0xb160
movl 0x4(%rdx,%rax,4), %eax
subl %eax, 0x40(%r15,%rcx,4)
movq 0x28(%rsp), %rbp
movl 0xc(%rsp), %r9d
movb 0xb(%rsp), %cl
cmpl $0x1, %r14d
jne 0x4b56
xorl %r14d, %r14d
xorl %eax, %eax
movq 0x18(%rsp), %rcx
testq %rcx, %rcx
sete %r14b
setne %al
movl 0x10(%rsp), %ecx
movl %ecx, 0xc(%r15)
movl 0x4(%r15), %r15d
shll $0x4, %eax
leal (%rax,%r15), %r12d
addl $-0x8, %r12d
movq %r13, %rdi
movl %ebp, %esi
movl %r9d, %edx
callq 0x4e68
movl (%r13,%r12,4), %edx
movq %r13, %rdi
movl %r12d, %esi
callq 0x4e68
movq %r13, %rdi
movl %r15d, %esi
movl 0xc(%rsp), %edx
callq 0x47de
movl 0xc(%rsp), %r9d
movq 0x188(%r13), %r15
andl $0x0, (%r15)
leaq 0x6616(%rip), %rax      # 0xb160
movl 0x4(%rax), %eax
subl %eax, 0x40(%r15,%r14,4)
xorl %ebp, %ebp
jmp 0x4b6d
cmpl $0x3, %r14d
sete %bpl
je 0x4b65
testl %r14d, %r14d
jne 0x4b6d
testb %cl, %cl
je 0x4cf6
movl 0x14(%rsp), %ebx
movq 0x20(%rsp), %r14
movl $0x40, 0x4(%r15)
cmpl $0x6, %r9d
je 0x4b8d
testl %r9d, %r9d
jne 0x4c72
testb %bpl, %bpl
je 0x4c06
movq %r13, %rdi
movl %r14d, %esi
movl %r9d, %edx
callq 0x4e68
movl %ebx, %ebp
shrl $0xc, %ebp
andl $0x3, %ebp
leal 0x1(%rbp), %eax
addl $0x7, %ebp
movq 0x18(%rsp), %r12
cmpq $0x1, %r12
cmovnel %eax, %ebp
movq %r13, %rdi
movl %r14d, %esi
movl %ebp, %edx
callq 0x47de
movl 0xc(%rsp), %r9d
movq 0x188(%r13), %r15
movl 0x40(%r15,%r12,4), %eax
movl %r9d, %ecx
subl $0x6, %ecx
cmovbl %r9d, %ecx
movslq %ecx, %rcx
leaq 0x6574(%rip), %rdx      # 0xb160
subl 0x4(%rdx,%rcx,4), %eax
movl %ebp, %ecx
subl $0x6, %ecx
cmovbl %ebp, %ecx
movl %eax, 0x40(%r15,%r12,4)
addl 0x4(%rdx,%rcx,4), %eax
movl %eax, 0x40(%r15,%r12,4)
cmpq $0x0, 0x18(%rsp)
movq 0x28(%rsp), %r8
jne 0x4c3a
movl %r14d, %eax
subl %r8d, %eax
cmpl $0x10, %eax
jne 0x4c3a
leal -0x8(%r14), %eax
leaq 0x84b7(%rip), %rcx      # 0xd0e0
movq 0x130(%r13), %rdx
testq %rdx, (%rcx,%rax,8)
je 0x4c3a
movl %eax, 0x4(%r15)
cmpl $0x1, 0x18(%rsp)
jne 0x4c6c
movl %r8d, %eax
subl %r14d, %eax
cmpl $0x10, %eax
jne 0x4c6c
leal 0x8(%r14), %eax
leaq 0x8489(%rip), %rcx      # 0xd0e0
movq 0x100(%r13), %rdx
testq %rdx, 0x200(%rcx,%rax,8)
je 0x4c6c
movl %eax, 0x4(%r15)
andl $0x0, (%r15)
jmp 0x4c77
movq 0x28(%rsp), %r8
movl 0x8(%r15), %eax
testl %eax, %eax
je 0x4c98
cmpl $0x5, %r9d
je 0x4c8f
cmpl $0xb, %r9d
jne 0x4cd5
pushq $-0xd
jmp 0x4c91
pushq $-0x4
popq %rcx
andl %ecx, %eax
movl %eax, 0x8(%r15)
xorl %eax, %eax
cmpq $0x0, 0x18(%rsp)
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 0x470a
movl %r9d, %edx
xorl $0x3, %edx
pushq $-0x3
popq %rcx
movl %r8d, %esi
orl %edx, %esi
je 0x4c92
movl %r8d, %esi
xorl $0x7, %esi
pushq $-0x2
popq %rdi
orl %edx, %esi
jne 0x4d2f
movl %edi, %ecx
jmp 0x4c92
movq %r13, %rdi
movq 0x28(%rsp), %rsi
movl %r9d, %edx
callq 0x4e68
movq %r13, %rdi
movq 0x20(%rsp), %r14
movl %r14d, %esi
movl 0xc(%rsp), %edx
callq 0x47de
movl 0xc(%rsp), %r9d
movq 0x188(%r13), %r15
movl 0x14(%rsp), %ebx
jmp 0x4b76
xorl $0x9, %r9d
movl %r8d, %edx
xorl $0x38, %edx
pushq $-0x9
popq %rsi
orl %r9d, %edx
jne 0x4d48
movl %esi, %ecx
jmp 0x4c92
xorl $0x3f, %r8d
pushq $-0x5
popq %rdx
orl %r9d, %r8d
jne 0x4d5b
movl %edx, %ecx
jmp 0x4c92
movl 0x10(%rsp), %r8d
xorl $0x3, %r8d
movl %r14d, %r9d
orl %r8d, %r9d
je 0x4c92
movl %r14d, %ecx
xorl $0x7, %ecx
orl %r8d, %ecx
movl %edi, %ecx
je 0x4c92
movl 0x10(%rsp), %r8d
xorl $0x9, %r8d
movl %r14d, %ecx
xorl $0x38, %ecx
orl %r8d, %ecx
movl %esi, %ecx
je 0x4c92
xorl $0x3f, %r14d
orl %r8d, %r14d
movl %edx, %ecx
jne 0x4c98
jmp 0x4c92
nop