// File: YSRKEN[P]Shioi/I401/main.cpp
// Function: Board::IsShioiMove(Stone, unsigned long, unsigned long)
bool IsShioiMove(const Stone turn, const size_t block_position, const size_t depth) {
		// Block Katsu-Shi
		if (block_position >= kBoardSize * kBoardSize) {
			return true;
		}
		auto enemy_stone = EnemyTurn(turn);
		if (enemy_stone == Stone::Black && !IsValidMove(block_position)) {
			//PutBoard();
			return true;
		}
		board_[block_position] = enemy_stone;
		// If you must block enemy's Shi-ren or Katsu-shi, this Shioi's challenge is failed.
		auto result = FindGorenMove(enemy_stone);
		if (result.second) {
			board_[block_position] = Stone::None;
			return false;
		}
		//depth limit
		if (depth == 0) {
			board_[block_position] = Stone::None;
			return false;
		}
		// Find Next Shi-ren or Katsu-shi
		auto range = GetRange();
		for (size_t y : rep(range[1], range[3])) {
			for (size_t x : rep(range[0], range[2])) {
				size_t p = ToPosition(x, y);
			if (board_[p] != Stone::None) continue;
			if (turn == Stone::Black) {
				bool cho_ren_flg = false;
				size_t sum_4_strong = 0, sum_4_normal = 0, sum_3 = 0;
				size_t block_position2 = kBoardSize * kBoardSize;
				for (uint8_t dir = 0; dir < Direction::Directions; ++dir) {
					auto move_pattern = GetPatternB(p, static_cast<Direction>(dir));
					if (Board_helper::IsChorenB(move_pattern)) {
						cho_ren_flg = true;
						break;
					}
					//auto ren_count = CountRenB(move_pattern, p, static_cast<Direction>(dir));
					size_t s4s, s4n, s3;
					std::tie(s4s, s4n, s3) = CountRenB2(move_pattern, p, static_cast<Direction>(dir), block_position2);
					sum_4_strong += s4s;
					sum_4_normal += s4n;
					sum_3 += s3;
				}
				if (cho_ren_flg || sum_4_strong + sum_4_normal >= 2 || sum_3 >= 2) continue;
				if (sum_4_strong > 0) {
					board_[block_position] = Stone::None;
					return true;
				}
				if (sum_4_normal == 1) {
					board_[p] = Stone::Black;
					auto score = IsShioiMove(Stone::Black, block_position2, depth - 1);
					board_[p] = Stone::None;
					if (score) {
						board_[block_position] = Stone::None;
						return true;
					}
					continue;
				}
			}
			else {
				size_t block_position2 = kBoardSize * kBoardSize;
				size_t sum_4_strong = 0, sum_4_normal = 0;
				for (uint8_t dir = 0; dir < Direction::Directions; ++dir) {
					auto move_pattern = GetPatternW(p, static_cast<Direction>(dir));
					if (Board_helper::IsChorenW(move_pattern)) return true;
					size_t s4s, s4n, blk;
					std::tie(s4s, s4n, blk) = CountRenW2(move_pattern, p, static_cast<Direction>(dir));
					sum_4_strong += s4s;
					sum_4_normal += s4n;
					if (s4n) block_position2 = blk;
				}
				if (sum_4_strong > 0 || sum_4_normal > 1) {
					board_[block_position] = Stone::None;
					return true;
				}
				if (sum_4_normal == 1) {
					board_[p] = Stone::White;
					auto score = IsShioiMove(Stone::White, block_position2, depth - 1);
					board_[p] = Stone::None;
					if (score) {
						board_[block_position] = Stone::None;
						return true;
					}
					continue;
				}
			}
		}
		}

		board_[block_position] = Stone::None;
		return false;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x330, %rsp            # imm = 0x330
movb %sil, %al
movq %rdi, -0x10(%rbp)
movb %al, -0x11(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x310(%rbp)
cmpq $0xe1, -0x20(%rbp)
jb 0x1533b
movb $0x1, -0x1(%rbp)
jmp 0x159aa
movzbl -0x11(%rbp), %edi
callq 0x68d0
movb %al, -0x29(%rbp)
movzbl -0x29(%rbp), %eax
cmpl $0x1, %eax
jne 0x1536d
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0xaf70
testb $0x1, %al
jne 0x1536d
movb $0x1, -0x1(%rbp)
jmp 0x159aa
movq -0x310(%rbp), %rdi
movb -0x29(%rbp), %al
movb %al, -0x311(%rbp)
movq -0x20(%rbp), %rsi
callq 0x5590
movb -0x311(%rbp), %cl
movq -0x310(%rbp), %rdi
movb %cl, (%rax)
movzbl -0x29(%rbp), %esi
callq 0x9ae0
movb %dl, -0x48(%rbp)
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x40(%rbp)
movb -0x48(%rbp), %al
movb %al, -0x38(%rbp)
testb $0x1, -0x38(%rbp)
je 0x153d5
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x159aa
cmpq $0x0, -0x28(%rbp)
jne 0x153f8
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x159aa
movq -0x310(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x126b0
leaq -0x70(%rbp), %rdi
movl $0x1, %esi
callq 0x12a70
movq %rax, -0x320(%rbp)
leaq -0x70(%rbp), %rdi
movl $0x3, %esi
callq 0x12a70
movq -0x320(%rbp), %rdi
movq %rax, %rsi
callq 0xec40
movq %rax, -0x88(%rbp)
movq %rdx, -0x80(%rbp)
leaq -0x88(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
callq 0x54e0
movq %rax, -0x90(%rbp)
movq -0x78(%rbp), %rdi
callq 0x5510
movq %rax, -0x98(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x5550
testb $0x1, %al
jne 0x1548c
jmp 0x15993
leaq -0x90(%rbp), %rdi
callq 0x5580
movq (%rax), %rax
movq %rax, -0xa0(%rbp)
leaq -0x70(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x12a70
movq %rax, -0x328(%rbp)
leaq -0x70(%rbp), %rdi
movl $0x2, %esi
callq 0x12a70
movq -0x328(%rbp), %rdi
movq %rax, %rsi
callq 0xec40
movq %rax, -0xb8(%rbp)
movq %rdx, -0xb0(%rbp)
leaq -0xb8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
callq 0x54e0
movq %rax, -0xc0(%rbp)
movq -0xa8(%rbp), %rdi
callq 0x5510
movq %rax, -0xc8(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x5550
testb $0x1, %al
jne 0x15531
jmp 0x15980
leaq -0xc0(%rbp), %rdi
callq 0x5580
movq (%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x3100
movq -0x310(%rbp), %rdi
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rsi
callq 0x5590
movzbl (%rax), %eax
cmpl $0x0, %eax
je 0x15581
jmp 0x1596f
movzbl -0x11(%rbp), %eax
cmpl $0x1, %eax
jne 0x157ac
movb $0x0, -0xd9(%rbp)
movq $0x0, -0xe8(%rbp)
movq $0x0, -0xf0(%rbp)
movq $0x0, -0xf8(%rbp)
movq $0xe1, -0x100(%rbp)
movb $0x0, -0x101(%rbp)
movzbl -0x101(%rbp), %eax
cmpl $0x4, %eax
jge 0x156cd
movq -0x310(%rbp), %rsi
movq -0xd8(%rbp), %rdx
leaq -0x1a8(%rbp), %rdi
movzbl -0x101(%rbp), %ecx
callq 0xed20
leaq -0x1a8(%rbp), %rdi
callq 0xef70
testb $0x1, %al
jne 0x1560b
jmp 0x15617
movb $0x1, -0xd9(%rbp)
jmp 0x156cd
movq -0x310(%rbp), %rsi
movq -0xd8(%rbp), %rcx
leaq -0x1d8(%rbp), %rdi
leaq -0x1a8(%rbp), %rdx
leaq -0x100(%rbp), %r9
movzbl -0x101(%rbp), %r8d
callq 0x12aa0
leaq -0x1f0(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
leaq -0x1b8(%rbp), %rdx
leaq -0x1c0(%rbp), %rcx
callq 0x11390
leaq -0x1f0(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x113d0
movq -0x1b0(%rbp), %rax
addq -0xe8(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x1b8(%rbp), %rax
addq -0xf0(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x1c0(%rbp), %rax
addq -0xf8(%rbp), %rax
movq %rax, -0xf8(%rbp)
movb -0x101(%rbp), %al
addb $0x1, %al
movb %al, -0x101(%rbp)
jmp 0x155c8
testb $0x1, -0xd9(%rbp)
jne 0x156f4
movq -0xe8(%rbp), %rax
addq -0xf0(%rbp), %rax
cmpq $0x2, %rax
jae 0x156f4
cmpq $0x2, -0xf8(%rbp)
jb 0x156f9
jmp 0x1596f
cmpq $0x0, -0xe8(%rbp)
jbe 0x1571f
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
movb $0x1, -0x1(%rbp)
jmp 0x159aa
cmpq $0x1, -0xf0(%rbp)
jne 0x157a7
movq -0x310(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0x5590
movq -0x310(%rbp), %rdi
movb $0x1, (%rax)
movq -0x100(%rbp), %rdx
movq -0x28(%rbp), %rcx
subq $0x1, %rcx
movl $0x1, %esi
callq 0x15300
movq -0x310(%rbp), %rdi
andb $0x1, %al
movb %al, -0x1f1(%rbp)
movq -0xd8(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
testb $0x1, -0x1f1(%rbp)
je 0x157a2
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
movb $0x1, -0x1(%rbp)
jmp 0x159aa
jmp 0x1596f
jmp 0x1596d
movq $0xe1, -0x200(%rbp)
movq $0x0, -0x208(%rbp)
movq $0x0, -0x210(%rbp)
movb $0x0, -0x211(%rbp)
movzbl -0x211(%rbp), %eax
cmpl $0x4, %eax
jge 0x158b9
movq -0x310(%rbp), %rsi
movq -0xd8(%rbp), %rdx
leaq -0x2b8(%rbp), %rdi
movzbl -0x211(%rbp), %ecx
callq 0x159c0
movq -0x310(%rbp), %rsi
movq -0xd8(%rbp), %rcx
leaq -0x2e8(%rbp), %rdi
leaq -0x2b8(%rbp), %rdx
movzbl -0x211(%rbp), %r8d
callq 0x15c00
leaq -0x300(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
leaq -0x2c8(%rbp), %rdx
leaq -0x2d0(%rbp), %rcx
callq 0x11390
leaq -0x300(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
callq 0x113d0
movq -0x2c0(%rbp), %rax
addq -0x208(%rbp), %rax
movq %rax, -0x208(%rbp)
movq -0x2c8(%rbp), %rax
addq -0x210(%rbp), %rax
movq %rax, -0x210(%rbp)
cmpq $0x0, -0x2c8(%rbp)
je 0x158a4
movq -0x2d0(%rbp), %rax
movq %rax, -0x200(%rbp)
jmp 0x158a6
movb -0x211(%rbp), %al
addb $0x1, %al
movb %al, -0x211(%rbp)
jmp 0x157d4
cmpq $0x0, -0x208(%rbp)
ja 0x158cd
cmpq $0x1, -0x210(%rbp)
jbe 0x158e9
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
movb $0x1, -0x1(%rbp)
jmp 0x159aa
cmpq $0x1, -0x210(%rbp)
jne 0x1596b
movq -0x310(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0x5590
movq -0x310(%rbp), %rdi
movb $0x2, (%rax)
movq -0x200(%rbp), %rdx
movq -0x28(%rbp), %rcx
subq $0x1, %rcx
movl $0x2, %esi
callq 0x15300
movq -0x310(%rbp), %rdi
andb $0x1, %al
movb %al, -0x301(%rbp)
movq -0xd8(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
testb $0x1, -0x301(%rbp)
je 0x15969
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
movb $0x1, -0x1(%rbp)
jmp 0x159aa
jmp 0x1596f
jmp 0x1596d
jmp 0x1596f
leaq -0xc0(%rbp), %rdi
callq 0x55c0
jmp 0x15515
jmp 0x15982
leaq -0x90(%rbp), %rdi
callq 0x55c0
jmp 0x15470
movq -0x310(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movb $0x0, (%rax)
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x330, %rsp            # imm = 0x330
popq %rbp
retq
nopl (%rax,%rax)