// File: /workspace/github_cpp_makefile_star2_O2/kobanium[P]Ray/src/feature/Nakade.cpp
// Function: IsNakadeSelfAtari(game_info_t const*, int, int)
bool
IsNakadeSelfAtari( const game_info_t *game, const int pos, const int color )
{
  const char *board = game->board;
  const string_t *string = game->string;
  const int *string_id = game->string_id;
  const int *string_next = game->string_next;
  const int neighbor4[4] = { NORTH(pos), WEST(pos), EAST(pos), SOUTH(pos) };
  unsigned long long hash = 0;
  int stones[10], checked[4] = { 0 };
  int check = 0, n = 0, my_stone, reviser, id;

  // 上下左右を確認し, 自分の連だったら, それぞれの石の座標を記録
  for (int i = 0 ; i < 4; i++) {
    if (board[neighbor4[i]] == color) {
      id = string_id[neighbor4[i]];
      bool check_flag = false;
      for (int j = 0; j < check; j++) {
        if (checked[j] == id) {
          check_flag = true;
          break;
        }
      }
      if (check_flag) continue;
      my_stone = string[id].origin;
      while (my_stone != STRING_END) {
        stones[n++] = my_stone;
        my_stone = string_next[my_stone];
      }
      checked[check++] = id;
    }
  }

  // 確認している座標も加える
  stones[n++] = pos;
  
  // 連の大きさが6以上なら打たないように
  // falseを返す
  if (n > 5) {
    return false;
  }

  // 座標をソート
  std::sort(stones, stones + n);

  // 石の座標の補正項
  reviser = start - stones[0];

  // ハッシュ値を計算
  for (int i = 0; i < n; i++) {
    hash ^= shape_bit[stones[i] + reviser];
  }

  // ハッシュ値が一致しているか確認
  // ナカデのパターンならばtrueを返す
  // そうでなければfalseを返す
  switch (n) {
    case 3:
    case 4:
    case 5:
      for (int i = 0; i < NAKADE_PATTERNS[n - 3]; i++) {
        if (nakade_hash[n - 3][i] == hash) {
          return true;
        }
      }
      break;
  }

  return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x50, %rsp
leaq 0x9620(%rdi), %rax
leaq 0x96200(%rdi), %rcx
leaq 0x21e97(%rip), %r8      # 0x618bc
movl (%r8), %r8d
movl %esi, %r9d
subl %r8d, %r9d
movl %r9d, (%rsp)
leal -0x1(%rsi), %r9d
movl %r9d, 0x4(%rsp)
leal 0x1(%rsi), %r9d
movl %r9d, 0x8(%rsp)
addl %esi, %r8d
movl %r8d, 0xc(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
xorl %r8d, %r8d
xorl %r9d, %r9d
xorl %ebp, %ebp
movslq %ebp, %r14
cmpq $0x4, %r8
je 0x3faf2
movslq (%rsp,%r8,4), %r10
movsbl 0x43f8(%rdi,%r10), %r11d
cmpl %edx, %r11d
jne 0x3faea
movl 0x95720(%rdi,%r10,4), %r10d
movslq %r10d, %r11
testl %r9d, %r9d
movl $0x0, %ebx
cmovgl %r9d, %ebx
xorl %r15d, %r15d
cmpq %r15, %rbx
je 0x3faaa
leaq 0x1(%r15), %r12
cmpl %r10d, 0x10(%rsp,%r15,4)
movq %r12, %r15
jne 0x3fa95
jmp 0x3faea
imulq $0x7c8, %r11, %r11      # imm = 0x7C8
leaq (%rax,%r11), %rbx
addq $0x7bc, %rbx            # imm = 0x7BC
leaq (%rsp,%r14,4), %r11
addq $0x20, %r11
movslq (%rbx), %rbx
cmpq $0x2b7, %rbx            # imm = 0x2B7
je 0x3fadf
movl %ebx, (%r11)
leaq (%rcx,%rbx,4), %rbx
incl %ebp
addq $0x4, %r11
jmp 0x3fac4
movslq %r9d, %r11
incl %r9d
movl %r10d, 0x10(%rsp,%r11,4)
incq %r8
jmp 0x3fa5c
movl %esi, 0x20(%rsp,%r14,4)
cmpl $0x4, %r14d
jle 0x3fb04
xorl %eax, %eax
jmp 0x3fb87
leaq (%rsp,%r14,4), %rsi
addq $0x20, %rsi
addq $0x4, %rsi
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0x4009e
movl 0x21db5(%rip), %ecx     # 0x618d8
subl (%rbx), %ecx
xorl %eax, %eax
movslq %ecx, %rdx
leaq 0x1c6dfb0f(%rip), %rsi  # 0x1c71f640
xorl %ecx, %ecx
cmpq %r14, %rax
jg 0x3fb49
movslq 0x20(%rsp,%rax,4), %rdi
addq %rdx, %rdi
xorq (%rsi,%rdi,8), %rcx
incq %rax
jmp 0x3fb33
addl $-0x2, %ebp
xorl %eax, %eax
cmpl $0x2, %ebp
ja 0x3fb87
movl %ebp, %esi
leaq 0x8364(%rip), %rdx      # 0x47ec0
movl (%rdx,%rsi,4), %edx
testl %edx, %edx
cmovlel %eax, %edx
imulq $0x48, %rsi, %rsi
leaq 0x1c6e1c21(%rip), %rdi  # 0x1c721790
xorl %r8d, %r8d
cmpq %r8, %rdx
setne %al
je 0x3fb87
leaq (%rsi,%r8,8), %r9
incq %r8
cmpq %rcx, (%rdi,%r9)
jne 0x3fb72
addq $0x50, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq