// File: /workspace/github_cpp_makefile_star2_O1/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 $0x178, %rsp            # imm = 0x178
movl %r8d, %ebx
movl %ecx, %r13d
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %r14
incq 0x58(%rdi)
movb 0x1a(%rsi), %al
leaq 0x25bb0(%rip), %rcx     # 0x31da5
cmpb (%rcx), %al
jne 0xc205
movq %r15, %rdi
callq 0xe358
movb %al, 0x1a(%r15)
movb 0x1a(%r15), %al
leaq 0x25b99(%rip), %rcx     # 0x31da9
movb (%rcx), %cl
cmpb %cl, %al
jge 0xc384
testl %ebx, %ebx
jle 0xc3a4
movl %ebp, 0x8(%rsp)
movq %r15, 0x18(%rsp)
movq %rbx, 0x20(%rsp)
movabsq $-0xae502812aa7333, %rdi # imm = 0xFF51AFD7ED558CCD
movabsq $-0x3b314601e57a13ad, %rax # imm = 0xC4CEB9FE1A85EC53
movw $0x8001, %r12w          # imm = 0x8001
movb $0xe, %r15b
movb $-0x2, %dl
cmpq $0x0, 0x38(%r14)
je 0xc2bc
movl %r13d, %ebx
movq %rax, %rbp
movq %rdi, %r13
movq 0x18(%rsp), %rdi
callq 0xd860
movq %r13, %rdi
movq %rax, %rcx
shrq $0x21, %rax
xorq %rcx, %rax
imulq %r13, %rax
movq %rax, %rdx
shrq $0x21, %rdx
xorq %rax, %rdx
imulq %rbp, %rdx
movq %rdx, %rax
shrq $0x21, %rax
xorq %rdx, %rax
movq 0x38(%r14), %rbp
xorl %edx, %edx
divq 0x40(%r14)
shlq $0x4, %rdx
cmpq %rcx, (%rbp,%rdx)
jne 0xc2b7
addq %rdx, %rbp
movzbl 0xc(%rbp), %eax
cmpl 0x20(%rsp), %eax
jge 0xc4f8
movl %ebx, %r13d
movb $-0x2, %dl
cmpw %r13w, %r12w
movl %r13d, %ebx
jge 0xc403
movl %edx, %r13d
leaq 0x68(%r14), %rdx
leaq 0xb0(%rsp), %rdi
movq 0x18(%rsp), %rsi
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
callq 0xdedc
movl %ebx, 0x10(%rsp)
movl %ebx, %eax
negl %eax
movq 0x20(%rsp), %rcx
decl %ecx
movl %ecx, 0x14(%rsp)
movswl %ax, %ebp
cmpl $0x0, 0xf0(%rsp)
js 0xc40d
movl 0x8(%rsp), %ecx
cmpw %r12w, %cx
movl %r12d, %eax
cmovgl %ecx, %eax
negl %eax
movswl %ax, %ecx
movq %r14, %rbx
movq %r14, %rdi
leaq 0xb8(%rsp), %rsi
movl %ebp, %edx
movl 0x14(%rsp), %r8d
callq 0xc1c8
movl %eax, %r14d
negl %r14d
cmpw %r14w, %r12w
jge 0xc36f
movq 0xe8(%rsp), %rax
movslq 0xf0(%rsp), %rcx
movzwl (%rax,%rcx,2), %r15d
movl %r15d, %r13d
shrl $0x8, %r15d
movl %r14d, %r12d
cmpw %r14w, 0x10(%rsp)
jle 0xc413
leaq 0xb0(%rsp), %rdi
callq 0xe00e
movq %rbx, %r14
jmp 0xc2fd
jne 0xc38e
xorl %r14d, %r14d
jmp 0xc4e3
xorl %ecx, %ecx
cmpb 0x19(%r15), %al
setne %cl
leal 0x7fff(%rcx,%rcx), %r14d
jmp 0xc4e3
movq %r14, %rbx
cmpw $0xdead, 0x1c(%r15)     # imm = 0xDEAD
jne 0xc3bd
movq %r15, %rdi
callq 0xe52a
movw %ax, 0x1c(%r15)
xorl %r14d, %r14d
subw 0x1c(%r15), %r14w
movl 0x6c(%rbx), %eax
testl %eax, %eax
je 0xc4e3
shlxl %eax, %r14d, %r14d
movl 0x68(%rbx), %ecx
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
movl %edx, 0x68(%rbx)
imull $0x6495, %edx, %ecx     # imm = 0x6495
bzhil %eax, %ecx, %eax
subl %eax, %r14d
jmp 0xc4e3
movl %ebx, %eax
movq %r14, %rbx
movl %r12d, %r14d
jmp 0xc436
movq %r14, %rbx
movl %r12d, %r14d
movq 0xe8(%rsp), %rdi
testq %rdi, %rdi
je 0xc425
callq 0x5490
movabsq $-0xae502812aa7333, %rdi # imm = 0xFF51AFD7ED558CCD
movl 0x10(%rsp), %eax
movl %r13d, %edx
cmpq $0x0, 0x38(%rbx)
je 0xc4e3
movq %rbx, %r12
cmpw %ax, %r14w
setl %al
movb $0x2, %cl
subb %al, %cl
cmpw 0x8(%rsp), %r14w
movzbl %cl, %eax
movl $0x3, %ebx
cmovgl %eax, %ebx
movl %edx, %r13d
movq %rdi, %rbp
movq 0x18(%rsp), %rdi
callq 0xd860
movq %rax, %rcx
movzbl %r15b, %eax
shll $0x8, %eax
movzbl %r13b, %esi
orl %eax, %esi
movq %rcx, %rax
shrq $0x21, %rax
xorq %rcx, %rax
imulq %rbp, %rax
movq %rax, %rdx
shrq $0x21, %rdx
xorq %rax, %rdx
movabsq $-0x3b314601e57a13ad, %rax # imm = 0xC4CEB9FE1A85EC53
imulq %rax, %rdx
movq %rdx, %rax
shrq $0x21, %rax
xorq %rdx, %rax
movq 0x38(%r12), %rdi
xorl %edx, %edx
divq 0x40(%r12)
shlq $0x4, %rdx
movq %rcx, (%rdi,%rdx)
movw %r14w, 0x8(%rdi,%rdx)
movw %si, 0xa(%rdi,%rdx)
movq 0x20(%rsp), %rax
movb %al, 0xc(%rdi,%rdx)
movb %bl, 0xd(%rdi,%rdx)
movw $0xdead, 0xe(%rdi,%rdx) # imm = 0xDEAD
movl %r14d, %eax
addq $0x178, %rsp            # imm = 0x178
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzbl 0xd(%rbp), %eax
cmpl $0x3, %eax
je 0xc53c
cmpl $0x2, %eax
je 0xc52a
cmpl $0x1, %eax
je 0xc569
leaq 0x20cc1(%rip), %rdi     # 0x2d1d3
leaq 0x20cd3(%rip), %rsi     # 0x2d1ec
leaq 0x20ce0(%rip), %rcx     # 0x2d200
movl $0x5a, %edx
callq 0x5200
movzwl 0x8(%rbp), %eax
movl 0x8(%rsp), %ecx
cmpw %cx, %ax
cmovlel %ecx, %eax
movl %ebx, %ecx
jmp 0xc54c
movzwl 0x8(%rbp), %eax
cmpw %bx, %ax
cmovgel %ebx, %eax
movl %eax, %ecx
movl 0x8(%rsp), %eax
movl %eax, 0x8(%rsp)
movl %ecx, 0x10(%rsp)
cmpw %cx, %ax
jge 0xc569
cmpb $-0x4, 0xa(%rbp)
jne 0xc573
movl 0x10(%rsp), %r13d
jmp 0xc2ba
movzwl 0x8(%rbp), %r14d
jmp 0xc4e3
movzwl 0xa(%rbp), %esi
movq 0x18(%rsp), %rbx
movq 0x20(%rbx), %rax
leaq 0xb0(%rsp), %rdi
movq %rax, 0x20(%rdi)
vmovups (%rbx), %ymm0
vmovups %ymm0, (%rdi)
movl %esi, %r15d
vzeroupper
callq 0xd74e
testb %al, %al
movl 0x8(%rsp), %r12d
movl %r15d, 0x14(%rsp)
je 0xc5f2
shrl $0x8, %r15d
movl 0x10(%rsp), %ebx
movl %ebx, %eax
negl %eax
movl %r12d, %ecx
negl %ecx
movq 0x20(%rsp), %rdx
leal -0x1(%rdx), %r8d
movswl %ax, %edx
movswl %cx, %ecx
leaq 0xb0(%rsp), %rsi
movq %r14, %rdi
callq 0xc1c8
movl %eax, %r12d
negl %r12d
movq %r13, %rdi
movl %ebx, %r13d
movl 0x14(%rsp), %edx
jmp 0xc2bc
movq %rbp, 0x28(%rsp)
movb %al, 0xf(%rsp)
movq %rbx, %rdi
callq 0xd860
leaq 0x138(%rsp), %r12
movq %r12, %rdi
movq %rax, %rsi
callq 0xd392
leaq 0x20c32(%rip), %rsi     # 0x2d24f
leaq 0x118(%rsp), %rdi
movq %r12, %rdx
callq 0xd1f7
movq %rbx, %r15
leaq 0x20c27(%rip), %rsi     # 0x2d25e
leaq 0x118(%rsp), %rdi
callq 0x5720
leaq 0x40(%rsp), %rbx
movq %rbx, -0x10(%rbx)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
jne 0xc666
vmovups (%rcx), %xmm0
vmovups %xmm0, (%rbx)
jmp 0xc673
movq %rdx, 0x30(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x40(%rsp)
movq 0x8(%rax), %rdx
movq %rdx, 0x38(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0xf8(%rsp), %rdi
movq %r15, %rsi
callq 0x1d46c
leaq 0x50(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0xd2e8
leaq 0x20189(%rip), %rsi     # 0x2c842
leaq 0x50(%rsp), %rdi
callq 0x5720
leaq 0xa0(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
jne 0xc6e9
vmovups (%rcx), %xmm0
vmovups %xmm0, (%r15)
jmp 0xc6fc
movq %rdx, 0x90(%rsp)
movq (%rcx), %rdx
movq %rdx, 0xa0(%rsp)
movq 0x8(%rax), %rdx
movq %rdx, 0x98(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq 0x308ba(%rip), %rax     # 0x3cfd8
movq (%rax), %rsi
movq 0x90(%rsp), %rdi
callq 0x53b0
movq 0x90(%rsp), %rdi
cmpq %r15, %rdi
je 0xc740
callq 0x5310
leaq 0x60(%rsp), %r12
movq -0x10(%r12), %rdi
cmpq %r12, %rdi
je 0xc754
callq 0x5310
leaq 0x108(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc76a
callq 0x5310
movq 0x30(%rsp), %rdi
cmpq %rbx, %rdi
je 0xc779
callq 0x5310
leaq 0x128(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
movq 0x30849(%rip), %rbx     # 0x3cfd8
je 0xc796
callq 0x5310
leaq 0x148(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc7ac
callq 0x5310
leaq 0x50(%rsp), %r15
movq %r15, %rdi
movq 0x28(%rsp), %rsi
callq 0xd8f8
leaq 0x2007d(%rip), %rsi     # 0x2c842
movq %r15, %rdi
callq 0x5720
leaq 0x80(%rsp), %r15
movq %r15, -0x10(%r15)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
jne 0xc7f3
vmovups (%rcx), %xmm0
vmovups %xmm0, (%r15)
jmp 0xc803
movq %rdx, 0x70(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x80(%rsp)
movq 0x8(%rax), %rdx
movq %rdx, 0x78(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq (%rbx), %rsi
movq 0x70(%rsp), %rdi
callq 0x53b0
movq 0x70(%rsp), %rdi
cmpq %r15, %rdi
je 0xc837
callq 0x5310
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0xc846
callq 0x5310
leaq 0x158(%rsp), %r15
movq %r15, %rdi
movq 0x18(%rsp), %rsi
movl $0x1, %edx
callq 0x1d55e
movq (%rbx), %rsi
movq (%r15), %rdi
callq 0x53b0
movq (%r15), %rdi
leaq 0x168(%rsp), %rax
cmpq %rax, %rdi
movl 0x8(%rsp), %r12d
je 0xc885
callq 0x5310
cmpb $0x0, 0xf(%rsp)
movl 0x14(%rsp), %r15d
jne 0xc5ad
leaq 0x209cc(%rip), %rdi     # 0x2d268
leaq 0x20949(%rip), %rsi     # 0x2d1ec
leaq 0x20956(%rip), %rcx     # 0x2d200
movl $0x6b, %edx
callq 0x5200
movq %rax, %rbx
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
jne 0xc949
jmp 0xc967
movq %rbx, %r14
movq %rax, %rbx
leaq 0x60(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc8eb
callq 0x5310
jmp 0xc8eb
movq %rbx, %r14
movq %rax, %rbx
leaq 0x108(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc909
callq 0x5310
jmp 0xc909
movq %rbx, %r14
movq %rax, %rbx
movq 0x30(%rsp), %rdi
cmpq %r14, %rdi
je 0xc91d
callq 0x5310
jmp 0xc91d
movq %rax, %rbx
leaq 0x128(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc938
callq 0x5310
jmp 0xc938
movq %rax, %rbx
leaq 0x148(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0xc967
callq 0x5310
jmp 0xc967
jmp 0xc952
movq %rax, %rbx
movq 0xe8(%rsp), %rdi
testq %rdi, %rdi
je 0xc967
callq 0x5490
movq %rbx, %rdi
callq 0x56c0
nop