// File: tewalds[P]morat/hex/agentmctsthread.cpp
// Function: Morat::Hex::AgentMCTS::AgentThread::walk_tree(Morat::Hex::Board&, Morat::Hex::AgentMCTS::Node*, int)
void AgentMCTS::AgentThread::walk_tree(Board & board, Node * node, int depth){
	Side to_play = board.to_play();

	if(!node->children.empty() && node->outcome < Outcome::DRAW){
	//choose a child and recurse
		Node * child;
		do{
			int remain = board.moves_remain();
			child = choose_move(node, to_play, remain);

			if(child->outcome < Outcome::DRAW){
				movelist.addtree(child->move, to_play);

				if(!board.move(child->move)){
					logerr("move failed: " + child->move.to_s() + "\n" + board.to_s(true));
					assert(false && "move failed");
				}

				child->exp.addvloss(); //balanced out after rollouts

				walk_tree(board, child, depth+1);

				child->exp.addv(movelist.getexp(to_play));

				if(!agent->do_backup(node, child, to_play) && //not solved
					agent->ravefactor > min_rave &&  //using rave
					node->children.num() > 1 &&       //not a macro move
					50*remain*(agent->ravefactor + agent->decrrave*remain) > node->exp.num()) //rave is still significant
					update_rave(node, to_play);

				return;
			}
		}while(!agent->do_backup(node, child, to_play));

		return;
	}

	if(agent->profile && stage == 0){
		stage = 1;
		timestamps[1] = Time();
	}

	Outcome won = (agent->minimax ? node->outcome : board.outcome());

	//if it's not already decided
	if(won < Outcome::DRAW){
		//create children if valid
		if(node->exp.num() >= agent->visitexpand+1 && create_children(board, node)){
			walk_tree(board, node, depth);
			return;
		}

		if(agent->profile){
			stage = 2;
			timestamps[2] = Time();
		}

		//do random game on this node
		random_policy.prepare(board);
		for(int i = 0; i < agent->rollouts; i++){
			Board copy = board;
			rollout(copy, node->move, depth);
		}
	}else{
		movelist.finishrollout(won); //got to a terminal state, it's worth recording
	}

	treelen.add(depth);

	movelist.subvlosses(1);

	if(agent->profile){
		timestamps[3] = Time();
		if(stage == 1)
			timestamps[2] = timestamps[3];
		stage = 3;
	}

	return;
}

// Assembly:
subq $0x188, %rsp            # imm = 0x188
movq %rdi, 0x180(%rsp)
movq %rsi, 0x178(%rsp)
movq %rdx, 0x170(%rsp)
movl %ecx, 0x16c(%rsp)
movq 0x180(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x178(%rsp), %rdi
callq 0x1a8a0
movb %al, 0x16b(%rsp)
movq 0x170(%rsp), %rdi
addq $0x28, %rdi
callq 0x1b500
testb $0x1, %al
jne 0x26b12
movq 0x170(%rsp), %rdi
addq $0x22, %rdi
leaq 0x46e00(%rip), %rsi     # 0x6d4c3
callq 0x1b520
testb $0x1, %al
jne 0x266d1
jmp 0x26b12
jmp 0x266d3
movq 0x178(%rsp), %rdi
callq 0x28e80
movq 0x20(%rsp), %rdi
movl %eax, 0x15c(%rsp)
movq 0x170(%rsp), %rsi
movb 0x16b(%rsp), %al
movb %al, 0x15b(%rsp)
movl 0x15c(%rsp), %ecx
movzbl 0x15b(%rsp), %edx
callq 0x26e00
movq %rax, 0x160(%rsp)
movq 0x160(%rsp), %rdi
addq $0x22, %rdi
leaq 0x46d92(%rip), %rsi     # 0x6d4c3
callq 0x1b520
testb $0x1, %al
jne 0x2673f
jmp 0x26acd
movq 0x20(%rsp), %rdi
addq $0xcb78, %rdi           # imm = 0xCB78
movq 0x160(%rsp), %rsi
addq $0x24, %rsi
movb 0x16b(%rsp), %al
movb %al, 0x15a(%rsp)
movzbl 0x15a(%rsp), %edx
callq 0x28e90
movq 0x178(%rsp), %rdi
movq 0x160(%rsp), %rsi
addq $0x24, %rsi
movl $0x1, %ecx
movl %ecx, %edx
callq 0x1c500
testb $0x1, %al
jne 0x26950
movq 0x160(%rsp), %rsi
addq $0x24, %rsi
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x19f80
movq 0x18(%rsp), %rdx
leaq 0x27d0c(%rip), %rsi     # 0x4e4d0
leaq 0xf8(%rsp), %rdi
callq 0x19f30
jmp 0x267d3
leaq 0x2610e(%rip), %rdx     # 0x4c8e8
leaq 0x118(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0xb910
jmp 0x267f1
movq 0x178(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
movl $0x1, %edx
callq 0x35f30
jmp 0x2680d
leaq 0x138(%rsp), %rdi
leaq 0x118(%rsp), %rsi
leaq 0xa8(%rsp), %rdx
callq 0x19e40
jmp 0x2682c
leaq 0x138(%rsp), %rdi
callq 0x1a9b0
jmp 0x2683b
leaq 0x138(%rsp), %rdi
callq 0x5260
leaq 0xa8(%rsp), %rdi
callq 0x5260
leaq 0x118(%rsp), %rdi
callq 0x5260
leaq 0xf8(%rsp), %rdi
callq 0x5260
leaq 0xd8(%rsp), %rdi
callq 0x5260
leaq 0x27c5b(%rip), %rdi     # 0x4e4de
leaq 0x27c6b(%rip), %rsi     # 0x4e4f5
movl $0x33, %edx
leaq 0x27c77(%rip), %rcx     # 0x4e50d
callq 0x52a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
jmp 0x2693e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
jmp 0x26931
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
jmp 0x26924
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
jmp 0x26917
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x5260
leaq 0xa8(%rsp), %rdi
callq 0x5260
leaq 0x118(%rsp), %rdi
callq 0x5260
leaq 0xf8(%rsp), %rdi
callq 0x5260
leaq 0xd8(%rsp), %rdi
callq 0x5260
jmp 0x26de7
movq 0x160(%rsp), %rdi
addq $0x10, %rdi
callq 0x28d90
movq 0x20(%rsp), %rdi
movq 0x178(%rsp), %rsi
movq 0x160(%rsp), %rdx
movl 0x16c(%rsp), %ecx
addl $0x1, %ecx
callq 0x26650
movq 0x20(%rsp), %rdi
movq 0x160(%rsp), %rax
addq $0x10, %rax
movq %rax, 0x10(%rsp)
addq $0xcb78, %rdi           # imm = 0xCB78
movb 0x16b(%rsp), %al
movb %al, 0xa7(%rsp)
movzbl 0xa7(%rsp), %esi
callq 0x28e40
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x28de0
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rdi
movq 0x170(%rsp), %rsi
movq 0x160(%rsp), %rdx
movb 0x16b(%rsp), %al
movb %al, 0xa6(%rsp)
movzbl 0xa6(%rsp), %ecx
callq 0x27110
testb $0x1, %al
jne 0x26ac8
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rax
vmovss 0x7c(%rax), %xmm0
leaq 0x26865(%rip), %rax     # 0x4d280
vucomiss (%rax), %xmm0
jbe 0x26ac8
movq 0x170(%rsp), %rdi
addq $0x28, %rdi
callq 0x1a560
cmpl $0x1, %eax
jbe 0x26ac8
movq 0x20(%rsp), %rax
imull $0x32, 0x15c(%rsp), %ecx
vcvtsi2ss %ecx, %xmm0, %xmm0
movq 0x40(%rax), %rcx
vmovss 0x7c(%rcx), %xmm3
movq 0x40(%rax), %rax
vmovss 0x80(%rax), %xmm2
vcvtsi2ssl 0x15c(%rsp), %xmm1, %xmm1
vfmadd213ss %xmm3, %xmm2, %xmm1 # xmm1 = (xmm2 * xmm1) + xmm3
vmulss %xmm1, %xmm0, %xmm0
vmovss %xmm0, 0xc(%rsp)
movq 0x170(%rsp), %rdi
addq $0x10, %rdi
callq 0x1c800
vmovss 0xc(%rsp), %xmm0
vcvtusi2ss %rax, %xmm1, %xmm1
vucomiss %xmm1, %xmm0
jbe 0x26ac8
movq 0x20(%rsp), %rdi
movq 0x170(%rsp), %rsi
movb 0x16b(%rsp), %al
movb %al, 0xa5(%rsp)
movzbl 0xa5(%rsp), %edx
callq 0x27720
jmp 0x26ddf
jmp 0x26acf
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rdi
movq 0x170(%rsp), %rsi
movq 0x160(%rsp), %rdx
movb 0x16b(%rsp), %al
movb %al, 0xa4(%rsp)
movzbl 0xa4(%rsp), %ecx
callq 0x27110
xorb $-0x1, %al
testb $0x1, %al
jne 0x266d3
jmp 0x26ddf
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rax
testb $0x1, 0x68(%rax)
je 0x26b5f
movq 0x20(%rsp), %rax
cmpl $0x0, 0x12120(%rax)
jne 0x26b5f
movq 0x20(%rsp), %rax
movl $0x1, 0x12120(%rax)
leaq 0x98(%rsp), %rdi
callq 0x6780
movq 0x20(%rsp), %rax
movq 0x98(%rsp), %rcx
movq %rcx, 0x121d0(%rax)
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rax
cmpl $0x0, 0xa4(%rax)
je 0x26b85
movq 0x170(%rsp), %rax
movb 0x22(%rax), %al
movb %al, 0x97(%rsp)
jmp 0x26b99
movq 0x178(%rsp), %rdi
callq 0x1a900
movb %al, 0x97(%rsp)
leaq 0x97(%rsp), %rdi
leaq 0x4691b(%rip), %rsi     # 0x6d4c3
callq 0x1b520
testb $0x1, %al
jne 0x26bb6
jmp 0x26d39
movq 0x170(%rsp), %rdi
addq $0x10, %rdi
callq 0x1c800
movq 0x20(%rsp), %rcx
movq 0x40(%rcx), %rcx
movl 0xa8(%rcx), %ecx
addl $0x1, %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
jb 0x26c26
movq 0x20(%rsp), %rdi
movq 0x178(%rsp), %rsi
movq 0x170(%rsp), %rdx
callq 0x277d0
testb $0x1, %al
jne 0x26c00
jmp 0x26c26
movq 0x20(%rsp), %rdi
movq 0x178(%rsp), %rsi
movq 0x170(%rsp), %rdx
movl 0x16c(%rsp), %ecx
callq 0x26650
jmp 0x26ddf
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rax
testb $0x1, 0x68(%rax)
je 0x26c65
movq 0x20(%rsp), %rax
movl $0x2, 0x12120(%rax)
leaq 0x88(%rsp), %rdi
callq 0x6780
movq 0x20(%rsp), %rax
movq 0x88(%rsp), %rcx
movq %rcx, 0x121d8(%rax)
movq 0x20(%rsp), %rdi
addq $0xa14, %rdi            # imm = 0xA14
movq 0x178(%rsp), %rsi
callq 0x28f10
movl $0x0, 0x84(%rsp)
movq 0x20(%rsp), %rcx
movl 0x84(%rsp), %eax
movq 0x40(%rcx), %rcx
cmpl 0x94(%rcx), %eax
jge 0x26d37
movq 0x178(%rsp), %rsi
leaq 0x38(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x118b0
movq 0x20(%rsp), %rdi
movq (%rsp), %rsi
movq 0x170(%rsp), %rax
movw 0x24(%rax), %ax
movw %ax, 0x36(%rsp)
movl 0x16c(%rsp), %ecx
movzwl 0x36(%rsp), %edx
callq 0x28120
movb %al, 0xb(%rsp)
jmp 0x26cec
movb 0xb(%rsp), %al
movb %al, 0x35(%rsp)
leaq 0x38(%rsp), %rdi
callq 0xc040
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x26c89
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0x38(%rsp), %rdi
callq 0xc040
jmp 0x26de7
jmp 0x26d5a
movq 0x20(%rsp), %rdi
addq $0xcb78, %rdi           # imm = 0xCB78
movb 0x97(%rsp), %al
movb %al, 0x34(%rsp)
movzbl 0x34(%rsp), %esi
callq 0x28ff0
movq 0x20(%rsp), %rdi
addq $0x12128, %rdi          # imm = 0x12128
movl 0x16c(%rsp), %esi
callq 0x29180
movq 0x20(%rsp), %rdi
addq $0xcb78, %rdi           # imm = 0xCB78
movl $0x1, %esi
callq 0x291f0
movq 0x20(%rsp), %rax
movq 0x40(%rax), %rax
testb $0x1, 0x68(%rax)
je 0x26ddd
leaq 0x28(%rsp), %rdi
callq 0x6780
movq 0x20(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, 0x121e0(%rax)
cmpl $0x1, 0x12120(%rax)
jne 0x26dce
movq 0x20(%rsp), %rax
movq 0x121e0(%rax), %rcx
movq %rcx, 0x121d8(%rax)
movq 0x20(%rsp), %rax
movl $0x3, 0x12120(%rax)
jmp 0x26ddf
addq $0x188, %rsp            # imm = 0x188
retq
movq 0xd0(%rsp), %rdi
callq 0x5760
nopw %cs:(%rax,%rax)