// File: /workspace/github_cpp_makefile_star2_O3/iTruth[P]klotski/klotski_search.cpp
// Function: klotski_search::start_search()
bool klotski_search::start_search() noexcept{
	if(!is_situation_valid()){
		return false;
	}
	if(klotski_board::is_win(situation)){
		last_route.clear();
		last_route.push_back(situation);
		return true;
	}
	std::queue<record_item> open;
	std::stack<record_item> close;
	std::unordered_map<klotski_board::situation_type, bool, klotski_board::situation_type_hash> situation_search_state;
	open.push(record_item{situation, record_item::Undefined, nullptr});
	situation_search_state[situation] = true;
	while(!open.empty()){
		auto situation_front = open.front();
		open.pop();
		close.push(situation_front);
		auto zero_pos = get_zero_pos(situation_front.situation);
		if(std::get<0>(zero_pos) != 0){
			auto situation_tmp = situation_front;
			situation_tmp.Orientation = record_item::Horizontal;
			situation_tmp.prev = &close.top();
			std::swap(situation_tmp.situation[std::get<1>(zero_pos)][std::get<0>(zero_pos)],
					situation_tmp.situation[std::get<1>(zero_pos)][std::get<0>(zero_pos) - 1]);
			if(!situation_search_state[situation_tmp.situation]){
				open.push(situation_tmp);
				situation_search_state[situation_tmp.situation] = true;
				if(klotski_board::is_win(situation_tmp.situation)){
					build_route(situation_tmp);
					return true;
				}
			}
		}
		if(std::get<0>(zero_pos) < dx){
			auto situation_tmp = situation_front;
			situation_tmp.Orientation = record_item::Horizontal;
			situation_tmp.prev = &close.top();
			std::swap(situation_tmp.situation[std::get<1>(zero_pos)][std::get<0>(zero_pos)],
					situation_tmp.situation[std::get<1>(zero_pos)][std::get<0>(zero_pos) + 1]);
			if(!situation_search_state[situation_tmp.situation]){
				open.push(situation_tmp);
				situation_search_state[situation_tmp.situation] = true;
				if(klotski_board::is_win(situation_tmp.situation)){
					build_route(situation_tmp);
					return true;
				}
			}
		}
		if(std::get<1>(zero_pos) != 0){
			auto situation_tmp = situation_front;
			situation_tmp.Orientation = record_item::Vertical;
			situation_tmp.prev = &close.top();
			std::swap(situation_tmp.situation[std::get<1>(zero_pos)][std::get<0>(zero_pos)],
					situation_tmp.situation[std::get<1>(zero_pos) - 1][std::get<0>(zero_pos)]);
			if(!situation_search_state[situation_tmp.situation]){
				open.push(situation_tmp);
				situation_search_state[situation_tmp.situation] = true;
				if(klotski_board::is_win(situation_tmp.situation)){
					build_route(situation_tmp);
					return true;
				}
			}
		}
		if(std::get<1>(zero_pos) < dy){
			auto situation_tmp = situation_front;
			situation_tmp.Orientation = record_item::Vertical;
			situation_tmp.prev = &close.top();
			std::swap(situation_tmp.situation[std::get<1>(zero_pos)][std::get<0>(zero_pos)],
					situation_tmp.situation[std::get<1>(zero_pos) + 1][std::get<0>(zero_pos)]);
			if(!situation_search_state[situation_tmp.situation]){
				open.push(situation_tmp);
				situation_search_state[situation_tmp.situation] = true;
				if(klotski_board::is_win(situation_tmp.situation)){
					build_route(situation_tmp);
					return true;
				}
			}
		}
	}
	return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movq %rdi, %rbx
movq (%rdi), %rax
callq *0x8(%rax)
testb %al, %al
je 0x85a9
leaq 0x8(%rbx), %r14
movq %r14, %rdi
callq 0x73a8
testb %al, %al
je 0x85b0
addq $0x20, %rbx
movq %rbx, %rdi
callq 0x8ba8
movb $0x1, %bpl
movq %rbx, %rdi
movq %r14, %rsi
callq 0x8bd0
jmp 0x8a93
xorl %ebp, %ebp
jmp 0x8a93
pxor %xmm0, %xmm0
leaq 0xe0(%rsp), %rdi
movdqa %xmm0, 0x40(%rdi)
movdqa %xmm0, 0x30(%rdi)
movdqa %xmm0, 0x20(%rdi)
movdqa %xmm0, 0x10(%rdi)
movdqa %xmm0, (%rdi)
xorl %esi, %esi
callq 0x90e6
leaq 0x90(%rsp), %rdi
pxor %xmm0, %xmm0
movdqa %xmm0, 0x40(%rdi)
movdqa %xmm0, 0x30(%rdi)
movdqa %xmm0, 0x20(%rdi)
movdqa %xmm0, 0x10(%rdi)
movdqa %xmm0, (%rdi)
xorl %esi, %esi
callq 0x90e6
leaq 0x88(%rsp), %rax
movq %rax, -0x30(%rax)
movq $0x1, -0x28(%rax)
pxor %xmm0, %xmm0
movdqu %xmm0, -0x20(%rax)
movl $0x3f800000, -0x10(%rax) # imm = 0x3F800000
movdqu %xmm0, -0x8(%rax)
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
callq 0x5916
leaq 0x30(%rsp), %rsi
movl $0x2, 0x18(%rsi)
movq $0x0, 0x20(%rsi)
leaq 0xe0(%rsp), %rdi
callq 0x9282
leaq 0x30(%rsp), %rdi
callq 0x59fa
leaq 0x58(%rsp), %rdi
movq %r14, %rsi
callq 0x953a
movb $0x1, (%rax)
movq 0xf0(%rsp), %r13
cmpq %r13, 0x110(%rsp)
je 0x8a24
leaq 0x30(%rsp), %r14
movq %rsp, %rbp
movq %r14, %rdi
movq %r13, %rsi
callq 0x5916
movdqu 0x18(%r13), %xmm0
leaq 0x48(%rsp), %rax
movdqu %xmm0, (%rax)
leaq 0xe0(%rsp), %rdi
callq 0x99b6
leaq 0x90(%rsp), %rdi
movq %r14, %rsi
callq 0x9a20
leaq 0x28(%rsp), %rdi
movq %r14, %rdx
callq 0x8ab2
movslq 0x2c(%rsp), %r13
testq %r13, %r13
je 0x87a7
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5916
leaq 0x48(%rsp), %rax
movups (%rax), %xmm0
leaq 0x18(%rsp), %rax
movups %xmm0, (%rax)
movl $0x0, 0x18(%rsp)
movq 0xc0(%rsp), %rax
cmpq 0xc8(%rsp), %rax
jne 0x8730
movq 0xd8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x20(%rsp)
movslq 0x28(%rsp), %rax
movq (%rsp), %rcx
leaq (%rax,%rax,2), %rax
movq (%rcx,%rax,8), %rax
movq -0x4(%rax,%r13,4), %xmm0
pshufd $0xe1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,2,3]
movq %xmm0, -0x4(%rax,%r13,4)
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
cmpb $0x0, (%rax)
jne 0x879f
leaq 0xe0(%rsp), %rdi
movq %rbp, %rsi
callq 0x9a20
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
movb $0x1, (%rax)
movq %rbp, %rdi
callq 0x73a8
testb %al, %al
jne 0x8a28
movq %rbp, %rdi
callq 0x59fa
cmpl 0x70(%rbx), %r13d
jge 0x8871
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5916
leaq 0x48(%rsp), %rax
movups (%rax), %xmm0
leaq 0x18(%rsp), %rax
movups %xmm0, (%rax)
movl $0x0, 0x18(%rsp)
movq 0xc0(%rsp), %rax
cmpq 0xc8(%rsp), %rax
jne 0x87fa
movq 0xd8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x20(%rsp)
movslq 0x28(%rsp), %r15
movq (%rsp), %rax
leaq (%r15,%r15,2), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax,%r13,4), %xmm0
pshufd $0xe1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,2,3]
movq %xmm0, (%rax,%r13,4)
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
cmpb $0x0, (%rax)
jne 0x8867
leaq 0xe0(%rsp), %rdi
movq %rbp, %rsi
callq 0x9a20
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
movb $0x1, (%rax)
movq %rbp, %rdi
callq 0x73a8
testb %al, %al
jne 0x8a42
movq %rbp, %rdi
callq 0x59fa
jmp 0x8876
movl 0x28(%rsp), %r15d
movslq %r15d, %r12
testl %r15d, %r15d
je 0x8941
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5916
leaq 0x48(%rsp), %rax
movdqu (%rax), %xmm0
leaq 0x18(%rsp), %rax
movdqu %xmm0, (%rax)
movl $0x1, 0x18(%rsp)
movq 0xc0(%rsp), %rax
cmpq 0xc8(%rsp), %rax
jne 0x88cd
movq 0xd8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x20(%rsp)
movq (%rsp), %rax
leaq (%r12,%r12,2), %rcx
movq -0x18(%rax,%rcx,8), %rdx
movq (%rax,%rcx,8), %rax
movl (%rax,%r13,4), %ecx
movl (%rdx,%r13,4), %esi
movl %esi, (%rax,%r13,4)
movl %ecx, (%rdx,%r13,4)
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
cmpb $0x0, (%rax)
jne 0x8939
leaq 0xe0(%rsp), %rdi
movq %rbp, %rsi
callq 0x9a20
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
movb $0x1, (%rax)
movq %rbp, %rdi
callq 0x73a8
testb %al, %al
jne 0x8a35
movq %rbp, %rdi
callq 0x59fa
cmpl 0x74(%rbx), %r15d
jge 0x8a06
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5916
leaq 0x48(%rsp), %rax
movdqu (%rax), %xmm0
leaq 0x18(%rsp), %rax
movdqu %xmm0, (%rax)
movl $0x1, 0x18(%rsp)
movq 0xc0(%rsp), %rax
cmpq 0xc8(%rsp), %rax
jne 0x8996
movq 0xd8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x20(%rsp)
movq (%rsp), %rax
leaq (%r12,%r12,2), %rcx
movq (%rax,%rcx,8), %rdx
movq 0x18(%rax,%rcx,8), %rax
movl (%rdx,%r13,4), %ecx
movl (%rax,%r13,4), %esi
movl %esi, (%rdx,%r13,4)
movl %ecx, (%rax,%r13,4)
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
cmpb $0x0, (%rax)
jne 0x89fe
leaq 0xe0(%rsp), %rdi
movq %rbp, %rsi
callq 0x9a20
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0x953a
movb $0x1, (%rax)
movq %rbp, %rdi
callq 0x73a8
testb %al, %al
jne 0x8a4f
movq %rbp, %rdi
callq 0x59fa
movq %r14, %rdi
callq 0x59fa
movq 0xf0(%rsp), %r13
cmpq %r13, 0x110(%rsp)
jne 0x8695
xorl %ebp, %ebp
jmp 0x8a6f
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x8b46
jmp 0x8a5a
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x8b46
jmp 0x8a5a
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x8b46
jmp 0x8a5a
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x8b46
movq %rsp, %rdi
callq 0x59fa
leaq 0x30(%rsp), %rdi
callq 0x59fa
movb $0x1, %bpl
leaq 0x58(%rsp), %rdi
callq 0x8c22
leaq 0x90(%rsp), %rdi
callq 0x8cbc
leaq 0xe0(%rsp), %rdi
callq 0x8cbc
movl %ebp, %eax
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x8aa9
movq %rax, %rdi
callq 0x5609
nop