// File: 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
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
cmpl $0x0, 0x17c(%rax)
setne %cl
xorb $-0x1, %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0x17c(%rax)
movl 0x17c(%rax), %eax
movl %eax, -0x10(%rbp)
cmpl $0x0, -0x10(%rbp)
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x14(%rbp)
movl -0xc(%rbp), %edi
callq 0x7860
movl %eax, -0x18(%rbp)
movl -0xc(%rbp), %edi
callq 0x7870
movl %eax, -0x1c(%rbp)
movl -0xc(%rbp), %edi
callq 0x78b0
movl %eax, %ecx
movq -0x60(%rbp), %rax
movl %ecx, -0x20(%rbp)
movl 0x178(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x178(%rax)
cmpl $0x2, -0x20(%rbp)
jne 0x94ab
movl -0x10(%rbp), %edx
movl $0x38, %eax
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x10(%rbp), %edx
movl $0x3f, %eax
movl $0x7, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x28(%rbp)
movl -0x10(%rbp), %edx
movl $0xb, %eax
movl $0x5, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x2c(%rbp)
movl -0x10(%rbp), %edx
movl $0x9, %eax
movl $0x3, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x30(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jne 0x9441
movq -0x60(%rbp), %rdi
movl -0x10(%rbp), %edx
movl $0x3a, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x34(%rbp)
movl -0x10(%rbp), %edx
movl $0x3b, %eax
movl $0x3, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x38(%rbp)
movl -0x34(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x38(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x8600
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x8600
jmp 0x94a9
movq -0x60(%rbp), %rdi
movl -0x10(%rbp), %edx
movl $0x3e, %eax
movl $0x6, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x3c(%rbp)
movl -0x10(%rbp), %edx
movl $0x3d, %eax
movl $0x5, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x40(%rbp)
movl -0x3c(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x40(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x8600
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x8600
jmp 0x94ab
movq -0x60(%rbp), %rax
movq 0x188(%rax), %rax
cmpl $0xc, 0xc(%rax)
je 0x9558
cmpl $0x2, -0x20(%rbp)
je 0x9558
cmpl $0x3, -0x20(%rbp)
jne 0x951c
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x1c(%rbp), %eax
movl (%rdi,%rax,4), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq 0x188(%rdi), %rax
movl 0xc(%rax), %edx
callq 0x8600
movq -0x60(%rbp), %rdi
movl -0x10(%rbp), %edx
movl $0x6, %eax
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x44(%rbp)
movl -0x18(%rbp), %esi
movl -0x44(%rbp), %edx
callq 0x8600
jmp 0x9556
movq -0x60(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %eax
movl (%rdi,%rax,4), %edx
callq 0x8600
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x1c(%rbp), %eax
movl (%rdi,%rax,4), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq 0x188(%rdi), %rax
movl 0xc(%rax), %edx
callq 0x8600
jmp 0x9558
cmpl $0x1, -0x20(%rbp)
jne 0x95d7
movl -0x1c(%rbp), %eax
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x10(%rbp)
jne 0x9575
movl -0x48(%rbp), %eax
addl $-0x8, %eax
movl %eax, -0x64(%rbp)
jmp 0x957e
movl -0x48(%rbp), %eax
addl $0x8, %eax
movl %eax, -0x64(%rbp)
movq -0x60(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x10(%rbp), %edx
movl $0x6, %eax
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x50(%rbp)
movl -0x10(%rbp), %edx
xorl %eax, %eax
movl $0x6, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x54(%rbp)
movl -0x48(%rbp), %esi
movl -0x50(%rbp), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x50(%rbp), %edx
callq 0x8600
movq -0x60(%rbp), %rdi
movl -0x4c(%rbp), %esi
movl -0x54(%rbp), %edx
callq 0x8600
cmpl $0x0, -0x20(%rbp)
jne 0x9612
movq -0x60(%rbp), %rax
movq 0x188(%rax), %rax
cmpl $0xc, 0xc(%rax)
jne 0x9612
movq -0x60(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x1c(%rbp), %eax
movl (%rdi,%rax,4), %edx
callq 0x8600
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x1c(%rbp), %eax
movl (%rdi,%rax,4), %edx
callq 0x9200
cmpl $0x3, -0x20(%rbp)
jne 0x965d
movq -0x60(%rbp), %rax
movq 0x188(%rax), %rax
cmpl $0xc, 0xc(%rax)
jne 0x965d
movq -0x60(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x1c(%rbp), %eax
movl (%rdi,%rax,4), %edx
callq 0x9200
movq -0x60(%rbp), %rdi
movl -0x10(%rbp), %edx
movl $0x6, %eax
xorl %ecx, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x58(%rbp)
movl -0x18(%rbp), %esi
movl -0x58(%rbp), %edx
callq 0x8600
movq -0x60(%rbp), %rax
movq 0x188(%rax), %rcx
movq 0x18(%rcx), %rcx
movq %rcx, 0x188(%rax)
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax)