// File: /workspace/github_cpp_makefile_star2_O2/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 0x7c91
leaq 0x8(%rbx), %r14
movq %r14, %rdi
callq 0x68ea
testb %al, %al
je 0x7c98
addq $0x20, %rbx
movq %rbx, %rdi
callq 0x81fa
movb $0x1, %bpl
movq %rbx, %rdi
movq %r14, %rsi
callq 0x8222
jmp 0x80ef
xorl %ebp, %ebp
jmp 0x80ef
movq %rbx, (%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x824c
leaq 0x70(%rsp), %rdi
callq 0x8268
leaq 0x68(%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 0xc0(%rsp), %rdi
movq %r14, %rsi
callq 0x4e80
leaq 0xc0(%rsp), %rsi
movl $0x2, 0x18(%rsi)
andq $0x0, 0x20(%rsi)
leaq 0xe8(%rsp), %rdi
callq 0x893c
leaq 0xc0(%rsp), %rdi
callq 0x4f26
leaq 0x38(%rsp), %rdi
movq %r14, %rsi
callq 0x8bde
movb $0x1, (%rax)
leaq 0xc0(%rsp), %r14
leaq 0x10(%rsp), %r12
movq 0xf8(%rsp), %rsi
cmpq %rsi, 0x118(%rsp)
setne %bpl
je 0x80ce
movq %r14, %rdi
callq 0x8284
leaq 0xe8(%rsp), %rdi
callq 0x9102
leaq 0x70(%rsp), %rdi
movq %r14, %rsi
callq 0x916c
leaq 0x8(%rsp), %rdi
movq %r14, %rdx
callq 0x810e
movslq 0xc(%rsp), %r15
testq %r15, %r15
je 0x7e39
movq %r12, %rdi
movq %r14, %rsi
callq 0x8284
andl $0x0, 0x28(%rsp)
movq 0xa0(%rsp), %rax
cmpq 0xa8(%rsp), %rax
jne 0x7dc1
movq 0xb8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x30(%rsp)
movslq 0x8(%rsp), %rax
movq 0x10(%rsp), %rcx
imulq $0x18, %rax, %rax
movq (%rcx,%rax), %rax
movq -0x4(%rax,%r15,4), %xmm0
pshufd $0xe1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,2,3]
movq %xmm0, -0x4(%rax,%r15,4)
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
cmpb $0x0, (%rax)
jne 0x7e31
leaq 0xe8(%rsp), %rdi
movq %r12, %rsi
callq 0x916c
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
movb $0x1, (%rax)
movq %r12, %rdi
callq 0x68ea
testb %al, %al
jne 0x8079
movq %r12, %rdi
callq 0x4f26
movq (%rsp), %rax
cmpl 0x70(%rax), %r15d
jge 0x7ef5
movq %r12, %rdi
movq %r14, %rsi
callq 0x8284
andl $0x0, 0x28(%rsp)
movq 0xa0(%rsp), %rax
cmpq 0xa8(%rsp), %rax
jne 0x7e7d
movq 0xb8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x30(%rsp)
movslq 0x8(%rsp), %r13
movq 0x10(%rsp), %rax
imulq $0x18, %r13, %rcx
movq (%rax,%rcx), %rax
movq (%rax,%r15,4), %xmm0
pshufd $0xe1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,2,3]
movq %xmm0, (%rax,%r15,4)
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
cmpb $0x0, (%rax)
jne 0x7eeb
leaq 0xe8(%rsp), %rdi
movq %r12, %rsi
callq 0x916c
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
movb $0x1, (%rax)
movq %r12, %rdi
callq 0x68ea
testb %al, %al
jne 0x8099
movq %r12, %rdi
callq 0x4f26
jmp 0x7efa
movl 0x8(%rsp), %r13d
movslq %r13d, %rbx
testl %r13d, %r13d
je 0x7fb4
movq %r12, %rdi
movq %r14, %rsi
callq 0x8284
movl $0x1, 0x28(%rsp)
movq 0xa0(%rsp), %rax
cmpq 0xa8(%rsp), %rax
jne 0x7f3f
movq 0xb8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x30(%rsp)
movq 0x10(%rsp), %rax
imulq $0x18, %rbx, %rcx
movq -0x18(%rax,%rcx), %rdx
movq (%rax,%rcx), %rax
movl (%rax,%r15,4), %ecx
movl (%rdx,%r15,4), %esi
movl %esi, (%rax,%r15,4)
movl %ecx, (%rdx,%r15,4)
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
cmpb $0x0, (%rax)
jne 0x7fac
leaq 0xe8(%rsp), %rdi
movq %r12, %rsi
callq 0x916c
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
movb $0x1, (%rax)
movq %r12, %rdi
callq 0x68ea
testb %al, %al
jne 0x8089
movq %r12, %rdi
callq 0x4f26
movq (%rsp), %rax
cmpl 0x74(%rax), %r13d
jge 0x806c
movq %r12, %rdi
movq %r14, %rsi
callq 0x8284
movl $0x1, 0x28(%rsp)
movq 0xa0(%rsp), %rax
cmpq 0xa8(%rsp), %rax
jne 0x7ffb
movq 0xb8(%rsp), %rax
movq -0x8(%rax), %rax
movl $0x1e0, %ecx            # imm = 0x1E0
addq %rcx, %rax
addq $-0x28, %rax
movq %rax, 0x30(%rsp)
movq 0x10(%rsp), %rax
imulq $0x18, %rbx, %rcx
movq (%rax,%rcx), %rdx
movq 0x18(%rax,%rcx), %rax
movl (%rdx,%r15,4), %ecx
movl (%rax,%r15,4), %esi
movl %esi, (%rdx,%r15,4)
movl %ecx, (%rax,%r15,4)
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
cmpb $0x0, (%rax)
jne 0x8064
leaq 0xe8(%rsp), %rdi
movq %r12, %rsi
callq 0x916c
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x8bde
movb $0x1, (%rax)
movq %r12, %rdi
callq 0x68ea
testb %al, %al
jne 0x80a9
movq %r12, %rdi
callq 0x4f26
movq %r14, %rdi
callq 0x4f26
jmp 0x7d34
leaq 0x10(%rsp), %rsi
movq (%rsp), %rdi
callq 0x8198
jmp 0x80b7
leaq 0x10(%rsp), %rsi
movq (%rsp), %rdi
callq 0x8198
jmp 0x80b7
leaq 0x10(%rsp), %rsi
movq (%rsp), %rdi
callq 0x8198
jmp 0x80b7
leaq 0x10(%rsp), %rsi
movq (%rsp), %rdi
callq 0x8198
leaq 0x10(%rsp), %rdi
callq 0x4f26
leaq 0xc0(%rsp), %rdi
callq 0x4f26
leaq 0x38(%rsp), %rdi
callq 0x82cc
leaq 0x70(%rsp), %rdi
callq 0x838a
leaq 0xe8(%rsp), %rdi
callq 0x838a
movl %ebp, %eax
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x8105
movq %rax, %rdi
callq 0x497f
nop