// File: kobanium[P]Ray/src/feature/UctFeature.cpp
// Function: CheckSelfAtariForTree(game_info_t const*, int, int, unsigned int*)
bool
CheckSelfAtariForTree( const game_info_t *game, const int color, const int pos, unsigned int *tactical_features )
{
  const char *board = game->board;
  const string_t *string = game->string;
  const int *string_id = game->string_id;
  const int other = GetOppositeColor(color);
  int id, lib, already_num = 0, size = 0, libs = 0, count;
  int lib_candidate[PURE_BOARD_MAX], neighbor4[4], already[4] = { 0 };
  bool checked, flag, already_checked;

  GetNeighbor4(neighbor4, pos);

  for (int i = 0; i < 4; i++) {
    if (board[neighbor4[i]] == S_EMPTY) {
      lib_candidate[libs++] = neighbor4[i];
    }
  }

  //  空点
  if (libs >= 2) return true;

  //  上下左右の確認
  for (int i = 0; i < 4; i++) {
    if (board[neighbor4[i]] == color) {
      id = string_id[neighbor4[i]];
      already_checked = false;
      for (int j = 0; j < already_num; j++) {
        if (already[j] == id) {
          already_checked = true;
        }
      }
      if (already_checked) continue;

      if (string[id].libs > 2) return true;
      lib = string[id].lib[0];
      count = 0;
      while (lib != LIBERTY_END) {
        if (lib != pos) {
          checked = false;
          for (int j = 0; j < libs; j++) {
            if (lib_candidate[j] == lib) {
              checked = true;
              break;
            }
          }
          if (!checked) {
            lib_candidate[libs + count] = lib;
            count++;
          }
        }
        lib = string[id].lib[lib];
      }
      libs += count;
      size += string[id].size;
      already[already_num++] = id;
      if (libs >= 2) return true;
    } else if (board[neighbor4[i]] == other &&
               string[string_id[neighbor4[i]]].libs == 1) {
      return true;
    }
  }

  // 自己アタリの分類
  // 1.大きさが2以下の自己アタリ
  // 2.大きさが6以下でナカデの形になる自己アタリ
  // 3.それ以外の自己アタリ
  if (size < 2) {
    CompareSwapFeature(tactical_features, pos, UCT_CAPTURE_INDEX, UCT_SELF_ATARI_SMALL);
    flag = true;
  } else if (size < 6) {
    if (IsUctNakadeSelfAtari(game, pos, color)) {
      CompareSwapFeature(tactical_features, pos, UCT_CAPTURE_INDEX, UCT_SELF_ATARI_NAKADE);
      flag = true;
    } else {
      CompareSwapFeature(tactical_features, pos, UCT_CAPTURE_INDEX, UCT_SELF_ATARI_LARGE);
      flag = false;
    }
  } else {
    CompareSwapFeature(tactical_features, pos, UCT_CAPTURE_INDEX, UCT_SELF_ATARI_LARGE);
    flag = false;
  }
  return flag;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x640, %rsp            # imm = 0x640
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rax
addq $0x43f8, %rax           # imm = 0x43F8
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
addq $0x9620, %rax           # imm = 0x9620
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
addq $0x95720, %rax          # imm = 0x95720
movq %rax, -0x38(%rbp)
movl -0x14(%rbp), %edi
callq 0x25810
movl %eax, -0x3c(%rbp)
movl $0x0, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x50(%rbp)
leaq -0x620(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x72b0
leaq -0x610(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x9bc90
movl $0x0, -0x628(%rbp)
cmpl $0x4, -0x628(%rbp)
jge 0xa7569
movq -0x28(%rbp), %rax
movslq -0x628(%rbp), %rcx
movslq -0x610(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0xa7556
movslq -0x628(%rbp), %rax
movl -0x610(%rbp,%rax,4), %ecx
movl -0x50(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x50(%rbp)
cltq
movl %ecx, -0x600(%rbp,%rax,4)
jmp 0xa7558
movl -0x628(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x628(%rbp)
jmp 0xa750f
cmpl $0x2, -0x50(%rbp)
jl 0xa7578
movb $0x1, -0x1(%rbp)
jmp 0xa785c
movl $0x0, -0x62c(%rbp)
cmpl $0x4, -0x62c(%rbp)
jge 0xa77c0
movq -0x28(%rbp), %rax
movslq -0x62c(%rbp), %rcx
movslq -0x610(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl -0x14(%rbp), %eax
jne 0xa7758
movq -0x38(%rbp), %rax
movslq -0x62c(%rbp), %rcx
movslq -0x610(%rbp,%rcx,4), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x40(%rbp)
movb $0x0, -0x623(%rbp)
movl $0x0, -0x630(%rbp)
movl -0x630(%rbp), %eax
cmpl -0x48(%rbp), %eax
jge 0xa7611
movslq -0x630(%rbp), %rax
movl -0x620(%rbp,%rax,4), %eax
cmpl -0x40(%rbp), %eax
jne 0xa75fe
movb $0x1, -0x623(%rbp)
jmp 0xa7600
movl -0x630(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x630(%rbp)
jmp 0xa75d9
testb $0x1, -0x623(%rbp)
je 0xa761f
jmp 0xa77ac
movq -0x30(%rbp), %rax
movslq -0x40(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x4(%rax)
jle 0xa7640
movb $0x1, -0x1(%rbp)
jmp 0xa785c
movq -0x30(%rbp), %rax
movslq -0x40(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x44(%rbp)
movl $0x0, -0x54(%rbp)
cmpl $0x2b7, -0x44(%rbp)     # imm = 0x2B7
je 0xa7709
movl -0x44(%rbp), %eax
cmpl -0x18(%rbp), %eax
je 0xa76e6
movb $0x0, -0x621(%rbp)
movl $0x0, -0x634(%rbp)
movl -0x634(%rbp), %eax
cmpl -0x50(%rbp), %eax
jge 0xa76c0
movslq -0x634(%rbp), %rax
movl -0x600(%rbp,%rax,4), %eax
cmpl -0x44(%rbp), %eax
jne 0xa76ad
movb $0x1, -0x621(%rbp)
jmp 0xa76c0
jmp 0xa76af
movl -0x634(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x634(%rbp)
jmp 0xa7686
testb $0x1, -0x621(%rbp)
jne 0xa76e4
movl -0x44(%rbp), %ecx
movl -0x50(%rbp), %eax
addl -0x54(%rbp), %eax
cltq
movl %ecx, -0x600(%rbp,%rax,4)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0xa76e6
movq -0x30(%rbp), %rax
movslq -0x40(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x44(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x44(%rbp)
jmp 0xa7660
movl -0x54(%rbp), %eax
addl -0x50(%rbp), %eax
movl %eax, -0x50(%rbp)
movq -0x30(%rbp), %rax
movslq -0x40(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7c0(%rax), %eax
addl -0x4c(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x40(%rbp), %ecx
movl -0x48(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x48(%rbp)
cltq
movl %ecx, -0x620(%rbp,%rax,4)
cmpl $0x2, -0x50(%rbp)
jl 0xa7756
movb $0x1, -0x1(%rbp)
jmp 0xa785c
jmp 0xa77aa
movq -0x28(%rbp), %rax
movslq -0x62c(%rbp), %rcx
movslq -0x610(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl -0x3c(%rbp), %eax
jne 0xa77a8
movq -0x30(%rbp), %rax
movq -0x38(%rbp), %rcx
movslq -0x62c(%rbp), %rdx
movslq -0x610(%rbp,%rdx,4), %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xa77a8
movb $0x1, -0x1(%rbp)
jmp 0xa785c
jmp 0xa77aa
jmp 0xa77ac
movl -0x62c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x62c(%rbp)
jmp 0xa7582
cmpl $0x2, -0x4c(%rbp)
jge 0xa77e2
movq -0x20(%rbp), %rdi
movl -0x18(%rbp), %esi
xorl %edx, %edx
movl $0x1, %ecx
callq 0xa7430
movb $0x1, -0x622(%rbp)
jmp 0xa7851
cmpl $0x6, -0x4c(%rbp)
jge 0xa7835
movq -0x10(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x14(%rbp), %edx
callq 0xa47e0
testb $0x1, %al
jne 0xa77fd
jmp 0xa7819
movq -0x20(%rbp), %rdi
movl -0x18(%rbp), %esi
xorl %edx, %edx
movl $0x2, %ecx
callq 0xa7430
movb $0x1, -0x622(%rbp)
jmp 0xa7833
movq -0x20(%rbp), %rdi
movl -0x18(%rbp), %esi
xorl %edx, %edx
movl $0x3, %ecx
callq 0xa7430
movb $0x0, -0x622(%rbp)
jmp 0xa784f
movq -0x20(%rbp), %rdi
movl -0x18(%rbp), %esi
xorl %edx, %edx
movl $0x3, %ecx
callq 0xa7430
movb $0x0, -0x622(%rbp)
jmp 0xa7851
movb -0x622(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x640, %rsp            # imm = 0x640
popq %rbp
retq
nopw (%rax,%rax)