// File: /workspace/github_cpp_makefile_star2_O1/ShootMe[P]Klondike-Solver/Solitaire.cpp
// Function: SolitaireWorker::RunMinimalWorker(void*)
void SolitaireWorker::RunMinimalWorker(void * closedPointer) {
	HashMap<int> & closed = *reinterpret_cast<HashMap<int>*>(closedPointer);
	Move movesToMake[512];
	shared_ptr<MoveNode> firstNode = NULL;
	shared_ptr<MoveNode> node = NULL;
	Solitaire s = *solitaire;
	int doneCount = 10;
	while (closed.Size() < maxClosedCount && doneCount > 0) {
		mtx.lock();
		//Check for lowest score length
		int index = startMoves;
		while (index < 512 && open[index].size() == 0) { index++; }

		//End solver if no more states
		if (index >= 512) {
			mtx.unlock();
			doneCount--;
			this_thread::sleep_for(chrono::milliseconds(1));
			continue;
		}

		doneCount = 10;

		//Get next state to evaluate
		openCount--;
		firstNode = open[index].top();
		open[index].pop();
		mtx.unlock();

		//Initialize game to the found state
		s.ResetGame();
		int movesTotal = 0;
		node = firstNode;
		while (node != NULL) {
			movesToMake[movesTotal++] = node->Value;
			node = node->Parent;
		}
		while (movesTotal > 0) {
			s.MakeMove(movesToMake[--movesTotal]);
		}

		//Make any auto moves
		s.UpdateAvailableMoves();
		while (s.MovesAvailableCount() == 1) {
			Move move = s.GetMoveAvailable(0);
			s.MakeMove(move);
			firstNode = make_shared<MoveNode>(move, firstNode);
			s.UpdateAvailableMoves();
		}
		movesTotal = s.MovesMadeNormalizedCount();


		//Check for best solution to foundations
		if (s.FoundationCount() > maxFoundationCount || (s.FoundationCount() == maxFoundationCount && bestSolutionMoveCount > movesTotal)) {
			mtx.lock();
			if (s.FoundationCount() > maxFoundationCount || (s.FoundationCount() == maxFoundationCount && bestSolutionMoveCount > movesTotal)) {
				bestSolutionMoveCount = movesTotal;
				maxFoundationCount = s.FoundationCount();

				//Save solution
				for (int i = s.MovesMadeCount() - 1; i >= 0; i--) {
					bestSolution[i] = s[i];
				}
				bestSolution[s.MovesMadeCount()].Count = 255;
			}
			mtx.unlock();
		} else if (maxFoundationCount == 52) {
			//Dont check state if above or equal to current best solution
			int helper = s.MinimumMovesLeft();
			helper += movesTotal;
			if (helper >= bestSolutionMoveCount) { continue; }
		}

		int movesAvailableCount = s.MovesAvailableCount();
		//Make available moves and add them to be evaulated
		for (int i = 0; i < movesAvailableCount; i++) {
			Move move = s.GetMoveAvailable(i);
			int movesAdded = s.MovesAdded(move);

			s.MakeMove(move);

			movesAdded += movesTotal;
			movesAdded += s.MinimumMovesLeft();
			if (maxFoundationCount < 52 || movesAdded < bestSolutionMoveCount) {
				int helper = movesAdded;
				helper += 52 - s.FoundationCount() + s.RoundCount();
				HashKey key = s.GameState();

				mtx.lock();
				KeyValue<int> * result = closed.Add(key, movesAdded);
				if (result == NULL || result->Value > movesAdded) {
					node = make_shared<MoveNode>(move, firstNode);
					if (result != NULL) { result->Value = movesAdded; }

					openCount++;
					open[helper].push(node);
				}
				mtx.unlock();
			}

			s.UndoMove();
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x21b8, %rsp           # imm = 0x21B8
movq %rsi, 0x80(%rsp)
movq %rdi, 0x8(%rsp)
xorl %ebx, %ebx
leaq (%rsp,%rbx), %rdi
addq $0x19b0, %rdi           # imm = 0x19B0
callq 0x373c
addq $0x4, %rbx
cmpq $0x800, %rbx            # imm = 0x800
jne 0x3c66
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movq 0x8(%rsp), %rbx
movq 0xa800(%rbx), %rsi
leaq 0x98(%rsp), %rdi
movl $0x1918, %edx           # imm = 0x1918
callq 0x2180
movq 0x80(%rsp), %rax
movl 0x8(%rax), %eax
cmpl 0xa840(%rbx), %eax
jge 0x420f
movq 0x8(%rsp), %rax
leaq 0xa808(%rax), %rcx
movq %rcx, 0x20(%rsp)
leaq 0x48(%rsp), %r14
leaq 0x38(%rsp), %r15
leaq 0x58(%rsp), %r13
leaq 0xa000(%rax), %rcx
movq %rcx, 0x88(%rsp)
addq $0x48, %rax
movq %rax, 0x90(%rsp)
movl $0xa, %ebx
leaq 0x50(%rsp), %r12
leaq 0x98(%rsp), %rbp
movq 0x20(%rsp), %rdi
callq 0x2250
testl %eax, %eax
jne 0x4246
movq 0x8(%rsp), %rax
movslq 0xa83c(%rax), %rax
cmpq $0x1ff, %rax            # imm = 0x1FF
jg 0x3da3
movl %eax, %ecx
leaq (%rax,%rax,4), %rdx
shlq $0x4, %rdx
addq 0x90(%rsp), %rdx
addq $-0x200, %rax           # imm = 0xFE00
xorl %esi, %esi
movq (%rdx), %rdi
movq %rdi, %r8
subq -0x20(%rdx), %r8
shrq $0x3, %r8
cmpq $0x1, %rdi
adcq $-0x1, %r8
shlq $0x5, %r8
movq -0x28(%rdx), %rdi
movq -0x18(%rdx), %r9
subq -0x10(%rdx), %r9
sarq $0x4, %r9
addq %r8, %r9
subq -0x38(%rdx), %rdi
sarq $0x4, %rdi
addq %r9, %rdi
jne 0x3d9f
decq %rsi
addq $0x50, %rdx
cmpq %rsi, %rax
jne 0x3d52
movl $0x200, %eax            # imm = 0x200
jmp 0x3da3
subl %esi, %ecx
movl %ecx, %eax
cmpl $0x200, %eax            # imm = 0x200
jl 0x3de7
movq 0x20(%rsp), %rdi
callq 0x2160
movq $0x0, 0x50(%rsp)
movq $0xf4240, 0x58(%rsp)    # imm = 0xF4240
movq %r12, %rdi
movq %r12, %rsi
callq 0x2080
cmpl $-0x1, %eax
jne 0x3de0
callq 0x2040
cmpl $0x4, (%rax)
je 0x3dc6
decl %ebx
jmp 0x41c0
movq 0x8(%rsp), %rcx
decl 0xa830(%rcx)
cltq
leaq (%rax,%rax,4), %rax
shlq $0x4, %rax
leaq (%rcx,%rax), %rbx
movq 0x30(%rcx,%rax), %rsi
cmpq 0x38(%rcx,%rax), %rsi
jne 0x3e1c
movq 0x48(%rbx), %rax
movq -0x8(%rax), %rsi
movl $0x200, %eax            # imm = 0x200
addq %rax, %rsi
movq -0x10(%rsi), %rax
movq %rax, 0x40(%rsp)
addq $-0x8, %rsi
movq %r14, %rdi
callq 0x3804
movq %rbx, %rdi
callq 0x96a4
movq 0x20(%rsp), %rdi
callq 0x2160
movl 0x199c(%rsp), %esi
movq %rbp, %rdi
callq 0x5aae
movq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3804
movq 0x30(%rsp), %rsi
xorl %ebx, %ebx
testq %rsi, %rsi
je 0x3ea0
movl 0x10(%rsi), %eax
movl %eax, 0x19b0(%rsp,%rbx,4)
incq %rbx
movq (%rsi), %rax
movq %rax, 0x30(%rsp)
addq $0x8, %rsi
movq %r15, %rdi
callq 0x3804
movq 0x30(%rsp), %rsi
testq %rsi, %rsi
jne 0x3e73
movl %ebx, %ebx
testl %ebx, %ebx
jle 0x3eb8
movl 0x19ac(%rsp,%rbx,4), %esi
decq %rbx
movq %rbp, %rdi
callq 0x42a4
jmp 0x3ea0
movq %rbp, %rdi
callq 0x4456
cmpl $0x1, 0x19a8(%rsp)
leaq 0x70(%rsp), %rbx
jne 0x3f45
movl 0x190c(%rsp), %esi
movl %esi, 0x70(%rsp)
movq %rbp, %rdi
callq 0x42a4
movq $0x0, 0x50(%rsp)
movq %r13, %rdi
movq %r12, %rsi
leaq 0x1c(%rsp), %rdx
movq %rbx, %rcx
leaq 0x40(%rsp), %r8
callq 0x9718
movaps 0x50(%rsp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, 0x50(%rsp)
movq 0x48(%rsp), %rdi
movaps %xmm0, 0x40(%rsp)
testq %rdi, %rdi
je 0x3f24
callq 0x3794
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x3f33
callq 0x3794
movq %rbp, %rdi
callq 0x4456
cmpl $0x1, 0x19a8(%rsp)
je 0x3ecf
movq %rbp, %rdi
callq 0x4bfc
movl %eax, 0x18(%rsp)
movq 0x8(%rsp), %rax
movl 0xa834(%rax), %eax
cmpl %eax, 0x19a4(%rsp)
jg 0x3f80
jne 0x41e2
movq 0x8(%rsp), %rcx
movl 0x18(%rsp), %edx
cmpl %edx, 0xa838(%rcx)
jle 0x41e2
movq 0x20(%rsp), %rdi
callq 0x2250
testl %eax, %eax
jne 0x424d
movl 0x19a4(%rsp), %eax
movq 0x8(%rsp), %rcx
cmpl 0xa834(%rcx), %eax
jg 0x3fb9
jne 0x4012
movq 0x8(%rsp), %rcx
movl 0x18(%rsp), %edx
cmpl %edx, 0xa838(%rcx)
jle 0x4012
movq 0x8(%rsp), %rcx
movl 0x18(%rsp), %edx
movl %edx, 0xa838(%rcx)
movl %eax, 0xa834(%rcx)
movslq 0x19ac(%rsp), %rbx
testq %rbx, %rbx
jle 0x4005
leal -0x1(%rbx), %eax
movq %rbx, %rcx
subq %rax, %rcx
leaq 0x94(%rsp), %rax
leaq (%rax,%rcx,4), %rsi
leaq (,%rbx,4), %rdx
movq 0x88(%rsp), %rdi
callq 0x2180
movq 0x8(%rsp), %rax
movb $-0x1, 0xa002(%rax,%rbx,4)
movq 0x20(%rsp), %rdi
callq 0x2160
movslq 0x19a8(%rsp), %r12
movl $0xa, %ebx
testq %r12, %r12
jle 0x41bb
xorl %ebx, %ebx
movl 0x190c(%rsp,%rbx,4), %eax
movl %eax, 0x1c(%rsp)
movq %rbp, %rdi
leaq 0x1c(%rsp), %rsi
callq 0x4e52
movl %eax, 0x14(%rsp)
movl 0x1c(%rsp), %esi
movq %rbp, %rdi
callq 0x42a4
movl 0x18(%rsp), %eax
addl %eax, 0x14(%rsp)
movq %rbp, %rdi
callq 0x4cb4
movl %eax, %r13d
addl 0x14(%rsp), %r13d
movl %r13d, 0x14(%rsp)
movq 0x8(%rsp), %rax
cmpl $0x34, 0xa834(%rax)
jl 0x4099
movq 0x8(%rsp), %rax
cmpl 0xa838(%rax), %r13d
jge 0x418c
movl 0x19a0(%rsp), %r14d
subl 0x19a4(%rsp), %r13d
leaq 0x50(%rsp), %rdi
movq %rbp, %rsi
callq 0x4ede
movq 0x20(%rsp), %rdi
callq 0x2250
testl %eax, %eax
jne 0x423f
movq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rsi
leaq 0x14(%rsp), %rdx
callq 0x911e
movq %rax, %r15
testq %rax, %rax
je 0x40f5
movl 0x20(%r15), %eax
cmpl 0x14(%rsp), %eax
jle 0x4182
movq $0x0, 0x70(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x70(%rsp), %rsi
leaq 0x2f(%rsp), %rdx
leaq 0x1c(%rsp), %rcx
leaq 0x40(%rsp), %r8
callq 0x9718
movaps 0x70(%rsp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, 0x70(%rsp)
movq 0x38(%rsp), %rdi
movaps %xmm0, 0x30(%rsp)
testq %rdi, %rdi
je 0x413d
callq 0x3794
movq 0x78(%rsp), %rdi
testq %rdi, %rdi
je 0x414c
callq 0x3794
testq %r15, %r15
je 0x4159
movl 0x14(%rsp), %eax
movl %eax, 0x20(%r15)
leal (%r14,%r13), %eax
addl $0x34, %eax
movq 0x8(%rsp), %rcx
incl 0xa830(%rcx)
cltq
leaq (%rax,%rax,4), %rdi
shlq $0x4, %rdi
addq %rcx, %rdi
leaq 0x30(%rsp), %rsi
callq 0x9808
movq 0x20(%rsp), %rdi
callq 0x2160
movq %rbp, %rdi
callq 0x50e4
incq %rbx
cmpq %rbx, %r12
jne 0x4034
leaq 0x48(%rsp), %r14
leaq 0x38(%rsp), %r15
leaq 0x58(%rsp), %r13
leaq 0x50(%rsp), %r12
movl $0xa, %ebx
jmp 0x41c0
leaq 0x50(%rsp), %r12
movq 0x80(%rsp), %rax
movl 0x8(%rax), %eax
movq 0x8(%rsp), %rcx
cmpl 0xa840(%rcx), %eax
jge 0x420f
testl %ebx, %ebx
jg 0x3d12
jmp 0x420f
cmpl $0x34, %eax
jne 0x401c
movq %rbp, %rdi
callq 0x4cb4
addl 0x18(%rsp), %eax
movl $0xa, %ebx
movq 0x8(%rsp), %rcx
cmpl 0xa838(%rcx), %eax
jl 0x401c
jmp 0x41c0
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x421e
callq 0x3794
movq 0x48(%rsp), %rdi
testq %rdi, %rdi
je 0x422d
callq 0x3794
addq $0x21b8, %rsp           # imm = 0x21B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %edi
callq 0x2120
movl %eax, %edi
callq 0x2120
movl %eax, %edi
callq 0x2120
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
jmp 0x426e
movq %rax, %rbx
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x4280
callq 0x3794
movq 0x48(%rsp), %rdi
testq %rdi, %rdi
je 0x428f
callq 0x3794
movq %rbx, %rdi
callq 0x22e0
nop