// File: /workspace/github_cpp_makefile_star2_O2/tewalds[P]morat/hex/agentmctsthread.cpp
// Function: Morat::Hex::AgentMCTS::AgentThread::choose_move(Morat::Hex::AgentMCTS::Node const*, Morat::Side, int) const
AgentMCTS::Node * AgentMCTS::AgentThread::choose_move(const Node * node, Side to_play, int remain) const {
	float val, maxval = -1000000000;
	float logvisits = log(node->exp.num());
	int dynwidenlim = (agent->dynwiden > 0 ? (int)(logvisits/agent->logdynwiden)+2 : Board::max_vec_size);

	float raveval = use_rave * (agent->ravefactor + agent->decrrave*remain);
	float explore = use_explore * agent->explore;
	if(agent->parentexplore)
		explore *= node->exp.avg();

	Node * ret   = NULL,
		 * child = node->children.begin(),
		 * end   = node->children.end();

	for(; child != end && dynwidenlim >= 0; child++){
		if(child->outcome >= Outcome::DRAW){
			if(child->outcome == to_play) //return a win immediately
				return child;

			val = (child->outcome == Outcome::DRAW ? -1 : -2); //-1 for tie so any unknown is better, -2 for loss so it's even worse
		}else{
			val = child->value(raveval, agent->knowledge, agent->fpurgency);
			if(explore > 0)
				val += explore*sqrt(logvisits/(child->exp.num() + 1));
			dynwidenlim--;
		}

		if(maxval < val){
			maxval = val;
			ret = child;
		}
	}

	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
vcvtusi2sdq 0x18(%rsi), %xmm0, %xmm0
movl %ecx, %ebp
movl %edx, 0x1c(%rsp)
movq %rsi, %r15
movq %rdi, %r14
callq 0x5280
movq 0x40(%r14), %rax
vcvtsd2ss %xmm0, %xmm0, %xmm0
vxorps %xmm1, %xmm1, %xmm1
movl $0x271, %r13d           # imm = 0x271
vmovss %xmm0, 0x10(%rsp)
vmovss 0x98(%rax), %xmm0
vucomiss %xmm1, %xmm0
jbe 0x1166e
vmovss 0x10(%rsp), %xmm0
vdivss 0x9c(%rax), %xmm0, %xmm0
vcvttss2si %xmm0, %r13d
addl $0x2, %r13d
vmovss 0x80(%rax), %xmm0
movsbl 0x2f15(%r14), %ecx
movsbl 0x2f14(%r14), %ebx
cmpb $0x1, 0x74(%rax)
vcvtsi2ss %ebp, %xmm2, %xmm1
vfmadd213ss 0x7c(%rax), %xmm0, %xmm1 # xmm1 = (xmm0 * xmm1) + mem
vcvtsi2ss %ecx, %xmm2, %xmm0
vmulss 0x78(%rax), %xmm0, %xmm2
jne 0x116c4
leaq 0x10(%r15), %rdi
vmovss %xmm2, 0x8(%rsp)
vmovss %xmm1, 0xc(%rsp)
callq 0xe362
vmovss 0x8(%rsp), %xmm2
vmovss 0xc(%rsp), %xmm1
vmulss %xmm0, %xmm2, %xmm2
movq 0x28(%r15), %rcx
vcvtsi2ss %ebx, %xmm3, %xmm0
xorl %ebp, %ebp
movl $0x0, %r15d
leaq 0x10(%rcx), %rax
cmpq $0x2, %rcx
cmovaeq %rax, %r15
jb 0x116f0
movzwl 0x6(%rcx), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq %rax, %rbp
vmulss %xmm0, %xmm1, %xmm0
leaq 0x157b6(%rip), %rbx     # 0x26eb1
xorl %r12d, %r12d
vmovss %xmm2, 0x8(%rsp)
vmovss %xmm0, 0x18(%rsp)
vcvtss2sd %xmm2, %xmm2, %xmm0
vmovsd %xmm0, 0x20(%rsp)
vmovss 0x12df0(%rip), %xmm0    # 0x2450c
cmpq %rbp, %r15
je 0x117fa
testl %r13d, %r13d
js 0x117fa
movb 0x22(%r15), %al
movb (%rbx), %cl
cmpb %cl, %al
jge 0x1179e
movq 0x40(%r14), %rax
vmovss %xmm0, 0xc(%rsp)
vmovss 0x18(%rsp), %xmm0
movq %r15, %rdi
vmovss 0x90(%rax), %xmm1
movzbl 0x84(%rax), %esi
callq 0xe234
vmovss 0x8(%rsp), %xmm2
vmovaps %xmm0, %xmm3
vucomiss 0x12d9f(%rip), %xmm2    # 0x24510
jbe 0x117d9
movq 0x18(%r15), %rax
vmovss 0x10(%rsp), %xmm1
incq %rax
vcvtusi2ss %rax, %xmm4, %xmm0
vdivss %xmm0, %xmm1, %xmm0
vcvtss2sd %xmm0, %xmm0, %xmm0
vucomisd 0x11a6a(%rip), %xmm0    # 0x23200
jb 0x117b9
vsqrtsd %xmm0, %xmm0, %xmm0
jmp 0x117ca
cmpb 0x1c(%rsp), %al
je 0x117f7
xorl %edx, %edx
cmpb %cl, %al
leaq 0x12d51(%rip), %rax     # 0x24500
sete %dl
vmovss (%rax,%rdx,4), %xmm3
jmp 0x117e2
vmovss %xmm3, 0x14(%rsp)
callq 0x5270
vmovss 0x14(%rsp), %xmm3
vcvtss2sd %xmm3, %xmm3, %xmm1
vfmadd231sd 0x20(%rsp), %xmm0, %xmm1 # xmm1 = (xmm0 * mem) + xmm1
vcvtsd2ss %xmm1, %xmm1, %xmm3
vmovss 0xc(%rsp), %xmm0
decl %r13d
vucomiss %xmm0, %xmm3
vmaxss %xmm0, %xmm3, %xmm0
cmovaq %r15, %r12
addq $0x30, %r15
jmp 0x1171c
movq %r15, %r12
movq %r12, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq