// File: tewalds[P]morat/pentago/agentmctsthread.cpp
// Function: Morat::Pentago::AgentMCTS::AgentThread::choose_move(Morat::Pentago::AgentMCTS::Node const*, Morat::Side) const
AgentMCTS::Node * AgentMCTS::AgentThread::choose_move(const Node * node, Side to_play) const {
	float val, maxval = -1000000000;
	float logvisits = log(node->exp.num());

	float explore = agent->explore;
	if(agent->parentexplore)
		explore *= node->exp.avg();

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

	for(; child != end; 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(agent->knowledge, agent->fpurgency);
			if(explore > 0)
				val += explore*sqrt(logvisits/(child->exp.num() + 1));
		}

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

	return ret;
}

// Assembly:
subq $0x68, %rsp
movb %dl, %al
movb %al, 0x5f(%rsp)
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x18(%rsp)
vmovss 0x2051a(%rip), %xmm0    # 0x458b0
vmovss %xmm0, 0x40(%rsp)
movq 0x48(%rsp), %rdi
callq 0x1da00
vcvtusi2sd %rax, %xmm0, %xmm0
callq 0x5360
movq 0x18(%rsp), %rax
vmovaps %xmm0, %xmm1
vcvtsd2ss %xmm1, %xmm0, %xmm0
vmovss %xmm0, 0x3c(%rsp)
movq 0x40(%rax), %rcx
vmovss 0x4c(%rcx), %xmm0
vmovss %xmm0, 0x38(%rsp)
movq 0x40(%rax), %rax
testb $0x1, 0x49(%rax)
je 0x253f3
movq 0x48(%rsp), %rdi
callq 0x1da30
vmulss 0x38(%rsp), %xmm0, %xmm0
vmovss %xmm0, 0x38(%rsp)
movq $0x0, 0x30(%rsp)
movq 0x48(%rsp), %rdi
addq $0x18, %rdi
callq 0x1d7b0
movq %rax, 0x28(%rsp)
movq 0x48(%rsp), %rdi
addq $0x18, %rdi
callq 0x1d800
movq %rax, 0x20(%rsp)
movq 0x28(%rsp), %rax
cmpq 0x20(%rsp), %rax
je 0x2558a
movq 0x28(%rsp), %rdi
addq $0x12, %rdi
leaq 0x363d9(%rip), %rsi     # 0x5b81b
callq 0x140c0
testb $0x1, %al
jne 0x2544d
jmp 0x254ab
movq 0x28(%rsp), %rdi
addq $0x12, %rdi
leaq 0x5f(%rsp), %rsi
callq 0x1d9c0
testb $0x1, %al
jne 0x25466
jmp 0x25475
movq 0x28(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0x25594
movq 0x28(%rsp), %rdi
addq $0x12, %rdi
leaq 0x36396(%rip), %rsi     # 0x5b81b
callq 0x14ae0
movb %al, %dl
movl $0xfffffffe, %eax       # imm = 0xFFFFFFFE
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
testb $0x1, %dl
cmovnel %ecx, %eax
vcvtsi2ss %eax, %xmm0, %xmm0
vmovss %xmm0, 0x44(%rsp)
jmp 0x2554d
movq 0x18(%rsp), %rcx
movq 0x28(%rsp), %rdi
movq 0x40(%rcx), %rax
movb 0x50(%rax), %al
movq 0x40(%rcx), %rcx
vmovss 0x58(%rcx), %xmm0
andb $0x1, %al
movzbl %al, %esi
callq 0x26590
vmovss %xmm0, 0x44(%rsp)
vmovss 0x38(%rsp), %xmm0
vpxor %xmm1, %xmm1, %xmm1
vucomiss %xmm1, %xmm0
jbe 0x2554b
vmovss 0x38(%rsp), %xmm1
vcvtss2sd %xmm1, %xmm0, %xmm0
vmovsd %xmm0, 0x10(%rsp)
vmovss 0x3c(%rsp), %xmm0
vmovss %xmm0, 0xc(%rsp)
movq 0x28(%rsp), %rdi
callq 0x1da00
vmovss 0xc(%rsp), %xmm0
addq $0x1, %rax
vcvtusi2ss %rax, %xmm1, %xmm1
vdivss %xmm1, %xmm0, %xmm1
vcvtss2sd %xmm1, %xmm0, %xmm0
callq 0x5350
vmovaps %xmm0, %xmm1
vmovsd 0x10(%rsp), %xmm0
vmovss 0x44(%rsp), %xmm3
vcvtss2sd %xmm3, %xmm2, %xmm2
vfmadd213sd %xmm2, %xmm0, %xmm1 # xmm1 = (xmm0 * xmm1) + xmm2
vcvtsd2ss %xmm1, %xmm0, %xmm0
vmovss %xmm0, 0x44(%rsp)
jmp 0x2554d
vmovss 0x40(%rsp), %xmm1
vmovss 0x44(%rsp), %xmm0
vucomiss %xmm1, %xmm0
jbe 0x25575
vmovss 0x44(%rsp), %xmm0
vmovss %xmm0, 0x40(%rsp)
movq 0x28(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0x25577
movq 0x28(%rsp), %rax
addq $0x20, %rax
movq %rax, 0x28(%rsp)
jmp 0x25422
movq 0x30(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
addq $0x68, %rsp
retq
nop