// File: jswaff[P]prophet3/src/search.cpp
// Function: qsearch(position*, int, int, int, int, bool, search_stats*, unsigned long long*, undo*)
int32 qsearch(position *pos,int32 alpha,int32 beta,int32 ply,int32 qply,
        bool incheck,search_stats *stats,move *startp,undo *undo_stack) {

    assert(alpha < beta);

    // time check
    if (!analysis_mode && nodes_last_time_check >= 10000) {
        if (milli_timer() >= stop_time) {
            abort_search = true;
            printd("# Aborting qsearch on time...\n");
            return 0;
        }
        nodes_last_time_check = 0;
    } else {
        nodes_last_time_check++;
    }

    // TODO: try hash probe

    int32 stand_pat = eval(pos,false);
    assert(test_eval_symmetry(stand_pat,pos));

    if (stand_pat > alpha) {
        if (stand_pat >= beta) {
            return beta;
        }
        // our static evaluation will serve as the lower bound
        alpha = stand_pat;
    }


    if (ply >= MAX_PLY) {
        return alpha;
    }

    // get ready to search
    uint32 moves_searched=0,moves_pruned=0;
    move_order_dto mo_dto = build_move_order_dto(startp,0,0,0,0,true);

    move *mp;
    //bool just_caps_promos = true; //!incheck || qply>=3;
    while (next(pos,&mp,&mo_dto)) {
        assert(good_move(pos,*mp));
        assert(is_capture(*mp) || get_promopiece(*mp));
        /*if (just_caps_promos && !is_capture(*mp) && !get_promopiece(*mp)) {
            continue;
        }*/

        apply_move(pos,*mp,undo_stack);
        if (in_check(pos,opposite_player(pos->player))) {
            undo_last_move(pos,undo_stack);
            continue;
        }

        // can this capture possibly raise alpha?
        if (!incheck && !get_promopiece(*mp)
                && (piece_val(get_captured_piece(*mp)) + pawn_val*2 + stand_pat) < alpha) {
            undo_last_move(pos,undo_stack);
            moves_pruned++;
            continue;
        }

        // if not a promising capture just skip
        if (!incheck && !get_promopiece(*mp)
                && piece_val(get_piece(*mp)) > piece_val(get_captured_piece(*mp))
                && see(pos,*mp) < 0) {
            undo_last_move(pos,undo_stack);
            moves_pruned++;
            continue;
        }

        bool gives_check = false; // in_check(pos,pos->player);
        stats->qnodes++; // avoids double counting leaf nodes
        int32 score = -qsearch(pos,-beta,-alpha,ply+1,qply+1,gives_check,stats,mo_dto.endp,undo_stack);
        moves_searched++;

        // restore the position
        undo_last_move(pos,undo_stack);

        if (abort_search) {
            return 0;
        }

        if (score > alpha) {
            if (score >= beta) {
                return beta;
            }
            alpha = score;
        }
    }

    assert(moves_searched+moves_pruned==num_moves(pos,true,false));

    return alpha;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movb %r9b, %al
movq 0x20(%rbp), %r9
movq 0x18(%rbp), %r9
movq 0x10(%rbp), %r9
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x1151a
jmp 0x11539
leaq 0x26b0a(%rip), %rdi     # 0x3802b
leaq 0x26971(%rip), %rsi     # 0x37e99
movl $0x147, %edx            # imm = 0x147
leaq 0x26bb1(%rip), %rcx     # 0x380e5
callq 0x20c0
testb $0x1, 0x8765c0(%rip)    # 0x887b00
jne 0x1158a
cmpq $0x2710, 0x8765ab(%rip) # imm = 0x2710
jb 0x1158a
callq 0x14080
cmpl 0x876596(%rip), %eax    # 0x887af0
jl 0x1157d
movb $0x1, 0x87659e(%rip)    # 0x887b01
leaq 0x26bd7(%rip), %rdi     # 0x38141
movb $0x0, %al
callq 0x8db0
movl $0x0, -0x4(%rbp)
jmp 0x11913
movq $0x0, 0x876570(%rip) # 0x887af8
jmp 0x1159c
movq 0x876567(%rip), %rax    # 0x887af8
addq $0x1, %rax
movq %rax, 0x87655c(%rip)    # 0x887af8
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x7630
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x1af60
testb $0x1, %al
jne 0x115bc
jmp 0x115be
jmp 0x115dd
leaq 0x26b9b(%rip), %rdi     # 0x38160
leaq 0x268cd(%rip), %rsi     # 0x37e99
movl $0x158, %edx            # imm = 0x158
leaq 0x26b0d(%rip), %rcx     # 0x380e5
callq 0x20c0
movl -0x28(%rbp), %eax
cmpl -0x14(%rbp), %eax
jle 0x115fe
movl -0x28(%rbp), %eax
cmpl -0x18(%rbp), %eax
jl 0x115f8
movl -0x18(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x11913
movl -0x28(%rbp), %eax
movl %eax, -0x14(%rbp)
cmpl $0x64, -0x1c(%rbp)
jl 0x1160f
movl -0x14(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x11913
movl $0x0, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
movq 0x18(%rbp), %rsi
leaq -0x70(%rbp), %rdi
xorl %eax, %eax
movl %eax, %r9d
movq %r9, %rdx
movq %r9, %rcx
movq %r9, %r8
movl $0x1, (%rsp)
callq 0x10270
movq -0x10(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0xc670
testb $0x1, %al
jne 0x11659
jmp 0x118c4
movq -0x10(%rbp), %rdi
movq -0x78(%rbp), %rax
movq (%rax), %rsi
callq 0xcef0
testb $0x1, %al
jne 0x1166f
jmp 0x11671
jmp 0x11690
leaq 0x2691d(%rip), %rdi     # 0x37f95
leaq 0x2681a(%rip), %rsi     # 0x37e99
movl $0x16e, %edx            # imm = 0x16E
leaq 0x26a5a(%rip), %rcx     # 0x380e5
callq 0x20c0
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0xab20
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x81(%rbp)
jne 0x116c3
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0xaae0
cmpl $0x0, %eax
setne %al
movb %al, -0x81(%rbp)
movb -0x81(%rbp), %al
testb $0x1, %al
jne 0x116cf
jmp 0x116d1
jmp 0x116f0
leaq 0x26aaa(%rip), %rdi     # 0x38182
leaq 0x267ba(%rip), %rsi     # 0x37e99
movl $0x16f, %edx            # imm = 0x16F
leaq 0x269fa(%rip), %rcx     # 0x380e5
callq 0x20c0
movq -0x10(%rbp), %rdi
movq -0x78(%rbp), %rax
movq (%rax), %rsi
movq 0x20(%rbp), %rdx
callq 0x3620
movq -0x10(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
movl 0x138(%rax), %edi
callq 0x14130
movq -0x90(%rbp), %rdi
movl %eax, %esi
callq 0xfc10
testb $0x1, %al
jne 0x11732
jmp 0x11744
movq -0x10(%rbp), %rdi
movq 0x20(%rbp), %rsi
callq 0x39a0
jmp 0x1163f
testb $0x1, -0x21(%rbp)
jne 0x11796
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0xaae0
cmpl $0x0, %eax
jne 0x11796
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0xab00
movl %eax, %edi
callq 0x68c0
addl $0xc8, %eax
addl -0x28(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x11796
movq -0x10(%rbp), %rdi
movq 0x20(%rbp), %rsi
callq 0x39a0
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x1163f
testb $0x1, -0x21(%rbp)
jne 0x11815
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0xaae0
cmpl $0x0, %eax
jne 0x11815
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0xaac0
movl %eax, %edi
callq 0x68c0
movl %eax, -0x94(%rbp)
movq -0x78(%rbp), %rax
movq (%rax), %rdi
callq 0xab00
movl %eax, %edi
callq 0x68c0
movl %eax, %ecx
movl -0x94(%rbp), %eax
cmpl %ecx, %eax
jle 0x11815
movq -0x10(%rbp), %rdi
movq -0x78(%rbp), %rax
movq (%rax), %rsi
callq 0x11f10
cmpl $0x0, %eax
jge 0x11815
movq -0x10(%rbp), %rdi
movq 0x20(%rbp), %rsi
callq 0x39a0
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x1163f
movb $0x0, -0x79(%rbp)
movq 0x10(%rbp), %rax
movq 0x20(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rdi
xorl %esi, %esi
subl -0x18(%rbp), %esi
xorl %edx, %edx
subl -0x14(%rbp), %edx
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
movl -0x20(%rbp), %r8d
addl $0x1, %r8d
movb -0x79(%rbp), %r9b
movq 0x10(%rbp), %r11
movq -0x40(%rbp), %r10
movq 0x20(%rbp), %rax
andb $0x1, %r9b
movzbl %r9b, %r9d
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x114e0
movl %eax, %ecx
xorl %eax, %eax
subl %ecx, %eax
movl %eax, -0x80(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
movq 0x20(%rbp), %rsi
callq 0x39a0
testb $0x1, 0x87626b(%rip)    # 0x887b01
je 0x118a1
movl $0x0, -0x4(%rbp)
jmp 0x11913
movl -0x80(%rbp), %eax
cmpl -0x14(%rbp), %eax
jle 0x118bf
movl -0x80(%rbp), %eax
cmpl -0x18(%rbp), %eax
jl 0x118b9
movl -0x18(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x11913
movl -0x80(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x1163f
movl -0x2c(%rbp), %eax
addl -0x30(%rbp), %eax
movl %eax, -0x98(%rbp)
movq -0x10(%rbp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x14c80
movl %eax, %ecx
movl -0x98(%rbp), %eax
cmpl %ecx, %eax
jne 0x118ee
jmp 0x1190d
leaq 0x268b4(%rip), %rdi     # 0x381a9
leaq 0x2659d(%rip), %rsi     # 0x37e99
movl $0x19f, %edx            # imm = 0x19F
leaq 0x267dd(%rip), %rcx     # 0x380e5
callq 0x20c0
movl -0x14(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
nop