// File: /workspace/github_cpp_makefile_star2_O3/bjohnsonfl[P]Overhead-Chess-Engine-/position.cpp
// Function: position::undo_move(move)
void position::undo_move (move m)
{
    sideToPlay = player(!sideToPlay);
    player us = sideToPlay;
    player them = player(!us);
    square from = source_sq(m);
    square to = destination_sq(m);
    moveFlag flag = move_flag(m);
    --ply;
    //castling
    //capturing
    //promoting
    //enpassent
    //update pieces
    
    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(newKingSq, king);
            remove_piece(newRookSq, rook);
            place_piece(from, king);
            place_piece(to, rook);
            
            
            
        }
        else
        {
            square newKingSq =  us == white ? g1 : g8;
            square newRookSq =  us == white ? f1 : f8;
            remove_piece(newKingSq, king);
            remove_piece(newRookSq, rook);
            place_piece(from, king);
            place_piece(to, rook);
            
        }
    }
    
    //not all promotions are captures and not all captures are promotions
    
    //captures
    if((state->captured != not_piece) && !(flag == castling))
    {
        if(flag == promoting)
        {
            remove_piece(to, board[to]);
            place_piece(to, state -> captured);
            piece pawn = us == white ?  w_pawn : b_pawn;
            place_piece(from, pawn);
            
        }
        else
        {
            place_piece(from, board[to]);
            remove_piece(to, board[to]);
            place_piece(to, state -> captured);
        
        }
    }
    if(flag == enPass)
    {
      
        square enPsq = to;
        square capturedPawn = us == white ? square(enPsq + south) : square(enPsq + nort);
        piece pawn = us == white ?  w_pawn : b_pawn;
        piece theirPawn = us == white ?  b_pawn : w_pawn;
        remove_piece(enPsq, pawn);
        place_piece(from, pawn);
        place_piece(capturedPawn, theirPawn);
        
         
    }
    
    if((flag == regular) && (state->captured == not_piece))
    {
        place_piece(from, board[to]);
        remove_piece(to, board[to]);
    }
    
    if( (flag == promoting) && (state->captured == not_piece)){
        remove_piece(to, board[to]);
        piece pawn = us == white ?  w_pawn : b_pawn;
        place_piece(from, pawn);
        
    }
    state = state -> prev;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %esi, %r12d
movq %rdi, %rbx
movl 0x17c(%rdi), %r15d
xorl %eax, %eax
testl %r15d, %r15d
sete %al
movl %eax, 0x17c(%rdi)
movl %esi, %ebp
andl $0x3f, %ebp
movl %esi, %r14d
shrl $0x6, %r14d
andl $0x3f, %r14d
shrl $0xe, %r12d
andl $0x3, %r12d
decl 0x178(%rdi)
cmpl $0x2, %r12d
jne 0x54ca
xorl %eax, %eax
testl %r15d, %r15d
movl $0x38, %ecx
cmovnel %eax, %ecx
movl $0xb, %r12d
movl $0x5, %eax
cmovnel %eax, %r12d
movl $0x9, %r15d
movl $0x3, %edx
cmovnel %edx, %r15d
movl $0x3e, %esi
movl $0x6, %edi
cmovel %esi, %edi
movl $0x3d, %r8d
cmovnel %eax, %r8d
movl $0x3a, %eax
movl $0x2, %esi
cmovel %eax, %esi
movl $0x3b, %r13d
cmovnel %edx, %r13d
cmpl %ecx, %r14d
cmovnel %edi, %esi
cmovnel %r8d, %r13d
movq %rbx, %rdi
movl %r12d, %edx
callq 0x5370
movq %rbx, %rdi
movl %r13d, %esi
movl %r15d, %edx
callq 0x5370
movq %rbx, %rdi
movl %ebp, %esi
movl %r12d, %edx
callq 0x4cb4
movq %rbx, %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0x4cb4
addq $0x188, %rbx            # imm = 0x188
movq %rbx, %r13
jmp 0x5614
leaq 0x188(%rbx), %r13
movq 0x188(%rbx), %rax
cmpl $0xc, 0xc(%rax)
je 0x5555
movl %r14d, %eax
movl (%rbx,%rax,4), %edx
movq %rbx, %rdi
cmpl $0x3, %r12d
jne 0x5523
movl %r14d, %esi
callq 0x5370
movq 0x188(%rbx), %rax
movl 0xc(%rax), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x4cb4
xorl %eax, %eax
testl %r15d, %r15d
movl $0x6, %edx
cmovnel %eax, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x4cb4
jmp 0x5598
movl %ebp, %esi
movq %rax, (%rsp)
callq 0x4cb4
movq (%rsp), %rax
movl (%rbx,%rax,4), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x5370
movq 0x188(%rbx), %rax
movl 0xc(%rax), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x4cb4
movl %r12d, %eax
leaq 0x2e4d(%rip), %rcx      # 0x83ac
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%r13), %rax
cmpl $0xc, 0xc(%rax)
jne 0x5614
movl %r14d, %r15d
movl (%rbx,%r15,4), %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x4cb4
movl (%rbx,%r15,4), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x5370
jmp 0x5614
movq (%r13), %rax
cmpl $0xc, 0xc(%rax)
jne 0x5614
movl %r14d, %eax
movl (%rbx,%rax,4), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x5370
xorl %eax, %eax
testl %r15d, %r15d
movl $0x6, %edx
cmovnel %eax, %edx
movq %rbx, %rdi
movl %ebp, %esi
jmp 0x560f
xorl %r12d, %r12d
xorl %eax, %eax
testl %r15d, %r15d
movl $0x6, %ecx
cmovnel %ecx, %r15d
sete %al
cmovel %ecx, %r12d
shll $0x4, %eax
addl %r14d, %eax
addl $-0x8, %eax
movl %eax, (%rsp)
movq %rbx, %rdi
movl %r14d, %esi
movl %r12d, %edx
callq 0x5370
movq %rbx, %rdi
movl %ebp, %esi
movl %r12d, %edx
callq 0x4cb4
movq %rbx, %rdi
movl (%rsp), %esi
movl %r15d, %edx
callq 0x4cb4
movq (%r13), %rax
movq 0x18(%rax), %rax
movq %rax, (%r13)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop