// File: /workspace/github_cpp_makefile_star2_O1/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 $0x68, %rsp
movl $0x3, %edi
subl %ecx, %edi
movl %ecx, %eax
negl %eax
movl %eax, 0x4(%rsp)
leal -0x3(%rcx), %eax
movl %eax, (%rsp)
movsbl 0x12(%rsi), %eax
testl %eax, %eax
jns 0x216fe
movsbl 0x12(%rdx), %r8d
cmpl $-0x3, %r8d
je 0x216fa
movb 0x13(%rdx), %r11b
cmpl %ecx, %r8d
je 0x216d5
movq 0x20(%rsi), %r8
leaq 0x10(%r8), %rdx
movl $0x0, %ebx
movl $0x0, %r14d
cmpq $0x2, %r8
cmovaeq %rdx, %rbx
jb 0x215d7
movzwl 0x6(%r8), %r8d
leaq (%r8,%r8,4), %r8
leaq (%rdx,%r8,8), %r14
cmpq %r14, %rbx
je 0x216cb
xorl %edx, %edx
cmpl %eax, (%rsp)
sete %dl
leaq 0x2(%rdx,%rdx), %r15
xorl %edx, %edx
xorl %r10d, %r10d
xorl %r9d, %r9d
movsbl 0x12(%rbx), %r8d
movb 0x13(%rbx), %r13b
leal 0x1(%r13), %r12d
cmpb %r11b, %r13b
movzbl %r11b, %ebp
movzbl %r12b, %r11d
cmovbl %ebp, %r11d
cmpl $-0x3, %r8d
jne 0x21633
xorl %r8d, %r8d
movl $0x3, %r12d
movq 0x8(%rbx), %r13
cmpq %r12, %r10
jae 0x21643
xorl %ebp, %ebp
movq %r13, %r9
movq %r12, %r10
jmp 0x2163e
movb $0x1, %bpl
cmpl %ecx, %r8d
jne 0x2166b
movl %r12d, %r11d
movq %rbx, %rdx
jmp 0x2167a
jne 0x21678
cmpq %r13, %r9
setb %bpl
seta %r12b
andb %bpl, %r8b
orb %r12b, %r8b
movq %rbx, %r8
jne 0x21661
movq %r9, %r13
movq %rdx, %r8
xorl %ebp, %ebp
movq %r13, %r9
movq %r8, %rdx
jmp 0x2167a
cmpl %r8d, %edi
jne 0x2168e
movb $0x1, %r8b
xorl %r12d, %r12d
jmp 0x21620
xorl %ebp, %ebp
testb %bpl, %bpl
jne 0x216c1
addq $0x28, %rbx
cmpq %r14, %rbx
jne 0x215f5
jmp 0x216c1
testb %r8b, %r8b
je 0x216a2
cmpl 0x4(%rsp), %r8d
jne 0x216ad
movl $0x5, %r12d
jmp 0x216b9
xorl %r8d, %r8d
movq %r15, %r12
jmp 0x21620
cmpl %r8d, (%rsp)
jne 0x2170f
movl $0x1, %r12d
xorl %r8d, %r8d
jmp 0x21620
cmpq $0x3, %r10
sete %r8b
jmp 0x216d0
xorl %r8d, %r8d
xorl %edx, %edx
testb %r8b, %r8b
jne 0x216fa
movb 0x12(%rdx), %r8b
lock
cmpxchgb %r8b, 0x12(%rsi)
jne 0x21585
movzwl 0x14(%rdx), %eax
movw %ax, 0x18(%rsi)
movb %r11b, 0x13(%rsi)
cmpb $0x0, 0x12(%rsi)
setns %al
jmp 0x21700
xorl %eax, %eax
jmp 0x21700
movb $0x1, %al
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
movl %r8d, %esi
callq 0xd56b
leaq 0xba85(%rip), %rsi      # 0x2d1ab
leaq 0x8(%rsp), %rdi
movq %rbx, %rdx
callq 0x21c5e
leaq 0x83a8(%rip), %rdx      # 0x29ae2
leaq 0x48(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x21c09
leaq 0x48(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x28(%rsp), %rdx
callq 0x4a01
movq %rax, %rbx
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x21778
callq 0x42b0
jmp 0x21778
movq %rax, %rbx
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x2178b
callq 0x42b0
movq %rbx, %rdi
callq 0x45b0
nop