// File: 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
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq -0x10(%rbp), %rax
addq $0x43f8, %rax           # imm = 0x43F8
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
addq $0x9620, %rax           # imm = 0x9620
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
addq $0x95720, %rax          # imm = 0x95720
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
addq $0x96200, %rax          # imm = 0x96200
movq %rax, -0x38(%rbp)
movl -0x14(%rbp), %eax
leaq 0x43545(%rip), %rcx     # 0xe7a4c
subl (%rcx), %eax
movl %eax, -0x50(%rbp)
movl -0x14(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x4c(%rbp)
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
movl -0x14(%rbp), %eax
leaq 0x43524(%rip), %rcx     # 0xe7a4c
addl (%rcx), %eax
movl %eax, -0x44(%rbp)
movq $0x0, -0x58(%rbp)
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x72b0
movl $0x0, -0x94(%rbp)
movl $0x0, -0x98(%rbp)
movl $0x0, -0xa8(%rbp)
cmpl $0x4, -0xa8(%rbp)
jge 0xa469e
movq -0x20(%rbp), %rax
movslq -0xa8(%rbp), %rcx
movslq -0x50(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl -0x18(%rbp), %eax
jne 0xa4688
movq -0x30(%rbp), %rax
movslq -0xa8(%rbp), %rcx
movslq -0x50(%rbp,%rcx,4), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0xa4(%rbp)
movb $0x0, -0xa9(%rbp)
movl $0x0, -0xb0(%rbp)
movl -0xb0(%rbp), %eax
cmpl -0x94(%rbp), %eax
jge 0xa45fa
movslq -0xb0(%rbp), %rax
movl -0x90(%rbp,%rax,4), %eax
cmpl -0xa4(%rbp), %eax
jne 0xa45e7
movb $0x1, -0xa9(%rbp)
jmp 0xa45fa
jmp 0xa45e9
movl -0xb0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb0(%rbp)
jmp 0xa45ba
testb $0x1, -0xa9(%rbp)
je 0xa4608
jmp 0xa468a
movq -0x28(%rbp), %rax
movslq -0xa4(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %eax
movl %eax, -0x9c(%rbp)
cmpl $0x2b7, -0x9c(%rbp)     # imm = 0x2B7
je 0xa4668
movl -0x9c(%rbp), %ecx
movl -0x98(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x98(%rbp)
cltq
movl %ecx, -0x80(%rbp,%rax,4)
movq -0x38(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x9c(%rbp)
jmp 0xa4629
movl -0xa4(%rbp), %ecx
movl -0x94(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x94(%rbp)
cltq
movl %ecx, -0x90(%rbp,%rax,4)
jmp 0xa468a
movl -0xa8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa8(%rbp)
jmp 0xa4566
movl -0x14(%rbp), %ecx
movl -0x98(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x98(%rbp)
cltq
movl %ecx, -0x80(%rbp,%rax,4)
cmpl $0x5, -0x98(%rbp)
jle 0xa46ca
movb $0x0, -0x1(%rbp)
jmp 0xa47c6
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rsi
movslq -0x98(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
callq 0xa5240
movl 0x4337d(%rip), %eax     # 0xe7a68
subl -0x80(%rbp), %eax
movl %eax, -0xa0(%rbp)
movl $0x0, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
cmpl -0x98(%rbp), %eax
jge 0xa4744
movslq -0xb4(%rbp), %rax
movl -0x80(%rbp,%rax,4), %eax
addl -0xa0(%rbp), %eax
movslq %eax, %rcx
leaq 0x1c701099(%rip), %rax  # 0x1c7a57c0
movq (%rax,%rcx,8), %rax
xorq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0xa46fe
movl -0x98(%rbp), %eax
addl $-0x3, %eax
subl $0x2, %eax
ja 0xa47c2
jmp 0xa4754
movl $0x0, -0xb8(%rbp)
movl -0xb8(%rbp), %eax
movl -0x98(%rbp), %ecx
subl $0x3, %ecx
movslq %ecx, %rdx
leaq 0xc699(%rip), %rcx      # 0xb0e10
cmpl (%rcx,%rdx,4), %eax
jge 0xa47c0
movl -0x98(%rbp), %eax
subl $0x3, %eax
movslq %eax, %rcx
leaq 0x1c703181(%rip), %rax  # 0x1c7a7910
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movslq -0xb8(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq -0x58(%rbp), %rax
jne 0xa47ad
movb $0x1, -0x1(%rbp)
jmp 0xa47c6
jmp 0xa47af
movl -0xb8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb8(%rbp)
jmp 0xa475e
jmp 0xa47c2
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xc0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)