// File: /workspace/github_cpp_makefile_star2_O3/tewalds[P]pentagod/agentab.cpp
// Function: AgentAB::negamax(Board const&, short, short, int)
int16_t AgentAB::negamax(const Board & board, int16_t alpha, int16_t beta, int depth) {
	nodes_seen++;

	int won = board.won();
	if(won >= 0){
		if(won == 0)
			return SCORE_DRAW;
		if(won == board.toplay())
			return SCORE_WIN;
		return SCORE_LOSS;
	}

	if (depth <= 0){ //terminal node?
		int16_t score = -board.score();
		if(randomness){
			score <<= randomness;
			score -= rand() & ((1 << randomness)-1);
		}
		return score;
	}

	int16_t score = SCORE_LOSS;
	Move bestmove = M_RESIGN;
	Node * node;

	if(TT && (node = tt_get(board)) && node->depth >= depth){
		switch(node->flag){
		case VALID:  return node->score;
		case LBOUND: alpha = max(alpha, node->score); break;
		case UBOUND: beta  = min(beta,  node->score); break;
		default:     assert(false && "Unknown flag!");
		}
		if(alpha >= beta)
			return node->score;

		if(node->bestmove != M_UNKNOWN){
			//try the previous best move first
			bestmove = node->bestmove;
			Board n = board;
			bool move_success = n.move(bestmove);

//			if(!move_success){
//				logerr("FAIL!!!\nhash: " + to_str(board.hash()) + ", orientation: " + to_str(board.orient()) + ", state: " + board.state() + "\n");
//				logerr(node->to_s(board.orient()) + "\n");
//				logerr(board.to_s());
//			}

			assert(move_success);
			score = -negamax(n, -beta, -alpha, depth-1);
		}
	}

	if (score < beta) { // no cutoff from bestmove
		//TODO: sort moves first?

		//generate moves
		for (MoveIterator move(board); !move.done(); ++move) {
			int16_t value = -negamax(move.board(), -beta, -max(alpha, score), depth-1);
			if (score < value) {
				score = value;
				bestmove = *move;
				if (score >= beta){
					break;
				}
			}
		}
	}

	if (TT) {
		uint8_t flag = (score <= alpha ? UBOUND :
		                score >= beta  ? LBOUND : VALID);
		tt_set(Node(board.hash(), score, bestmove, depth, flag));
	}
	return score;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
incq 0x58(%rdi)
movl %r8d, %r15d
movl %ecx, %r13d
movl %edx, %ebp
movq %rsi, %r12
movq %rdi, %rbx
movb 0x1a(%rsi), %al
cmpb $-0x4, %al
jne 0x266a8
movq %r12, %rdi
callq 0xd9e4
movb %al, 0x1a(%r12)
testb %al, %al
js 0x266cf
je 0x267c5
movzbl 0x19(%r12), %ecx
movsbl %al, %eax
xorl %edx, %edx
cmpl %ecx, %eax
setne %dl
leal 0x7fff(%rdx,%rdx), %r13d
jmp 0x268c2
testl %r15d, %r15d
jle 0x267cd
cmpq $0x0, 0x38(%rbx)
movw $0x8001, %r14w          # imm = 0x8001
je 0x2672f
movq %r12, %rdi
callq 0x96fe
movq %rax, %rcx
shrq $0x11, %rax
movq 0x38(%rbx), %rsi
xorq %rcx, %rax
movq %rax, %rdx
shlq $0x1f, %rdx
xorq %rax, %rdx
movq %rdx, %rax
shrq $0x8, %rax
xorq %rdx, %rax
xorl %edx, %edx
divq 0x40(%rbx)
leaq (%rdx,%rdx,2), %rax
cmpq %rcx, (%rsi,%rax,8)
jne 0x2672f
leaq (%rsi,%rax,8), %rax
movzbl 0x10(%rax), %ecx
cmpl %r15d, %ecx
jae 0x268d4
movq %rbx, 0x8(%rsp)
movw $0x8efe, %bx            # imm = 0x8EFE
movq %r15, 0x18(%rsp)
movq %r12, 0x10(%rsp)
movl %r13d, 0x4(%rsp)
cmpw %r13w, %r14w
jge 0x26827
leaq 0x20(%rsp), %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %r12, %rsi
callq 0xd282
negl %r13d
leal -0x1(%r15), %r12d
movswl %r13w, %r15d
cmpb $0x23, 0x50(%rsp)
jg 0x2682c
cmpw %r14w, %bp
movl %r14d, %eax
cmovgl %ebp, %eax
negl %eax
movswl %ax, %ecx
movq 0x8(%rsp), %rdi
leaq 0x28(%rsp), %rsi
movl %r15d, %edx
movl %r12d, %r8d
callq 0x26674
movl %eax, %r13d
negl %r13d
cmpw %r13w, %r14w
jge 0x267b9
movzwl 0x50(%rsp), %ebx
movl %r13d, %r14d
cmpw %r13w, 0x4(%rsp)
jle 0x2682f
leaq 0x20(%rsp), %rdi
callq 0xd39c
jmp 0x2676e
xorl %r13d, %r13d
jmp 0x268c2
movzwl 0x1c(%r12), %r13d
cmpw $0xdead, %r13w          # imm = 0xDEAD
jne 0x267ec
movq %r12, %rdi
callq 0x21788
movl %eax, %r13d
movw %ax, 0x1c(%r12)
movl 0x6c(%rbx), %eax
negl %r13d
testl %eax, %eax
je 0x268c2
movl 0x68(%rbx), %ecx
shlxl %eax, %r13d, %r13d
movl %ecx, %edx
shll $0xd, %edx
xorl %ecx, %edx
movl %edx, %ecx
shrl $0x11, %ecx
xorl %edx, %ecx
movl %ecx, %edx
shll $0x5, %edx
xorl %ecx, %edx
bzhil %eax, %edx, %eax
movl %edx, 0x68(%rbx)
subl %eax, %r13d
jmp 0x268c2
movl %r14d, %r13d
jmp 0x2683e
movl %r14d, %r13d
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x2683e
callq 0x43d0
movq 0x8(%rsp), %r14
cmpq $0x0, 0x38(%r14)
je 0x268c2
cmpw 0x4(%rsp), %r13w
movq 0x10(%rsp), %rdi
movb $0x2, %cl
setl %al
subb %al, %cl
cmpw %bp, %r13w
movl $0x3, %ebp
movzbl %cl, %eax
cmovgl %eax, %ebp
callq 0x96fe
movq %rax, %rcx
shrq $0x11, %rax
movq 0x38(%r14), %rdi
movzwl %bx, %esi
xorq %rcx, %rax
movq %rax, %rdx
shlq $0x1f, %rdx
xorq %rax, %rdx
movq %rdx, %rax
shrq $0x8, %rax
xorq %rdx, %rax
xorl %edx, %edx
divq 0x40(%r14)
leaq (%rdx,%rdx,2), %rax
movq %rcx, (%rdi,%rax,8)
movq 0x18(%rsp), %rcx
movw %r13w, 0x8(%rdi,%rax,8)
movl %esi, 0xc(%rdi,%rax,8)
movb %cl, 0x10(%rdi,%rax,8)
movb %bpl, 0x11(%rdi,%rax,8)
movw $0xdead, 0x12(%rdi,%rax,8) # imm = 0xDEAD
movl %r13d, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzbl 0x11(%rax), %ecx
cmpl $0x3, %ecx
je 0x26908
cmpl $0x2, %ecx
je 0x268f2
cmpl $0x1, %ecx
jne 0x26996
movzwl 0x8(%rax), %r13d
jmp 0x268c2
movl %r13d, %edx
movzwl 0x8(%rax), %r13d
cmpw %bp, %r13w
movl %r13d, %ecx
cmovlel %ebp, %ecx
movl %ecx, %ebp
jmp 0x2691c
movl %r13d, %edx
movzwl 0x8(%rax), %r13d
cmpw %dx, %r13w
movl %r13d, %ecx
cmovgel %edx, %ecx
movl %ecx, %edx
movl %edx, 0x4(%rsp)
cmpw %dx, %bp
jge 0x268c2
movq %rbx, 0x8(%rsp)
movzwl 0xc(%rax), %ebx
cmpb $-0x4, %bl
jne 0x2693d
movl 0x4(%rsp), %r13d
jmp 0x26734
movq 0x20(%r12), %rax
leaq 0x20(%rsp), %rdi
movzwl %bx, %esi
movq %rax, 0x20(%rdi)
vmovups (%r12), %ymm0
vmovups %ymm0, (%rdi)
vzeroupper
callq 0x9282
movl 0x4(%rsp), %r13d
testb %al, %al
je 0x269b5
movq 0x8(%rsp), %rdi
movl %r13d, %eax
negl %eax
movl %ebp, %ecx
negl %ecx
leal -0x1(%r15), %r8d
leaq 0x20(%rsp), %rsi
movswl %ax, %edx
movswl %cx, %ecx
callq 0x26674
movl %eax, %r14d
negl %r14d
jmp 0x26738
leaq 0x6166(%rip), %rdi      # 0x2cb03
leaq 0x6178(%rip), %rsi      # 0x2cb1c
leaq 0x617d(%rip), %rcx      # 0x2cb28
movl $0x54, %edx
callq 0x41b0
leaq 0x28c8(%rip), %rdi      # 0x29284
leaq 0x6159(%rip), %rsi      # 0x2cb1c
leaq 0x615e(%rip), %rcx      # 0x2cb28
movl $0x65, %edx
callq 0x41b0
jmp 0x269d6
movq 0x68(%rsp), %rdi
movq %rax, %rbx
testq %rdi, %rdi
je 0x269e8
callq 0x43d0
movq %rbx, %rdi
callq 0x45b0