// File: /workspace/github_cpp_makefile_star2_O3/ShootMe[P]Klondike-Solver/Solitaire.cpp
// Function: SolitaireWorker::Run(int)
SolveResult SolitaireWorker::Run(int numThreads) {
	solitaire->MakeAutoMoves();
	if (solitaire->MovesAvailableCount() == 0) { return solitaire->FoundationCount() == 52 ? SolvedMinimal : Impossible; }

	openCount = 1;
	maxFoundationCount = solitaire->FoundationCount();
	bestSolutionMoveCount = 512;
	bestSolution[0].Count = 255;
	startMoves = solitaire->MinimumMovesLeft() + solitaire->MovesMadeNormalizedCount();
	int powerOf2 = 1;
	while (maxClosedCount > (1 << (powerOf2 + 2))) {
		powerOf2++;
	}
	HashMap<int> * closed = new HashMap<int>(powerOf2);

	shared_ptr<MoveNode> firstNode = solitaire->MovesMadeCount() > 0 ? make_shared<MoveNode>(solitaire->GetMoveMade(solitaire->MovesMadeCount() - 1)) : NULL;
	shared_ptr<MoveNode> node = firstNode;
	for (int i = solitaire->MovesMadeCount() - 2; i >= 0; i--) {
		node->Parent = make_shared<MoveNode>(solitaire->GetMoveMade(i));
		node = node->Parent;
	}
	open[startMoves].push(firstNode);

	thread * threads = new thread[numThreads];
	for (int i = 0; i < numThreads; i++) {
		threads[i] = thread(&SolitaireWorker::RunMinimalWorker, this, (void*)closed);
		this_thread::sleep_for(chrono::milliseconds(23));
	}

	for (int i = 0; i < numThreads; i++) {
		threads[i].join();
	}
	delete[] threads;

	//Reset game to best solution found
	solitaire->ResetGame();
	for (int i = 0; bestSolution[i].Count < 255; i++) {
		solitaire->MakeMove(bestSolution[i]);
	}

	SolveResult result = closed->Size() >= maxClosedCount ? (maxFoundationCount == 52 ? SolvedMayNotBeMinimal : CouldNotComplete) : (maxFoundationCount == 52 ? SolvedMinimal : Impossible);
	delete closed;
	return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %esi, %ebp
movq %rdi, %rbx
movq 0xa800(%rdi), %rdi
callq 0x54ec
movq 0xa800(%rbx), %rdi
cmpl $0x0, 0x1910(%rdi)
je 0x51d8
movl %ebp, 0x1c(%rsp)
movl $0x1, 0xa830(%rbx)
movl 0x190c(%rdi), %eax
movl %eax, 0xa834(%rbx)
movl $0x200, 0xa838(%rbx)    # imm = 0x200
movb $-0x1, 0xa002(%rbx)
callq 0x4b36
movl %eax, %ebp
movq 0xa800(%rbx), %rdi
callq 0x4a7e
addl %ebp, %eax
movl %eax, 0xa83c(%rbx)
movl 0xa840(%rbx), %eax
xorl %ebp, %ebp
incl %ebp
movl $0x4, %edx
movl %ebp, %ecx
shll %cl, %edx
cmpl %edx, %eax
jg 0x514b
movl $0x20, %edi
callq 0x21c0
movq %rax, 0x30(%rsp)
movq %rax, %rdi
movl %ebp, %esi
callq 0x916a
movq 0xa800(%rbx), %rax
movl 0x1914(%rax), %ecx
testl %ecx, %ecx
jle 0x51ea
decl %ecx
movl (%rax,%rcx,4), %eax
movq %rsp, %rcx
movl %eax, (%rcx)
leaq 0x48(%rsp), %rdi
movq $0x0, -0x8(%rdi)
leaq 0x40(%rsp), %r14
leaq 0x20(%rsp), %r15
movq %r14, %rsi
movq %r15, %rdx
callq 0x99be
movq (%r14), %rcx
movq 0x8(%r14), %rax
movq %rcx, (%r15)
leaq 0x28(%rsp), %r15
movq %rax, (%r15)
testq %rax, %rax
je 0x5202
movq 0x8e02(%rip), %rcx      # 0xdfd0
cmpb $0x0, (%rcx)
je 0x51fe
incl 0x8(%rax)
jmp 0x5202
xorl %ebp, %ebp
cmpl $0x34, 0x190c(%rdi)
sete %bpl
jmp 0x548c
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
leaq 0x28(%rsp), %r15
movaps %xmm0, -0x8(%r15)
jmp 0x5202
lock
incl 0x8(%rax)
movq 0xa800(%rbx), %rax
movl 0x1914(%rax), %r12d
cmpl $0x2, %r12d
jl 0x52a7
addl $-0x2, %r12d
incq %r12
movq %rsp, %r13
leaq 0x58(%rsp), %rbp
leaq 0x38(%rsp), %r14
movq 0xa800(%rbx), %rax
movl -0x4(%rax,%r12,4), %eax
movl %eax, 0x38(%rsp)
movq $0x0, (%rsp)
leaq 0x8(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
movq %r14, %rcx
callq 0x99be
movq 0x20(%rsp), %rax
movaps (%rsp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
movq 0x8(%rax), %rdi
movups %xmm0, (%rax)
testq %rdi, %rdi
je 0x527a
callq 0x3748
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x5289
callq 0x3748
movq 0x20(%rsp), %rsi
movq (%rsi), %rax
movq %rax, 0x20(%rsp)
addq $0x8, %rsi
movq %r15, %rdi
callq 0x37b8
decq %r12
jg 0x522e
movslq 0xa83c(%rbx), %rax
leaq (%rax,%rax,4), %rdi
shlq $0x4, %rdi
addq %rbx, %rdi
leaq 0x40(%rsp), %rsi
callq 0x971a
movl 0x1c(%rsp), %ebp
movslq %ebp, %r12
leaq (,%r12,8), %r14
movq %r14, %rdi
addq $0x8, %rdi
movq $-0x1, %rax
cmovbq %rax, %rdi
testl %r12d, %r12d
cmovsq %rax, %rdi
callq 0x2030
movq %rax, %r15
movq %r12, (%rax)
movl $0x8, %esi
testl %r12d, %r12d
je 0x53f4
movq %r15, %r13
addq $0x8, %r13
movq %r13, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x2100
testl %ebp, %ebp
jle 0x53c8
movl %ebp, %r12d
xorl %r14d, %r14d
movq %rsp, %rbp
leaq -0x1732(%rip), %rax     # 0x3bfe
movq %rax, (%rsp)
movq $0x0, 0x8(%rsp)
movq %rbx, 0x58(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x60(%rsp)
leaq 0x38(%rsp), %rdi
movq %rbp, %rsi
leaq 0x58(%rsp), %rdx
leaq 0x60(%rsp), %rcx
callq 0x91f0
cmpq $0x0, (%r13,%r14,8)
jne 0x549d
movq 0x38(%rsp), %rax
movq %rax, (%r13,%r14,8)
movq $0x0, (%rsp)
movq $0x15ef3c0, 0x8(%rsp)   # imm = 0x15EF3C0
movq %rbp, %rdi
movq %rbp, %rsi
callq 0x2080
cmpl $-0x1, %eax
jne 0x53a4
callq 0x2040
cmpl $0x4, (%rax)
je 0x538a
incq %r14
cmpq %r12, %r14
jne 0x5329
cmpl $0x0, 0x1c(%rsp)
jle 0x53c8
movq %r13, %rdi
callq 0x22b0
addq $0x8, %r13
decq %r12
jne 0x53b7
movq (%r15), %rax
testq %rax, %rax
movl $0x8, %esi
je 0x53f4
shlq $0x3, %rax
movq %rax, %rcx
cmpq $0x0, (%r15,%rcx)
jne 0x549d
addq $-0x8, %rcx
jne 0x53dc
addq $0x8, %rax
movq %rax, %rsi
movq %r15, %rdi
callq 0x2310
movq 0xa800(%rbx), %rdi
movl 0x1904(%rdi), %esi
callq 0x5958
cmpb $-0x1, 0xa002(%rbx)
je 0x5438
leaq 0xa000(%rbx), %r14
movq 0xa800(%rbx), %rdi
movl (%r14), %esi
callq 0x4232
cmpb $-0x1, 0x6(%r14)
leaq 0x4(%r14), %r14
jne 0x541e
movq 0x30(%rsp), %r14
movl 0x8(%r14), %eax
xorl %ecx, %ecx
cmpl $0x34, 0xa834(%rbx)
sete %cl
leal -0x2(%rcx), %ebp
cmpl 0xa840(%rbx), %eax
cmovll %ecx, %ebp
movq %r14, %rdi
callq 0x927a
movl $0x20, %esi
movq %r14, %rdi
callq 0x21d0
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x547d
callq 0x3748
movq 0x48(%rsp), %rdi
testq %rdi, %rdi
je 0x548c
callq 0x3748
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x2070
jmp 0x54c2
movq %rax, %rbx
movl $0x20, %esi
movq 0x30(%rsp), %rdi
callq 0x21d0
jmp 0x54e3
jmp 0x54c2
jmp 0x54c2
jmp 0x54c2
jmp 0x54c2
jmp 0x54c2
movq %rax, %rbx
movq 0x28(%rsp), %rdi
testq %rdi, %rdi
je 0x54d4
callq 0x3748
movq 0x48(%rsp), %rdi
testq %rdi, %rdi
je 0x54e3
callq 0x3748
movq %rbx, %rdi
callq 0x22e0
nop