// File: 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
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x1f0(%rbp)
movq (%rdi), %rax
callq *0x8(%rax)
testb $0x1, %al
jne 0x127fd
movb $0x0, -0x1(%rbp)
jmp 0x130b8
movq -0x1f0(%rbp), %rdi
addq $0x8, %rdi
callq 0xdb30
testb $0x1, %al
jne 0x12813
jmp 0x1284c
movq -0x1f0(%rbp), %rdi
addq $0x20, %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x132e0
movq -0x1f0(%rbp), %rsi
movq -0x1f8(%rbp), %rdi
addq $0x8, %rsi
callq 0x13320
jmp 0x12843
movb $0x1, -0x1(%rbp)
jmp 0x130b8
leaq -0x60(%rbp), %rdi
callq 0x13380
jmp 0x12857
leaq -0xb0(%rbp), %rdi
callq 0x133b0
jmp 0x12865
leaq -0xe8(%rbp), %rdi
callq 0x133e0
movq -0x1f0(%rbp), %rsi
addq $0x8, %rsi
leaq -0x110(%rbp), %rdi
callq 0x7310
jmp 0x1288a
movl $0x2, -0xf8(%rbp)
movq $0x0, -0xf0(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x13400
jmp 0x128b1
leaq -0x110(%rbp), %rdi
callq 0x13430
movq -0x1f0(%rbp), %rsi
addq $0x8, %rsi
leaq -0xe8(%rbp), %rdi
callq 0x13450
movq %rax, -0x200(%rbp)
jmp 0x128dd
movq -0x200(%rbp), %rax
movb $0x1, (%rax)
leaq -0x60(%rbp), %rdi
callq 0x13480
movb %al, -0x201(%rbp)
jmp 0x128f8
movb -0x201(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x12909
jmp 0x13089
leaq -0x60(%rbp), %rdi
callq 0x134a0
movq %rax, -0x210(%rbp)
jmp 0x1291b
movq -0x210(%rbp), %rsi
leaq -0x138(%rbp), %rdi
callq 0x134c0
jmp 0x12930
leaq -0x60(%rbp), %rdi
callq 0x13500
jmp 0x1293b
leaq -0xb0(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x13520
jmp 0x12950
movq -0x1f0(%rbp), %rsi
leaq -0x140(%rbp), %rdi
leaq -0x138(%rbp), %rdx
callq 0x130d0
jmp 0x1296c
leaq -0x140(%rbp), %rdi
callq 0x13550
cmpl $0x0, (%rax)
je 0x12b26
leaq -0x168(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x134c0
jmp 0x12996
movl $0x0, -0x150(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x13570
movq %rax, -0x218(%rbp)
jmp 0x129b5
movq -0x218(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x140(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0x13590
movslq (%rax), %rsi
leaq -0x168(%rbp), %rdi
movq %rdi, -0x228(%rbp)
callq 0xe720
movq -0x240(%rbp), %rdi
movq %rax, -0x248(%rbp)
callq 0x13550
movq -0x248(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe740
movq -0x240(%rbp), %rdi
movq %rax, -0x230(%rbp)
callq 0x13590
movq -0x228(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe720
movq -0x240(%rbp), %rdi
movq %rax, -0x238(%rbp)
callq 0x13550
movq -0x238(%rbp), %rdi
movl (%rax), %eax
decl %eax
movslq %eax, %rsi
callq 0xe740
movq -0x230(%rbp), %rdi
movq %rax, %rsi
callq 0xe820
movq -0x228(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0x13450
movq %rax, -0x220(%rbp)
jmp 0x12a81
movq -0x220(%rbp), %rax
testb $0x1, (%rax)
jne 0x12afe
leaq -0x60(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x135b0
jmp 0x12a9f
leaq -0xe8(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x13450
movq %rax, -0x250(%rbp)
jmp 0x12abb
movq -0x250(%rbp), %rax
movb $0x1, (%rax)
leaq -0x168(%rbp), %rdi
callq 0xdb30
testb $0x1, %al
jne 0x12ad7
jmp 0x12afc
movq -0x1f0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x13220
jmp 0x12aec
movb $0x1, -0x1(%rbp)
movl $0x1, -0x16c(%rbp)
jmp 0x12b08
jmp 0x12afe
movl $0x0, -0x16c(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x13430
movl -0x16c(%rbp), %eax
testl %eax, %eax
jne 0x1306c
jmp 0x12b24
jmp 0x12b26
leaq -0x140(%rbp), %rdi
callq 0x13550
movq -0x1f0(%rbp), %rcx
movl (%rax), %eax
cmpl 0x70(%rcx), %eax
jge 0x12ce9
leaq -0x198(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x134c0
jmp 0x12b59
movl $0x0, -0x180(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x13570
movq %rax, -0x258(%rbp)
jmp 0x12b78
movq -0x258(%rbp), %rax
movq %rax, -0x178(%rbp)
leaq -0x140(%rbp), %rdi
movq %rdi, -0x280(%rbp)
callq 0x13590
movslq (%rax), %rsi
leaq -0x198(%rbp), %rdi
movq %rdi, -0x268(%rbp)
callq 0xe720
movq -0x280(%rbp), %rdi
movq %rax, -0x288(%rbp)
callq 0x13550
movq -0x288(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe740
movq -0x280(%rbp), %rdi
movq %rax, -0x270(%rbp)
callq 0x13590
movq -0x268(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe720
movq -0x280(%rbp), %rdi
movq %rax, -0x278(%rbp)
callq 0x13550
movq -0x278(%rbp), %rdi
movl (%rax), %eax
incl %eax
movslq %eax, %rsi
callq 0xe740
movq -0x270(%rbp), %rdi
movq %rax, %rsi
callq 0xe820
movq -0x268(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0x13450
movq %rax, -0x260(%rbp)
jmp 0x12c44
movq -0x260(%rbp), %rax
testb $0x1, (%rax)
jne 0x12cc1
leaq -0x60(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x135b0
jmp 0x12c62
leaq -0xe8(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x13450
movq %rax, -0x290(%rbp)
jmp 0x12c7e
movq -0x290(%rbp), %rax
movb $0x1, (%rax)
leaq -0x198(%rbp), %rdi
callq 0xdb30
testb $0x1, %al
jne 0x12c9a
jmp 0x12cbf
movq -0x1f0(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x13220
jmp 0x12caf
movb $0x1, -0x1(%rbp)
movl $0x1, -0x16c(%rbp)
jmp 0x12ccb
jmp 0x12cc1
movl $0x0, -0x16c(%rbp)
leaq -0x198(%rbp), %rdi
callq 0x13430
movl -0x16c(%rbp), %eax
testl %eax, %eax
jne 0x1306c
jmp 0x12ce7
jmp 0x12ce9
leaq -0x140(%rbp), %rdi
callq 0x13590
cmpl $0x0, (%rax)
je 0x12ea3
leaq -0x1c0(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x134c0
jmp 0x12d13
movl $0x1, -0x1a8(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x13570
movq %rax, -0x298(%rbp)
jmp 0x12d32
movq -0x298(%rbp), %rax
movq %rax, -0x1a0(%rbp)
leaq -0x140(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0x13590
movslq (%rax), %rsi
leaq -0x1c0(%rbp), %rdi
movq %rdi, -0x2a8(%rbp)
callq 0xe720
movq -0x2c0(%rbp), %rdi
movq %rax, -0x2c8(%rbp)
callq 0x13550
movq -0x2c8(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe740
movq -0x2c0(%rbp), %rdi
movq %rax, -0x2b0(%rbp)
callq 0x13590
movq -0x2a8(%rbp), %rdi
movl (%rax), %eax
decl %eax
movslq %eax, %rsi
callq 0xe720
movq -0x2c0(%rbp), %rdi
movq %rax, -0x2b8(%rbp)
callq 0x13550
movq -0x2b8(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe740
movq -0x2b0(%rbp), %rdi
movq %rax, %rsi
callq 0xe820
movq -0x2a8(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0x13450
movq %rax, -0x2a0(%rbp)
jmp 0x12dfe
movq -0x2a0(%rbp), %rax
testb $0x1, (%rax)
jne 0x12e7b
leaq -0x60(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x135b0
jmp 0x12e1c
leaq -0xe8(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x13450
movq %rax, -0x2d0(%rbp)
jmp 0x12e38
movq -0x2d0(%rbp), %rax
movb $0x1, (%rax)
leaq -0x1c0(%rbp), %rdi
callq 0xdb30
testb $0x1, %al
jne 0x12e54
jmp 0x12e79
movq -0x1f0(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x13220
jmp 0x12e69
movb $0x1, -0x1(%rbp)
movl $0x1, -0x16c(%rbp)
jmp 0x12e85
jmp 0x12e7b
movl $0x0, -0x16c(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x13430
movl -0x16c(%rbp), %eax
testl %eax, %eax
jne 0x1306c
jmp 0x12ea1
jmp 0x12ea3
leaq -0x140(%rbp), %rdi
callq 0x13590
movq -0x1f0(%rbp), %rcx
movl (%rax), %eax
cmpl 0x74(%rcx), %eax
jge 0x13062
leaq -0x1e8(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x134c0
jmp 0x12ed6
movl $0x1, -0x1d0(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x13570
movq %rax, -0x2d8(%rbp)
jmp 0x12ef5
movq -0x2d8(%rbp), %rax
movq %rax, -0x1c8(%rbp)
leaq -0x140(%rbp), %rdi
movq %rdi, -0x300(%rbp)
callq 0x13590
movslq (%rax), %rsi
leaq -0x1e8(%rbp), %rdi
movq %rdi, -0x2e8(%rbp)
callq 0xe720
movq -0x300(%rbp), %rdi
movq %rax, -0x308(%rbp)
callq 0x13550
movq -0x308(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe740
movq -0x300(%rbp), %rdi
movq %rax, -0x2f0(%rbp)
callq 0x13590
movq -0x2e8(%rbp), %rdi
movl (%rax), %eax
incl %eax
movslq %eax, %rsi
callq 0xe720
movq -0x300(%rbp), %rdi
movq %rax, -0x2f8(%rbp)
callq 0x13550
movq -0x2f8(%rbp), %rdi
movslq (%rax), %rsi
callq 0xe740
movq -0x2f0(%rbp), %rdi
movq %rax, %rsi
callq 0xe820
movq -0x2e8(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0x13450
movq %rax, -0x2e0(%rbp)
jmp 0x12fc1
movq -0x2e0(%rbp), %rax
testb $0x1, (%rax)
jne 0x1303e
leaq -0x60(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x135b0
jmp 0x12fdf
leaq -0xe8(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x13450
movq %rax, -0x310(%rbp)
jmp 0x12ffb
movq -0x310(%rbp), %rax
movb $0x1, (%rax)
leaq -0x1e8(%rbp), %rdi
callq 0xdb30
testb $0x1, %al
jne 0x13017
jmp 0x1303c
movq -0x1f0(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x13220
jmp 0x1302c
movb $0x1, -0x1(%rbp)
movl $0x1, -0x16c(%rbp)
jmp 0x13048
jmp 0x1303e
movl $0x0, -0x16c(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x13430
movl -0x16c(%rbp), %eax
testl %eax, %eax
jne 0x1306c
jmp 0x13060
jmp 0x13062
movl $0x0, -0x16c(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x13430
movl -0x16c(%rbp), %eax
testl %eax, %eax
jne 0x13097
jmp 0x13084
jmp 0x128e7
movb $0x0, -0x1(%rbp)
movl $0x1, -0x16c(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x135e0
leaq -0xb0(%rbp), %rdi
callq 0x13600
leaq -0x60(%rbp), %rdi
callq 0x13620
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
movq %rax, %rdi
callq 0x5bd0
nop