// File: 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:
subq $0x78, %rsp
movb %dl, %al
movb %al, 0x6f(%rsp)
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movl %ecx, 0x54(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
vmovss 0x276a2(%rip), %xmm0    # 0x4e4cc
vmovss %xmm0, 0x4c(%rsp)
movq 0x58(%rsp), %rdi
addq $0x10, %rdi
callq 0x1c800
vcvtusi2sd %rax, %xmm0, %xmm0
callq 0x5330
movq 0x18(%rsp), %rax
vmovaps %xmm0, %xmm1
vcvtsd2ss %xmm1, %xmm0, %xmm0
vmovss %xmm0, 0x48(%rsp)
movq 0x40(%rax), %rax
vmovss 0x98(%rax), %xmm0
vpxor %xmm1, %xmm1, %xmm1
vucomiss %xmm1, %xmm0
jbe 0x26e96
movq 0x18(%rsp), %rax
vmovss 0x48(%rsp), %xmm0
movq 0x40(%rax), %rax
vdivss 0x9c(%rax), %xmm0, %xmm0
vcvttss2si %xmm0, %eax
addl $0x2, %eax
movl %eax, 0x14(%rsp)
jmp 0x26ea1
movl $0x271, %eax            # imm = 0x271
movl %eax, 0x14(%rsp)
jmp 0x26ea1
movq 0x18(%rsp), %rax
movl 0x14(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movb 0x2f14(%rax), %cl
andb $0x1, %cl
movzbl %cl, %ecx
vcvtsi2ss %ecx, %xmm0, %xmm0
movq 0x40(%rax), %rcx
vmovss 0x7c(%rcx), %xmm3
movq 0x40(%rax), %rcx
vmovss 0x80(%rcx), %xmm2
vcvtsi2ssl 0x54(%rsp), %xmm1, %xmm1
vfmadd213ss %xmm3, %xmm2, %xmm1 # xmm1 = (xmm2 * xmm1) + xmm3
vmulss %xmm1, %xmm0, %xmm0
vmovss %xmm0, 0x40(%rsp)
movb 0x2f15(%rax), %cl
andb $0x1, %cl
movzbl %cl, %ecx
vcvtsi2ss %ecx, %xmm0, %xmm0
movq 0x40(%rax), %rcx
vmulss 0x78(%rcx), %xmm0, %xmm0
vmovss %xmm0, 0x3c(%rsp)
movq 0x40(%rax), %rax
testb $0x1, 0x74(%rax)
je 0x26f2b
movq 0x58(%rsp), %rdi
addq $0x10, %rdi
callq 0x1cab0
vmulss 0x3c(%rsp), %xmm0, %xmm0
vmovss %xmm0, 0x3c(%rsp)
movq $0x0, 0x30(%rsp)
movq 0x58(%rsp), %rdi
addq $0x28, %rdi
callq 0x1c340
movq %rax, 0x28(%rsp)
movq 0x58(%rsp), %rdi
addq $0x28, %rdi
callq 0x1c390
movq %rax, 0x20(%rsp)
movq 0x28(%rsp), %rcx
xorl %eax, %eax
cmpq 0x20(%rsp), %rcx
movb %al, 0x13(%rsp)
je 0x26f78
cmpl $0x0, 0x44(%rsp)
setge %al
movb %al, 0x13(%rsp)
movb 0x13(%rsp), %al
testb $0x1, %al
jne 0x26f85
jmp 0x270f6
movq 0x28(%rsp), %rdi
addq $0x22, %rdi
leaq 0x4652e(%rip), %rsi     # 0x6d4c3
callq 0x1a8c0
testb $0x1, %al
jne 0x26fa0
jmp 0x26ffe
movq 0x28(%rsp), %rdi
addq $0x22, %rdi
leaq 0x6f(%rsp), %rsi
callq 0x1c7c0
testb $0x1, %al
jne 0x26fb9
jmp 0x26fc8
movq 0x28(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x27100
movq 0x28(%rsp), %rdi
addq $0x22, %rdi
leaq 0x464eb(%rip), %rsi     # 0x6d4c3
callq 0x1c810
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, 0x50(%rsp)
jmp 0x270b9
movq 0x18(%rsp), %rcx
movq 0x28(%rsp), %rdi
vmovss 0x40(%rsp), %xmm0
movq 0x40(%rcx), %rax
movb 0x84(%rax), %al
movq 0x40(%rcx), %rcx
vmovss 0x90(%rcx), %xmm1
andb $0x1, %al
movzbl %al, %esi
callq 0x1c870
vmovss %xmm0, 0x50(%rsp)
vmovss 0x3c(%rsp), %xmm0
vpxor %xmm1, %xmm1, %xmm1
vucomiss %xmm1, %xmm0
jbe 0x270ae
vmovss 0x3c(%rsp), %xmm1
vcvtss2sd %xmm1, %xmm0, %xmm0
vmovsd %xmm0, 0x8(%rsp)
vmovss 0x48(%rsp), %xmm0
vmovss %xmm0, 0x4(%rsp)
movq 0x28(%rsp), %rdi
addq $0x10, %rdi
callq 0x1c800
vmovss 0x4(%rsp), %xmm0
addq $0x1, %rax
vcvtusi2ss %rax, %xmm1, %xmm1
vdivss %xmm1, %xmm0, %xmm1
vcvtss2sd %xmm1, %xmm0, %xmm0
callq 0x5320
vmovaps %xmm0, %xmm1
vmovsd 0x8(%rsp), %xmm0
vmovss 0x50(%rsp), %xmm3
vcvtss2sd %xmm3, %xmm2, %xmm2
vfmadd213sd %xmm2, %xmm0, %xmm1 # xmm1 = (xmm0 * xmm1) + xmm2
vcvtsd2ss %xmm1, %xmm0, %xmm0
vmovss %xmm0, 0x50(%rsp)
movl 0x44(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x44(%rsp)
vmovss 0x4c(%rsp), %xmm1
vmovss 0x50(%rsp), %xmm0
vucomiss %xmm1, %xmm0
jbe 0x270e1
vmovss 0x50(%rsp), %xmm0
vmovss %xmm0, 0x4c(%rsp)
movq 0x28(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0x270e3
movq 0x28(%rsp), %rax
addq $0x30, %rax
movq %rax, 0x28(%rsp)
jmp 0x26f5a
movq 0x30(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
addq $0x78, %rsp
retq
nopw (%rax,%rax)