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

	Outcome won = board.outcome();
	if(won >= Outcome::DRAW){
		if(won == Outcome::DRAW)
			return SCORE_DRAW;
		if(won == +board.to_play())
			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 = std::max(alpha, node->score); break;
		case UBOUND: beta  = std::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.simple_hash()) + ", state: " + board.state() + "\n");
				logerr(node->to_s() + "\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 (RandomMoveIterator<XORShift_uint32> move(board, rand); !move.done(); ++move) {
//		for (MoveIterator move(board); !move.done(); ++move) {
			int16_t value = -negamax(move.board(), -beta, -std::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.simple_hash(), score, bestmove, depth, flag));
	}
	return score;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
incq 0x58(%rdi)
movl %edx, %ebp
leaq 0x25b99(%rip), %rdx     # 0x31da5
movl %r8d, %r12d
movl %ecx, %r14d
movq %rsi, %r15
movb 0x1a(%rsi), %al
cmpb (%rdx), %al
jne 0xc22e
movq %rdi, %rbx
movq %r15, %rdi
callq 0xe2a8
movq %rbx, %rdi
movb %al, 0x1a(%r15)
leaq 0x25b74(%rip), %rcx     # 0x31da9
movb (%rcx), %cl
cmpb %cl, %al
jge 0xc399
testl %r12d, %r12d
jle 0xc3b9
cmpq $0x0, 0x38(%rdi)
movl %ebp, (%rsp)
movb $-0x2, %al
movabsq $-0xae502812aa7333, %rbp # imm = 0xFF51AFD7ED558CCD
movabsq $-0x3b314601e57a13ad, %rsi # imm = 0xC4CEB9FE1A85EC53
movw $0x8001, %bx            # imm = 0x8001
movb $0xe, %r13b
movl %eax, 0x4(%rsp)
je 0xc2da
movq %rdi, 0x8(%rsp)
movq %r15, %rdi
callq 0xd800
movq %rax, %rcx
shrq $0x21, %rax
movabsq $-0x3b314601e57a13ad, %rsi # imm = 0xC4CEB9FE1A85EC53
movq 0x8(%rsp), %rdi
xorq %rcx, %rax
imulq %rbp, %rax
movq %rax, %rdx
shrq $0x21, %rdx
movq 0x38(%rdi), %rbp
xorq %rax, %rdx
imulq %rsi, %rdx
movq %rdx, %rax
shrq $0x21, %rax
xorq %rdx, %rax
xorl %edx, %edx
divq 0x40(%rdi)
shlq $0x4, %rdx
cmpq %rcx, (%rbp,%rdx)
jne 0xc2da
addq %rdx, %rbp
movzbl 0xc(%rbp), %eax
cmpl %r12d, %eax
jae 0xc50f
movq %r15, 0x18(%rsp)
cmpw %r14w, %bx
jge 0xc41f
movq %rdi, %rbp
leaq 0x68(%rdi), %rdx
leaq 0xa0(%rsp), %rdi
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movq %r15, %rsi
callq 0xde7a
movl %r14d, %eax
negl %eax
movl %r14d, 0x8(%rsp)
movq %r12, 0x10(%rsp)
leal -0x1(%r12), %r14d
movswl %ax, %r12d
cmpl $0x0, 0xe0(%rsp)
js 0xc424
movl (%rsp), %ecx
movl %ebx, %eax
cmpw %bx, %cx
cmovgl %ecx, %eax
negl %eax
movswl %ax, %ecx
leaq 0xa8(%rsp), %rsi
movq %rbp, %rdi
movl %r12d, %edx
movl %r14d, %r8d
callq 0xc1ee
movl %eax, %r15d
negl %r15d
cmpw %r15w, %bx
jge 0xc38a
movq 0xd8(%rsp), %rdi
movslq 0xe0(%rsp), %rax
movl %r15d, %ebx
movzwl (%rdi,%rax,2), %r13d
movl %r13d, 0x4(%rsp)
shrl $0x8, %r13d
cmpw %r15w, 0x8(%rsp)
jle 0xc434
leaq 0xa0(%rsp), %rdi
callq 0xdf94
jmp 0xc31d
jne 0xc3a3
xorl %r15d, %r15d
jmp 0xc4fa
xorl %ecx, %ecx
cmpb 0x19(%r15), %al
setne %cl
leal 0x7fff(%rcx,%rcx), %r15d
jmp 0xc4fa
movq %r15, %rbx
movzwl 0x1c(%r15), %r15d
cmpw $0xdead, %r15w          # imm = 0xDEAD
jne 0xc3de
movq %rdi, %r14
movq %rbx, %rdi
callq 0xe48a
movl %eax, %r15d
movq %r14, %rdi
movw %ax, 0x1c(%rbx)
movl 0x6c(%rdi), %eax
negl %r15d
testl %eax, %eax
je 0xc4fa
movl 0x68(%rdi), %ecx
shlxl %eax, %r15d, %r15d
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
imull $0x6495, %edx, %ecx     # imm = 0x6495
movl %edx, 0x68(%rdi)
bzhil %eax, %ecx, %eax
subl %eax, %r15d
jmp 0xc4fa
movl %ebx, %r15d
jmp 0xc456
movq 0xd8(%rsp), %rdi
movl %ebx, %r15d
testq %rdi, %rdi
je 0xc43c
callq 0x5490
movl %r15d, %ebx
movq 0x10(%rsp), %r12
movl 0x8(%rsp), %r14d
movl %ebx, %r15d
movabsq $-0x3b314601e57a13ad, %rsi # imm = 0xC4CEB9FE1A85EC53
movq %rbp, %rdi
cmpq $0x0, 0x38(%rdi)
je 0xc4fa
cmpw %r14w, %r15w
movb $0x2, %cl
movq %rdi, %r14
movq 0x18(%rsp), %rdi
movl $0x3, %ebx
movq %rsi, %rbp
setl %al
subb %al, %cl
cmpw (%rsp), %r15w
movzbl %cl, %eax
cmovgl %eax, %ebx
callq 0xd800
movzbl 0x4(%rsp), %esi
movq %rax, %rcx
movzbl %r13b, %eax
movabsq $-0xae502812aa7333, %rdx # imm = 0xFF51AFD7ED558CCD
movq 0x38(%r14), %rdi
shll $0x8, %eax
orl %eax, %esi
movq %rcx, %rax
shrq $0x21, %rax
xorq %rcx, %rax
imulq %rdx, %rax
movq %rax, %rdx
shrq $0x21, %rdx
xorq %rax, %rdx
imulq %rbp, %rdx
movq %rdx, %rax
shrq $0x21, %rax
xorq %rdx, %rax
xorl %edx, %edx
divq 0x40(%r14)
shlq $0x4, %rdx
movq %rcx, (%rdi,%rdx)
movw %r15w, 0x8(%rdi,%rdx)
movw %si, 0xa(%rdi,%rdx)
movb %r12b, 0xc(%rdi,%rdx)
movb %bl, 0xd(%rdi,%rdx)
movw $0xdead, 0xe(%rdi,%rdx) # imm = 0xDEAD
movl %r15d, %eax
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzbl 0xd(%rbp), %eax
cmpl $0x3, %eax
je 0xc547
cmpl $0x2, %eax
je 0xc52d
cmpl $0x1, %eax
jne 0xc87b
movzwl 0x8(%rbp), %r15d
jmp 0xc4fa
movq %r15, %rcx
movzwl 0x8(%rbp), %r15d
movl (%rsp), %edx
cmpw %dx, %r15w
movl %r15d, %eax
cmovlel %edx, %eax
movl %r14d, %edx
jmp 0xc55f
movq %r15, %rcx
movzwl 0x8(%rbp), %r15d
cmpw %r14w, %r15w
movl %r15d, %eax
cmovgel %r14d, %eax
movl %eax, %edx
movl (%rsp), %eax
movl %eax, (%rsp)
cmpw %dx, %ax
jge 0xc4fa
cmpb $-0x4, 0xa(%rbp)
movl %edx, %r14d
jne 0xc578
movq %rcx, %r15
jmp 0xc2da
movq 0x20(%rcx), %rax
leaq 0xa0(%rsp), %rdi
movzwl 0xa(%rbp), %r13d
movq %rcx, %r15
movq %rax, 0x20(%rdi)
movl %r13d, %esi
vmovups (%rcx), %ymm0
vmovups %ymm0, (%rdi)
vzeroupper
callq 0xd6ec
testb %al, %al
je 0xc5f0
movl (%rsp), %ecx
movq 0x8(%rsp), %rbx
movl %r14d, %eax
negl %eax
leal -0x1(%r12), %r8d
leaq 0xa0(%rsp), %rsi
movl %r13d, 0x4(%rsp)
shrl $0x8, %r13d
movswl %ax, %edx
negl %ecx
movq %rbx, %rdi
movswl %cx, %ecx
callq 0xc1ee
movq %rbx, %rdi
movl %eax, %ebx
movabsq $-0x3b314601e57a13ad, %rsi # imm = 0xC4CEB9FE1A85EC53
negl %ebx
jmp 0xc2da
movq %r15, %rdi
callq 0xd800
leaq 0x128(%rsp), %rbx
movq %rax, %rsi
movq %rbx, %rdi
callq 0xd33e
leaq 0x20c3d(%rip), %rsi     # 0x2d24f
leaq 0x108(%rsp), %rdi
movq %rbx, %rdx
callq 0xd1a3
leaq 0x20c35(%rip), %rsi     # 0x2d25e
leaq 0x108(%rsp), %rdi
callq 0x5720
leaq 0x30(%rsp), %r14
movq %rax, %rcx
addq $0x10, %rcx
movq %r14, -0x10(%r14)
movq (%rax), %rdx
cmpq %rcx, %rdx
jne 0xc659
vmovups (%rcx), %xmm0
vmovups %xmm0, (%r14)
jmp 0xc666
movq %rdx, 0x20(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x30(%rsp)
movq 0x8(%rax), %rdx
movq %rdx, 0x28(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0xe8(%rsp), %rdi
movq %r15, %rsi
callq 0x1d168
leaq 0x40(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0xe8(%rsp), %rdx
callq 0xd294
leaq 0x20196(%rip), %rsi     # 0x2c842
leaq 0x40(%rsp), %rdi
callq 0x5720
leaq 0x90(%rsp), %rbx
movq %rax, %rcx
addq $0x10, %rcx
movq %r15, %r13
movq %rbx, -0x10(%rbx)
movq (%rax), %rdi
cmpq %rcx, %rdi
jne 0xc6e1
vmovups (%rcx), %xmm0
movq %rbx, %rdi
vmovups %xmm0, (%rbx)
jmp 0xc6f4
movq %rdi, 0x80(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x90(%rsp)
movq 0x8(%rax), %rdx
movq 0x308d9(%rip), %r15     # 0x3cfd8
movq %rdx, 0x88(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq (%r15), %rsi
callq 0x53b0
movq 0x80(%rsp), %rdi
cmpq %rbx, %rdi
je 0xc730
callq 0x5310
leaq 0x50(%rsp), %r12
movq -0x10(%r12), %rdi
cmpq %r12, %rdi
je 0xc744
callq 0x5310
leaq 0xf8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc75a
callq 0x5310
movq 0x20(%rsp), %rdi
cmpq %r14, %rdi
je 0xc769
callq 0x5310
leaq 0x118(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc77f
callq 0x5310
leaq 0x138(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc795
callq 0x5310
leaq 0x40(%rsp), %rbx
movq %rbp, %rsi
movq %rbx, %rdi
callq 0xd898
leaq 0x20096(%rip), %rsi     # 0x2c842
movq %rbx, %rdi
callq 0x5720
leaq 0x70(%rsp), %rbx
movq %rax, %rcx
addq $0x10, %rcx
movq %rbx, -0x10(%rbx)
movq (%rax), %rdi
cmpq %rcx, %rdi
jne 0xc7d9
vmovups (%rcx), %xmm0
movq %rbx, %rdi
vmovups %xmm0, (%rbx)
jmp 0xc7e6
movq %rdi, 0x60(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x70(%rsp)
movq 0x8(%rax), %rdx
movq %rdx, 0x68(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq (%r15), %rsi
callq 0x53b0
movq 0x60(%rsp), %rdi
cmpq %rbx, %rdi
je 0xc815
callq 0x5310
movq 0x40(%rsp), %rdi
cmpq %r12, %rdi
je 0xc824
callq 0x5310
leaq 0x148(%rsp), %rbx
movl $0x1, %edx
movq %r13, %rsi
movq %rbx, %rdi
callq 0x1d25a
movq (%r15), %rsi
movq (%rbx), %rdi
callq 0x53b0
movq (%rbx), %rdi
leaq 0x158(%rsp), %rax
cmpq %rax, %rdi
je 0xc85c
callq 0x5310
leaq 0x20a05(%rip), %rdi     # 0x2d268
leaq 0x20982(%rip), %rsi     # 0x2d1ec
leaq 0x2098f(%rip), %rcx     # 0x2d200
movl $0x6b, %edx
callq 0x5200
leaq 0x20951(%rip), %rdi     # 0x2d1d3
leaq 0x20963(%rip), %rsi     # 0x2d1ec
leaq 0x20970(%rip), %rcx     # 0x2d200
movl $0x5a, %edx
callq 0x5200
movq 0x40(%rsp), %rdi
movq %rax, %rbx
cmpq %r12, %rdi
jne 0xc922
jmp 0xc940
leaq 0x50(%rsp), %rcx
movq %rax, %rbx
movq -0x10(%rcx), %rdi
cmpq %rcx, %rdi
je 0xc8c7
callq 0x5310
jmp 0xc8c7
movq %rax, %rbx
leaq 0xf8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc8e2
callq 0x5310
jmp 0xc8e2
movq %rax, %rbx
movq 0x20(%rsp), %rdi
cmpq %r14, %rdi
je 0xc8f6
callq 0x5310
jmp 0xc8f6
movq %rax, %rbx
leaq 0x118(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc911
callq 0x5310
jmp 0xc911
movq %rax, %rbx
leaq 0x138(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc940
callq 0x5310
jmp 0xc940
jmp 0xc92b
movq 0xd8(%rsp), %rdi
movq %rax, %rbx
testq %rdi, %rdi
je 0xc940
callq 0x5490
movq %rbx, %rdi
callq 0x56c0