// File: /workspace/github_cpp_makefile_star2_O2/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), %r13d
xorl %eax, %eax
testl %r13d, %r13d
sete %al
movl %eax, 0x17c(%rdi)
movl %esi, %ebp
andl $0x3f, %ebp
movl %esi, %r15d
shrl $0x6, %r15d
andl $0x3f, %r15d
decl 0x178(%rdi)
shrl $0xe, %r12d
andl $0x3, %r12d
cmpl $0x2, %r12d
jne 0x4faa
xorl %eax, %eax
testl %r13d, %r13d
pushq $0x38
popq %rcx
cmovnel %eax, %ecx
pushq $0xb
popq %r14
pushq $0x5
popq %rax
cmovnel %eax, %r14d
movl %r13d, (%rsp)
pushq $0x9
popq %r13
pushq $0x3
popq %rdx
cmovnel %edx, %r13d
pushq $0x3a
popq %rsi
pushq $0x2
popq %rdi
cmovel %esi, %edi
pushq $0x3b
popq %r8
cmovnel %edx, %r8d
pushq $0x3e
popq %rsi
pushq $0x6
popq %rdx
cmovnel %edx, %esi
movl %ebp, 0x4(%rsp)
pushq $0x3d
popq %rbp
cmovnel %eax, %ebp
cmpl %ecx, %r15d
cmovel %edi, %esi
cmovel %r8d, %ebp
movq %rbx, %rdi
movl %r14d, %edx
callq 0x4e68
movq %rbx, %rdi
movl %ebp, %esi
movl 0x4(%rsp), %ebp
movl %r13d, %edx
callq 0x4e68
movq %rbx, %rdi
movl %ebp, %esi
movl %r14d, %edx
callq 0x47de
movq %rbx, %rdi
movl %r15d, %esi
movl %r13d, %edx
movl (%rsp), %r13d
callq 0x47de
movl %r15d, %r14d
cmpl $0x2, %r12d
je 0x502c
movq 0x188(%rbx), %rax
cmpl $0xc, 0xc(%rax)
je 0x502c
movl (%rbx,%r14,4), %edx
movq %rbx, %rdi
cmpl $0x3, %r12d
jne 0x5001
movl %r15d, %esi
callq 0x4e68
movq 0x188(%rbx), %rax
movl 0xc(%rax), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x47de
xorl %edx, %edx
testl %r13d, %r13d
pushq $0x6
popq %rax
cmovel %eax, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x47de
jmp 0x506f
movl %ebp, %esi
callq 0x47de
movl (%rbx,%r14,4), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4e68
movq 0x188(%rbx), %rax
movl 0xc(%rax), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x47de
movl %r12d, %eax
leaq 0x22f6(%rip), %rcx      # 0x732c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x188(%rbx), %rax
cmpl $0xc, 0xc(%rax)
jne 0x50e7
movl (%rbx,%r14,4), %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x47de
movl (%rbx,%r14,4), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4e68
jmp 0x50e7
movq 0x188(%rbx), %rax
cmpl $0xc, 0xc(%rax)
jne 0x50e7
movl (%rbx,%r14,4), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4e68
xorl %edx, %edx
testl %r13d, %r13d
pushq $0x6
popq %rax
cmovel %eax, %edx
movq %rbx, %rdi
movl %ebp, %esi
jmp 0x50e2
movl %ebp, %r12d
xorl %ebp, %ebp
xorl %eax, %eax
testl %r13d, %r13d
pushq $0x6
popq %rcx
cmovnel %ecx, %r13d
sete %al
cmovel %ecx, %ebp
shll $0x4, %eax
leal (%rax,%r15), %r14d
addl $-0x8, %r14d
movq %rbx, %rdi
movl %r15d, %esi
movl %ebp, %edx
callq 0x4e68
movq %rbx, %rdi
movl %r12d, %esi
movl %ebp, %edx
callq 0x47de
movq %rbx, %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x47de
movq 0x188(%rbx), %rax
movq 0x18(%rax), %rax
movq %rax, 0x188(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq