// File: /workspace/github_cpp_makefile_star2_O1/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), %ebp
xorl %eax, %eax
testl %ebp, %ebp
sete %al
movl %eax, 0x17c(%rdi)
movl %esi, %eax
andl $0x3f, %eax
movl %eax, (%rsp)
movl %esi, %r15d
shrl $0x6, %r15d
andl $0x3f, %r15d
shrl $0xe, %r12d
andl $0x3, %r12d
decl 0x178(%rdi)
cmpl $0x2, %r12d
jne 0x5454
xorl %eax, %eax
testl %ebp, %ebp
movl $0x38, %ecx
cmovnel %eax, %ecx
movl %ebp, 0x4(%rsp)
movl $0xb, %ebp
movl $0x5, %eax
cmovnel %eax, %ebp
movl $0x9, %r13d
movl $0x3, %edx
cmovnel %edx, %r13d
movl $0x3a, %esi
movl $0x2, %edi
cmovel %esi, %edi
movl $0x3b, %r8d
cmovnel %edx, %r8d
movl $0x3e, %edx
movl $0x6, %esi
cmovel %edx, %esi
movl $0x3d, %r14d
cmovnel %eax, %r14d
cmpl %ecx, %r15d
cmovel %edi, %esi
cmovel %r8d, %r14d
movq %rbx, %rdi
movl %ebp, %edx
callq 0x531c
movq %rbx, %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x531c
movq %rbx, %rdi
movl (%rsp), %esi
movl %ebp, %edx
movl 0x4(%rsp), %ebp
callq 0x4c16
movq %rbx, %rdi
movl %r15d, %esi
movl %r13d, %edx
callq 0x4c16
movl %r12d, %r14d
cmpl $0x2, %r12d
je 0x54f2
movq 0x188(%rbx), %rax
cmpl $0xc, 0xc(%rax)
je 0x54f2
movl %r15d, %r13d
movl (%rbx,%r13,4), %edx
movq %rbx, %rdi
cmpl $0x3, %r12d
jne 0x54c6
movl %r15d, %esi
callq 0x531c
movq 0x188(%rbx), %rax
movl 0xc(%rax), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4c16
xorl %eax, %eax
testl %ebp, %ebp
movl $0x6, %edx
cmovnel %eax, %edx
movq %rbx, %rdi
movl (%rsp), %esi
callq 0x4c16
leaq 0x2e57(%rip), %rax      # 0x8314
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movl (%rsp), %esi
callq 0x4c16
movl (%rbx,%r13,4), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x531c
movq 0x188(%rbx), %rax
movl 0xc(%rax), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x4c16
leaq 0x2e1b(%rip), %rax      # 0x8314
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq 0x188(%rbx), %rax
cmpl $0xc, 0xc(%rax)
jne 0x5530
movl %r15d, %r14d
movl (%rbx,%r14,4), %edx
movq %rbx, %rdi
movl (%rsp), %esi
callq 0x4c16
movl (%rbx,%r14,4), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x531c
cmpl $0x3, %r12d
jne 0x55b4
movq 0x188(%rbx), %rax
cmpl $0xc, 0xc(%rax)
jne 0x55b4
movl %r15d, %eax
movl (%rbx,%rax,4), %edx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x531c
xorl %eax, %eax
testl %ebp, %ebp
movl $0x6, %edx
cmovnel %eax, %edx
movq %rbx, %rdi
movl (%rsp), %esi
jmp 0x55af
movl %ebp, %r12d
xorl %ebp, %ebp
xorl %eax, %eax
testl %r12d, %r12d
movl $0x6, %ecx
cmovnel %ecx, %r12d
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 0x531c
movq %rbx, %rdi
movl (%rsp), %esi
movl %ebp, %edx
callq 0x4c16
movq %rbx, %rdi
movl %r14d, %esi
movl %r12d, %edx
callq 0x4c16
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
nop