// File: kobanium[P]Ray/src/feature/Nakade.cpp
// Function: FindNakadePos(game_info_t const*, int, int)
static int
FindNakadePos( const game_info_t *game, const int pos, const int color )
{
  const char *board = game->board;
  bool flag[BOARD_MAX] = { false };  
  nakade_queue_t nakade_queue;
  unsigned long long hash = 0;
  int nakade[10], neighbor4[4];
  int size = 0, nakade_num = 0, current_pos, reviser;

  // キューの初期化
  InitializeNakadeQueue(&nakade_queue);

  // 開始点をキューに入れる
  Enqueue(&nakade_queue, pos);

  // 確認済みのフラグ
  flag[pos] = true;

  // キューが空になるまでループ
  while (!IsQueueEmpty(&nakade_queue)) {
    current_pos = Dequeue(&nakade_queue);
    nakade[nakade_num++] = current_pos;

    // 領域のサイズが6以上になったら
    // ナカデではないと判定
    if (size > 5) return NOT_NAKADE;

    GetNeighbor4(neighbor4, current_pos);

    // 上下左右について, 未確認で, 自分の石か空点なら追加
    for (int i = 0; i < 4; i++) {
      if (!flag[neighbor4[i]] &&
          (board[neighbor4[i]] & color) == 0) {
        Enqueue(&nakade_queue, neighbor4[i]);
        flag[neighbor4[i]] = true;
        size++;
      }
    }
  }

  // 領域が6以上ならナカデではない
  if (nakade_num > 5) return NOT_NAKADE;

  // 座標をソート
  std::sort(nakade, nakade + nakade_num);

  // 座標の補正項を算出
  reviser = start - nakade[0];

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

  // ナカデの形になっていれば, その座標を返す
  switch (nakade_num) {
    case 3:
    case 4:
    case 5:
      for (int i = 0; i < NAKADE_PATTERNS[nakade_num - 3]; i++) {
        if (nakade_hash[nakade_num - 3][i] == hash) {
        return nakade[0] + nakade_pos[nakade_num - 3][i];
        }
      }
      break;
  }

  return NOT_NAKADE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x450, %rsp            # imm = 0x450
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)
leaq -0x370(%rbp), %rdi
xorl %esi, %esi
movl $0x349, %edx            # imm = 0x349
callq 0x72b0
movq $0x0, -0x3f8(%rbp)
movl $0x0, -0x434(%rbp)
movl $0x0, -0x438(%rbp)
leaq -0x3f0(%rbp), %rdi
callq 0xa50f0
movl -0x14(%rbp), %esi
leaq -0x3f0(%rbp), %rdi
callq 0xa5110
movslq -0x14(%rbp), %rax
movb $0x1, -0x370(%rbp,%rax)
leaq -0x3f0(%rbp), %rdi
callq 0xa5190
xorb $-0x1, %al
testb $0x1, %al
jne 0xa4d13
jmp 0xa4e16
leaq -0x3f0(%rbp), %rdi
callq 0xa51b0
movl %eax, -0x43c(%rbp)
movl -0x43c(%rbp), %ecx
movl -0x438(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x438(%rbp)
cltq
movl %ecx, -0x420(%rbp,%rax,4)
cmpl $0x5, -0x434(%rbp)
jle 0xa4d5a
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xa4f6f
leaq -0x430(%rbp), %rdi
movl -0x43c(%rbp), %esi
callq 0x9bc90
movl $0x0, -0x444(%rbp)
cmpl $0x4, -0x444(%rbp)
jge 0xa4e11
movslq -0x444(%rbp), %rax
movslq -0x430(%rbp,%rax,4), %rax
testb $0x1, -0x370(%rbp,%rax)
jne 0xa4dfb
movq -0x20(%rbp), %rax
movslq -0x444(%rbp), %rcx
movslq -0x430(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
andl -0x18(%rbp), %eax
cmpl $0x0, %eax
jne 0xa4dfb
movslq -0x444(%rbp), %rax
movl -0x430(%rbp,%rax,4), %esi
leaq -0x3f0(%rbp), %rdi
callq 0xa5110
movslq -0x444(%rbp), %rax
movslq -0x430(%rbp,%rax,4), %rax
movb $0x1, -0x370(%rbp,%rax)
movl -0x434(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x434(%rbp)
jmp 0xa4dfd
movl -0x444(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x444(%rbp)
jmp 0xa4d76
jmp 0xa4cfc
cmpl $0x5, -0x438(%rbp)
jle 0xa4e2b
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xa4f6f
leaq -0x420(%rbp), %rdi
leaq -0x420(%rbp), %rsi
movslq -0x438(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
callq 0xa5240
movl 0x42c16(%rip), %eax     # 0xe7a68
subl -0x420(%rbp), %eax
movl %eax, -0x440(%rbp)
movl $0x0, -0x448(%rbp)
movl -0x448(%rbp), %eax
cmpl -0x438(%rbp), %eax
jge 0xa4eb7
movslq -0x448(%rbp), %rax
movl -0x420(%rbp,%rax,4), %eax
addl -0x440(%rbp), %eax
movslq %eax, %rcx
leaq 0x1c70092c(%rip), %rax  # 0x1c7a57c0
movq (%rax,%rcx,8), %rax
xorq -0x3f8(%rbp), %rax
movq %rax, -0x3f8(%rbp)
movl -0x448(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x448(%rbp)
jmp 0xa4e68
movl -0x438(%rbp), %eax
addl $-0x3, %eax
subl $0x2, %eax
ja 0xa4f68
jmp 0xa4ecb
movl $0x0, -0x44c(%rbp)
movl -0x44c(%rbp), %eax
movl -0x438(%rbp), %ecx
subl $0x3, %ecx
movslq %ecx, %rdx
leaq 0xbf22(%rip), %rcx      # 0xb0e10
cmpl (%rcx,%rdx,4), %eax
jge 0xa4f66
movl -0x438(%rbp), %eax
subl $0x3, %eax
movslq %eax, %rcx
leaq 0x1c702a0a(%rip), %rax  # 0x1c7a7910
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movslq -0x44c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpq -0x3f8(%rbp), %rax
jne 0xa4f50
movl -0x420(%rbp), %eax
movl -0x438(%rbp), %ecx
subl $0x3, %ecx
movslq %ecx, %rdx
leaq 0x1c702946(%rip), %rcx  # 0x1c7a7880
imulq $0x24, %rdx, %rdx
addq %rdx, %rcx
movslq -0x44c(%rbp), %rdx
addl (%rcx,%rdx,4), %eax
movl %eax, -0x4(%rbp)
jmp 0xa4f6f
jmp 0xa4f52
movl -0x44c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44c(%rbp)
jmp 0xa4ed5
jmp 0xa4f68
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x450, %rsp            # imm = 0x450
popq %rbp
retq
nopl (%rax,%rax)