// File: /workspace/github_cpp_makefile_star2_O3/tewalds[P]pentagod/agentmctsthread.cpp
// Function: AgentMCTS::do_backup(AgentMCTS::Node*, AgentMCTS::Node*, int)
bool AgentMCTS::do_backup(Node * node, Node * backup, int toplay){
	int nodeoutcome = node->outcome;
	if(nodeoutcome >= 0) //already proven, probably by a different thread
		return true;

	if(backup->outcome == -3) //nothing proven by this child, so no chance
		return false;


	uint8_t proofdepth = backup->proofdepth;
	if(backup->outcome != toplay){
		uint64_t sims = 0, bestsims = 0, outcome = 0, bestoutcome = 0;
		backup = NULL;

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

		for( ; child != end; child++){
			int childoutcome = child->outcome; //save a copy to avoid race conditions

			if(proofdepth < child->proofdepth+1)
				proofdepth = child->proofdepth+1;

			//these should be sorted in likelyness of matching, most likely first
			if(childoutcome == -3){ // win/draw/loss
				outcome = 3;
			}else if(childoutcome == toplay){ //win
				backup = child;
				outcome = 6;
				proofdepth = child->proofdepth+1;
				break;
			}else if(childoutcome == 3-toplay){ //loss
				outcome = 0;
			}else if(childoutcome == 0){ //draw
				if(nodeoutcome == toplay-3) //draw/loss
					outcome = 4;
				else
					outcome = 2;
			}else if(childoutcome == -toplay){ //win/draw
				outcome = 5;
			}else if(childoutcome == toplay-3){ //draw/loss
				outcome = 1;
			}else{
				logerr("childoutcome == " + to_str(childoutcome) + "\n");
				assert(false && "How'd I get here? All outcomes should be tested above");
			}

			sims = child->exp.num();
			if(bestoutcome < outcome){ //better outcome is always preferable
				bestoutcome = outcome;
				bestsims = sims;
				backup = child;
			}else if(bestoutcome == outcome && ((outcome == 0 && bestsims < sims) || bestsims > sims)){
				//find long losses or easy wins/draws
				bestsims = sims;
				backup = child;
			}
		}

		if(bestoutcome == 3) //no win, but found an unknown
			return false;
	}

	if(CAS(node->outcome, nodeoutcome, backup->outcome)){
		node->bestmove = backup->move;
		node->proofdepth = proofdepth;
	}else //if it was in a race, try again, might promote a partial solve to full solve
		return do_backup(node, backup, toplay);

	return (node->outcome >= 0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl $0x3, %r9d
movl %ecx, %eax
negl %eax
leal -0x3(%rcx), %edi
subl %ecx, %r9d
movl %eax, 0xc(%rsp)
movl %edi, 0x8(%rsp)
movsbl 0x12(%rsi), %eax
testl %eax, %eax
setns %dil
jns 0x21091
movsbl 0x12(%rdx), %r8d
cmpl $-0x3, %r8d
je 0x21096
movb 0x13(%rdx), %bl
cmpl %ecx, %r8d
je 0x21070
movq 0x20(%rsi), %r8
movl $0x0, %r14d
movl $0x0, %r15d
leaq 0x10(%r8), %rdx
cmpq $0x2, %r8
cmovaeq %rdx, %r14
jb 0x20f8e
movzwl 0x6(%r8), %r8d
leaq (%r8,%r8,4), %r8
leaq (%rdx,%r8,8), %r15
xorl %edx, %edx
cmpl %eax, 0x8(%rsp)
sete %dl
xorl %r10d, %r10d
xorl %ebp, %ebp
leaq 0x2(%rdx,%rdx), %rdx
movq %rdx, 0x10(%rsp)
xorl %edx, %edx
movb 0x13(%r14), %r12b
movsbl 0x12(%r14), %r8d
leal 0x1(%r12), %r11d
cmpb %bl, %r12b
movzbl %bl, %r12d
movzbl %r11b, %ebx
cmovbl %r12d, %ebx
cmpl $-0x3, %r8d
jne 0x20fd6
movl $0x3, %r12d
xorl %r11d, %r11d
jmp 0x20fea
cmpl %ecx, %r8d
je 0x21060
cmpl %r8d, %r9d
jne 0x21033
movb $0x1, %r11b
xorl %r12d, %r12d
movq 0x8(%r14), %r8
cmpq %r12, %r10
jae 0x20ffb
movq %r12, %r10
movq %r14, %rdx
jmp 0x21021
jne 0x2101e
cmpq %r8, %rbp
setb %r12b
seta %r13b
andb %r12b, %r11b
orb %r13b, %r11b
movq %r14, %r11
jne 0x21019
movq %rbp, %r8
movq %rdx, %r11
movq %r11, %rdx
jmp 0x21021
movq %rbp, %r8
addq $0x28, %r14
movq %r8, %rbp
cmpq %r15, %r14
jne 0x20fa8
jmp 0x21066
testb %r8b, %r8b
je 0x21047
cmpl 0xc(%rsp), %r8d
jne 0x2104e
movl $0x5, %r12d
jmp 0x20fd1
movq 0x10(%rsp), %r12
jmp 0x20fd1
cmpl %r8d, 0x8(%rsp)
jne 0x210a9
movl $0x1, %r12d
jmp 0x20fd1
movl %r11d, %ebx
movq %r14, %rdx
cmpq $0x3, %r10
je 0x21098
movb 0x12(%rdx), %r8b
lock
cmpxchgb %r8b, 0x12(%rsi)
jne 0x20f38
movzwl 0x14(%rdx), %eax
movw %ax, 0x18(%rsi)
movb %bl, 0x13(%rsi)
cmpb $0x0, 0x12(%rsi)
setns %dil
jmp 0x21098
movb $0x1, %dil
jmp 0x21098
xorl %edi, %edi
movl %edi, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x38(%rsp), %rbx
movl %r8d, %esi
movq %rbx, %rdi
callq 0xd4eb
leaq 0xb0eb(%rip), %rsi      # 0x2c1ab
leaq 0x18(%rsp), %rdi
movq %rbx, %rdx
callq 0x21634
leaq 0x7a0e(%rip), %rdx      # 0x28ae2
leaq 0x58(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x215df
leaq 0x58(%rsp), %rdi
leaq 0x18(%rsp), %rsi
leaq 0x38(%rsp), %rdx
callq 0x4a6f
leaq 0x28(%rsp), %rcx
movq %rax, %rbx
movq -0x10(%rcx), %rdi
cmpq %rcx, %rdi
je 0x21112
callq 0x42b0
jmp 0x21112
movq %rax, %rbx
leaq 0x48(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x21125
callq 0x42b0
movq %rbx, %rdi
callq 0x45b0
nop