// File: tewalds[P]morat/pentago/agentpns.cpp
// Function: Morat::Pentago::AgentPNS::AgentThread::pns(Morat::Pentago::Board const&, Morat::Pentago::AgentPNS::Node*, int, unsigned int, unsigned int)
bool AgentPNS::AgentThread::pns(const Board & board, Node * node, int depth, uint32_t tp, uint32_t td){
	// no children, create them
	if(node->children.empty()){
		treelen.add(depth);

		if(node->terminal())
			return true;

		if(agent->need_gc())
			return false;

		if(!node->children.lock())
			return false;

		int numnodes = board.moves_avail();
		CompactTree<Node>::Children temp;
		temp.alloc(numnodes, agent->ctmem);

		unsigned int i = 0;
		for(MoveIterator move(board); !move.done(); ++move){
			unsigned int pd;
			Outcome outcome;

			if(agent->ab){
				Board next = board;
				next.move(*move);

				pd = 0;
				outcome = solve1ply(move.board(), pd);
			}else{
				pd = 1;
				outcome = move.board().outcome();
			}

			temp[i] = Node(*move).outcome(outcome, board.to_play(), agent->ties, pd);
			i++;
		}
		nodes_seen += i;
		PLUS(agent->nodes_seen, i);
		PLUS(agent->nodes, i);
		temp.shrink(i); //if symmetry, there may be extra moves to ignore
		node->children.swap(temp);
		assert(temp.unlock());

		updatePDnum(node);

		return (agent->nodes_seen >= agent->max_nodes_seen);
	}

	bool mem;
	do{
		Node * child = node->children.begin(), // the best move to explore
		     * child2 = node->children.begin();// second best for thresholds

		uint32_t tpc, tdc; // the thresholds

		if(agent->df){
			for(auto & i : node->children){
				if(i.refdelta() <= child->refdelta()){
					child2 = child;
					child = & i;
				}else if(i.refdelta() < child2->refdelta()){
					child2 = & i;
				}
			}

			tpc = std::min(INF32/2, (td + child->phi - node->delta));
			tdc = std::min(tp, (uint32_t)(child2->delta*(1.0 + agent->epsilon) + 1));
		}else{
			tpc = tdc = 0;
			for(auto & i : node->children)
				if(child->refdelta() > i.refdelta())
					child = & i;
		}

		Board next = board;
		next.move(child->move);

		child->ref();
		uint64_t seen_before = nodes_seen;
		mem = pns(next, child, depth + 1, tpc, tdc);
		child->deref();
		PLUS(child->work, nodes_seen - seen_before);

		if(updatePDnum(node) && !agent->df)
			break;

	}while(!agent->timeout && mem && (!agent->df || (node->phi < tp && node->delta < td)));

	return mem;
}

// Assembly:
subq $0x218, %rsp            # imm = 0x218
movq %rdi, 0x208(%rsp)
movq %rsi, 0x200(%rsp)
movq %rdx, 0x1f8(%rsp)
movl %ecx, 0x1f4(%rsp)
movl %r8d, 0x1f0(%rsp)
movl %r9d, 0x1ec(%rsp)
movq 0x208(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x1f8(%rsp), %rdi
addq $0x18, %rdi
callq 0x2a440
testb $0x1, %al
jne 0x2822d
jmp 0x286e4
movq 0x70(%rsp), %rdi
addq $0x48, %rdi
movl 0x1f4(%rsp), %esi
callq 0x26460
movq 0x1f8(%rsp), %rdi
callq 0x2a460
testb $0x1, %al
jne 0x28255
jmp 0x28262
movb $0x1, 0x217(%rsp)
jmp 0x28b54
movq 0x70(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x2a4a0
testb $0x1, %al
jne 0x28276
jmp 0x28283
movb $0x0, 0x217(%rsp)
jmp 0x28b54
movq 0x1f8(%rsp), %rdi
addq $0x18, %rdi
callq 0x2a4d0
testb $0x1, %al
jne 0x282a5
movb $0x0, 0x217(%rsp)
jmp 0x28b54
movq 0x200(%rsp), %rdi
callq 0x168e0
movl %eax, 0x1e8(%rsp)
leaq 0x1e0(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x2a510
movq 0x70(%rsp), %rax
movq 0x68(%rsp), %rdi
movl 0x1e8(%rsp), %esi
movq 0x40(%rax), %rdx
addq $0x50, %rdx
callq 0x2a530
jmp 0x282eb
movl $0x0, 0x1d0(%rsp)
movq 0x200(%rsp), %rsi
leaq 0x180(%rsp), %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x15670
jmp 0x28312
jmp 0x28314
leaq 0x180(%rsp), %rdi
callq 0x157e0
movb %al, 0x67(%rsp)
jmp 0x28327
movb 0x67(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x28375
leaq 0x180(%rsp), %rdi
callq 0x15940
jmp 0x285c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
jmp 0x286d2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
jmp 0x285b5
leaq 0x17b(%rsp), %rdi
callq 0xeed0
jmp 0x28384
movq 0x70(%rsp), %rax
movq 0x40(%rax), %rax
cmpl $0x0, 0x1508(%rax)
je 0x2844b
movq 0x200(%rsp), %rax
movq 0x20(%rax), %rcx
movq %rcx, 0x170(%rsp)
vmovdqu (%rax), %ymm0
vmovdqu %ymm0, 0x150(%rsp)
leaq 0x180(%rsp), %rdi
vzeroupper
callq 0x15960
movq %rax, 0x58(%rsp)
jmp 0x283d2
movq 0x58(%rsp), %rax
movw (%rax), %ax
movw %ax, 0x14e(%rsp)
movzwl 0x14e(%rsp), %esi
leaq 0x150(%rsp), %rdi
callq 0x14c70
jmp 0x283f9
movl $0x0, 0x17c(%rsp)
leaq 0x180(%rsp), %rdi
callq 0x15810
movq %rax, 0x50(%rsp)
jmp 0x28418
movq 0x50(%rsp), %rdi
leaq 0x17c(%rsp), %rsi
callq 0x2a5a0
movb %al, 0x4f(%rsp)
jmp 0x28430
movb 0x4f(%rsp), %al
movb %al, 0x14d(%rsp)
movb 0x14d(%rsp), %al
movb %al, 0x17b(%rsp)
jmp 0x28493
movl $0x1, 0x17c(%rsp)
leaq 0x180(%rsp), %rdi
callq 0x15810
movq %rax, 0x40(%rsp)
jmp 0x2846a
movq 0x40(%rsp), %rdi
callq 0x14100
movb %al, 0x3f(%rsp)
jmp 0x2847a
movb 0x3f(%rsp), %al
movb %al, 0x14c(%rsp)
movb 0x14c(%rsp), %al
movb %al, 0x17b(%rsp)
leaq 0x180(%rsp), %rdi
callq 0x15960
movq %rax, 0x30(%rsp)
jmp 0x284a7
movq 0x30(%rsp), %rsi
leaq 0x128(%rsp), %rdi
movl $0x1, %edx
callq 0x29ef0
jmp 0x284c0
movb 0x17b(%rsp), %al
movb %al, 0x127(%rsp)
movq 0x200(%rsp), %rdi
callq 0x14b50
movb %al, 0x2f(%rsp)
jmp 0x284e1
movq 0x70(%rsp), %rax
movb 0x2f(%rsp), %cl
movb %cl, 0x126(%rsp)
movq 0x40(%rax), %rax
movb 0x1514(%rax), %al
movb %al, 0x125(%rsp)
movl 0x17c(%rsp), %r8d
movzbl 0x125(%rsp), %ecx
movzbl 0x126(%rsp), %edx
movzbl 0x127(%rsp), %esi
leaq 0x128(%rsp), %rdi
callq 0x2a7f0
movq %rax, 0x20(%rsp)
jmp 0x28536
movl 0x1d0(%rsp), %esi
leaq 0x1e0(%rsp), %rdi
callq 0x2a940
movq %rax, 0x18(%rsp)
jmp 0x28551
movq 0x20(%rsp), %rsi
movq 0x18(%rsp), %rdi
callq 0x2a9f0
jmp 0x28562
leaq 0x128(%rsp), %rdi
callq 0x29f80
movl 0x1d0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1d0(%rsp)
leaq 0x180(%rsp), %rdi
callq 0x15820
jmp 0x2858f
jmp 0x28314
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
leaq 0x128(%rsp), %rdi
callq 0x29f80
leaq 0x180(%rsp), %rdi
callq 0x15940
jmp 0x286d2
movq 0x70(%rsp), %rax
movl 0x1d0(%rsp), %ecx
movl %ecx, %edx
movq 0x68(%rax), %rcx
addq %rdx, %rcx
movq %rcx, 0x68(%rax)
movq 0x40(%rax), %rdi
addq $0x14f8, %rdi           # imm = 0x14F8
leaq 0x1d0(%rsp), %rsi
callq 0x1e4f0
jmp 0x285fa
movq 0x70(%rsp), %rax
movq 0x40(%rax), %rdi
addq $0x38, %rdi
leaq 0x1d0(%rsp), %rsi
callq 0x1e4f0
jmp 0x28616
movl 0x1d0(%rsp), %esi
leaq 0x1e0(%rsp), %rdi
callq 0x2aa80
jmp 0x2862c
movq 0x1f8(%rsp), %rdi
addq $0x18, %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x2aab0
jmp 0x28647
leaq 0x1e0(%rsp), %rdi
callq 0x2ab30
movb %al, 0x17(%rsp)
jmp 0x2865a
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0x28664
jmp 0x28666
jmp 0x28685
leaq 0x1d34d(%rip), %rdi     # 0x459ba
leaq 0x1d498(%rip), %rsi     # 0x45b0c
movl $0x85, %edx
leaq 0x1d4ef(%rip), %rcx     # 0x45b6f
callq 0x52d0
movq 0x70(%rsp), %rdi
movq 0x1f8(%rsp), %rsi
callq 0x28b80
jmp 0x28699
movq 0x70(%rsp), %rcx
movq 0x40(%rcx), %rax
movq 0x14f8(%rax), %rax
movq 0x40(%rcx), %rcx
cmpq 0x1500(%rcx), %rax
setae %al
andb $0x1, %al
movb %al, 0x217(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x2ab70
jmp 0x28b54
leaq 0x1e0(%rsp), %rdi
callq 0x2ab70
jmp 0x28b65
jmp 0x286e6
movq 0x1f8(%rsp), %rdi
addq $0x18, %rdi
callq 0x2abb0
movq %rax, 0x118(%rsp)
movq 0x1f8(%rsp), %rdi
addq $0x18, %rdi
callq 0x2abb0
movq %rax, %rcx
movq 0x70(%rsp), %rax
movq %rcx, 0x110(%rsp)
movq 0x40(%rax), %rax
testb $0x1, 0x150c(%rax)
je 0x288ec
movq 0x1f8(%rsp), %rax
addq $0x18, %rax
movq %rax, 0x100(%rsp)
movq 0x100(%rsp), %rdi
callq 0x2abb0
movq %rax, 0xf8(%rsp)
movq 0x100(%rsp), %rdi
callq 0x2ac00
movq %rax, 0xf0(%rsp)
movq 0xf8(%rsp), %rax
cmpq 0xf0(%rsp), %rax
je 0x28834
movq 0xf8(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq 0xe8(%rsp), %rdi
callq 0x2ac50
movl %eax, 0x10(%rsp)
movq 0x118(%rsp), %rdi
callq 0x2ac50
movl %eax, %ecx
movl 0x10(%rsp), %eax
cmpl %ecx, %eax
ja 0x287df
movq 0x118(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0x118(%rsp)
jmp 0x28819
movq 0xe8(%rsp), %rdi
callq 0x2ac50
movl %eax, 0xc(%rsp)
movq 0x110(%rsp), %rdi
callq 0x2ac50
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jae 0x28817
movq 0xe8(%rsp), %rax
movq %rax, 0x110(%rsp)
jmp 0x28819
jmp 0x2881b
movq 0xf8(%rsp), %rax
addq $0x20, %rax
movq %rax, 0xf8(%rsp)
jmp 0x2876f
movl $0x1ffffffe, 0xe4(%rsp) # imm = 0x1FFFFFFE
movl 0x1ec(%rsp), %eax
movq 0x118(%rsp), %rcx
movl (%rcx), %ecx
addl %ecx, %eax
movq 0x1f8(%rsp), %rcx
movl 0x4(%rcx), %ecx
subl %ecx, %eax
movl %eax, 0xe0(%rsp)
leaq 0xe4(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x2ac70
movq %rax, %rcx
movq 0x70(%rsp), %rax
movl (%rcx), %ecx
movl %ecx, 0x10c(%rsp)
movq 0x110(%rsp), %rcx
vcvtusi2sdl 0x4(%rcx), %xmm0, %xmm1
movq 0x40(%rax), %rax
vmovss 0x1510(%rax), %xmm2
vcvtss2sd %xmm2, %xmm0, %xmm0
vmovsd 0x1a75d(%rip), %xmm2    # 0x43010
vaddsd %xmm2, %xmm0, %xmm0
vfmadd213sd %xmm2, %xmm1, %xmm0 # xmm0 = (xmm1 * xmm0) + xmm2
vcvttsd2usi %xmm0, %eax
movl %eax, 0xdc(%rsp)
leaq 0x1f0(%rsp), %rdi
leaq 0xdc(%rsp), %rsi
callq 0x2ac70
movl (%rax), %eax
movl %eax, 0x108(%rsp)
jmp 0x289b4
movl $0x0, 0x108(%rsp)
movl $0x0, 0x10c(%rsp)
movq 0x1f8(%rsp), %rax
addq $0x18, %rax
movq %rax, 0xd0(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x2abb0
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x2ac00
movq %rax, 0xc0(%rsp)
movq 0xc8(%rsp), %rax
cmpq 0xc0(%rsp), %rax
je 0x289b2
movq 0xc8(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0x118(%rsp), %rdi
callq 0x2ac50
movl %eax, 0x8(%rsp)
movq 0xb8(%rsp), %rdi
callq 0x2ac50
movl %eax, %ecx
movl 0x8(%rsp), %eax
cmpl %ecx, %eax
jbe 0x2899a
movq 0xb8(%rsp), %rax
movq %rax, 0x118(%rsp)
jmp 0x2899c
movq 0xc8(%rsp), %rax
addq $0x20, %rax
movq %rax, 0xc8(%rsp)
jmp 0x28940
jmp 0x289b4
movq 0x200(%rsp), %rsi
leaq 0x90(%rsp), %rdi
movl $0x28, %edx
callq 0x5380
movq 0x118(%rsp), %rax
movw 0x12(%rax), %ax
movw %ax, 0x8e(%rsp)
leaq 0x90(%rsp), %rdi
movzwl 0x8e(%rsp), %esi
callq 0x14c70
movq 0x118(%rsp), %rdi
callq 0x2acb0
movq 0x70(%rsp), %rdi
movq 0x68(%rdi), %rax
movq %rax, 0x80(%rsp)
movq 0x118(%rsp), %rdx
movl 0x1f4(%rsp), %ecx
addl $0x1, %ecx
movl 0x10c(%rsp), %r8d
movl 0x108(%rsp), %r9d
leaq 0x90(%rsp), %rsi
callq 0x281d0
andb $0x1, %al
movb %al, 0x124(%rsp)
movq 0x118(%rsp), %rdi
callq 0x2ace0
movq 0x70(%rsp), %rax
movq 0x118(%rsp), %rdi
addq $0x8, %rdi
movq 0x68(%rax), %rax
subq 0x80(%rsp), %rax
movq %rax, 0x78(%rsp)
leaq 0x78(%rsp), %rsi
callq 0x26990
movq 0x70(%rsp), %rdi
movq 0x1f8(%rsp), %rsi
callq 0x28b80
testb $0x1, %al
jne 0x28a9e
jmp 0x28ab5
movq 0x70(%rsp), %rax
movq 0x40(%rax), %rax
testb $0x1, 0x150c(%rax)
jne 0x28ab5
jmp 0x28b44
jmp 0x28ab7
movq 0x70(%rsp), %rax
movq 0x40(%rax), %rax
movb 0x8(%rax), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x7(%rsp)
jne 0x28b38
xorl %eax, %eax
testb $0x1, 0x124(%rsp)
movb %al, 0x7(%rsp)
je 0x28b38
movq 0x70(%rsp), %rax
movq 0x40(%rax), %rcx
movb $0x1, %al
testb $0x1, 0x150c(%rcx)
movb %al, 0x6(%rsp)
je 0x28b30
movq 0x1f8(%rsp), %rax
movl (%rax), %ecx
xorl %eax, %eax
cmpl 0x1f0(%rsp), %ecx
movb %al, 0x5(%rsp)
jae 0x28b28
movq 0x1f8(%rsp), %rax
movl 0x4(%rax), %eax
cmpl 0x1ec(%rsp), %eax
setb %al
movb %al, 0x5(%rsp)
movb 0x5(%rsp), %al
movb %al, 0x6(%rsp)
movb 0x6(%rsp), %al
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
testb $0x1, %al
jne 0x286e6
movb 0x124(%rsp), %al
andb $0x1, %al
movb %al, 0x217(%rsp)
movb 0x217(%rsp), %al
andb $0x1, %al
addq $0x218, %rsp            # imm = 0x218
retq
movq 0x1d8(%rsp), %rdi
callq 0x57a0
nopw %cs:(%rax,%rax)