// File: kobanium[P]Ray/src/feature/UctFeature.cpp
// Function: CheckFeaturesLib2ForTree(game_info_t const*, int, int, unsigned int*)
void
CheckFeaturesLib2ForTree( const game_info_t *game, const int color, const int id, unsigned int *tactical_features )
{
  const string_t *string = game->string;
  int lib1, lib2, neighbor, lib1_state, lib2_state;

  // 呼吸点が2つになった連の呼吸点を取り出す
  lib1 = string[id].lib[0];
  lib2 = string[id].lib[lib1];

  // 呼吸点に打つ特徴
  lib1_state = CheckLibertyState(game, lib1, color, id);
  lib2_state = CheckLibertyState(game, lib2, color, id);
  switch (lib1_state) {
  case L_DECREASE :
    CompareSwapFeature(tactical_features, lib1, UCT_EXTENSION_INDEX, UCT_2POINT_EXTENSION_DECREASE);
    break;
  case L_EVEN :
    CompareSwapFeature(tactical_features, lib1, UCT_EXTENSION_INDEX, UCT_2POINT_EXTENSION_EVEN);
    break;
  case L_INCREASE:
    CompareSwapFeature(tactical_features, lib1, UCT_EXTENSION_INDEX, UCT_2POINT_EXTENSION_INCREASE);
    break;
  default :
    break;
  }
  switch (lib2_state) {
  case L_DECREASE :
    CompareSwapFeature(tactical_features, lib2, UCT_EXTENSION_INDEX, UCT_2POINT_EXTENSION_DECREASE);
    break;
  case L_EVEN :
    CompareSwapFeature(tactical_features, lib2, UCT_EXTENSION_INDEX, UCT_2POINT_EXTENSION_EVEN);
    break;
  case L_INCREASE:
    CompareSwapFeature(tactical_features, lib2, UCT_EXTENSION_INDEX, UCT_2POINT_EXTENSION_INCREASE);
    break;
  default :
    break;
  }


  // 呼吸点が2つになった連の周囲の敵連を調べる
  // 1. 呼吸点が1つの敵連
  // 2. 呼吸点が2つの敵連
  // それぞれに対して, 特徴を判定する
  // さらに2.に関しては1手で取れるかどうかも考慮する
  neighbor = string[id].neighbor[0];
  if (string[id].size <= 2) {
    while (neighbor != NEIGHBOR_END) {
      if (string[neighbor].libs == 1) {
        lib1 = string[neighbor].lib[0];
        if (string[neighbor].size <= 2) {
          CompareSwapFeature(tactical_features, lib1, UCT_CAPTURE_INDEX, UCT_2POINT_CAPTURE_S_S);
        } else {
          CompareSwapFeature(tactical_features, lib1, UCT_CAPTURE_INDEX, UCT_2POINT_CAPTURE_S_L);
        }
      } else if (string[neighbor].libs == 2) {
        lib1 = string[neighbor].lib[0];
        lib2 = string[neighbor].lib[lib1];
        if (string[neighbor].size <= 2) {
          if (IsCapturableAtari(game, lib1, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_S_S);
          } else {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_ATARI_S_S);
          }
          if (IsCapturableAtari(game, lib2, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_S_S);
          } else {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_ATARI_S_S);
          }
        } else {
          if (IsCapturableAtari(game, lib1, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_S_L);
          } else {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_ATARI_S_L);
          }
          if (IsCapturableAtari(game, lib2, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_S_L);
          } else {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_ATARI_S_L);
          }
        }
      }
      neighbor = string[id].neighbor[neighbor];
    }
  } else {
    while (neighbor != NEIGHBOR_END) {
      if (string[neighbor].libs == 1) {
        lib1 = string[neighbor].lib[0];
        if (string[neighbor].size <= 2) {
          CompareSwapFeature(tactical_features, lib1, UCT_CAPTURE_INDEX, UCT_2POINT_CAPTURE_L_S);
        } else {
          CompareSwapFeature(tactical_features, lib1, UCT_CAPTURE_INDEX, UCT_2POINT_CAPTURE_L_L);
        }
      } else if (string[neighbor].libs == 2) {
        lib1 = string[neighbor].lib[0];
        lib2 = string[neighbor].lib[lib1];
        if (string[neighbor].size <= 2) {
          if (IsCapturableAtari(game, lib1, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_L_S);
          } else {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_ATARI_L_S);
          }
          if (IsCapturableAtari(game, lib2, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_L_S);
          } else {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_ATARI_L_S);
          }
        } else {
          if (IsCapturableAtari(game, lib1, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_L_L);
          } else {
            CompareSwapFeature(tactical_features, lib1, UCT_ATARI_INDEX, UCT_2POINT_ATARI_L_L);
          }
          if (IsCapturableAtari(game, lib2, color, string[neighbor].origin)) {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_C_ATARI_L_L);
          } else {
            CompareSwapFeature(tactical_features, lib2, UCT_ATARI_INDEX, UCT_2POINT_ATARI_L_L);
          }
        }
      }
      neighbor = string[id].neighbor[neighbor];
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movq -0x8(%rbp), %rax
addq $0x9620, %rax           # imm = 0x9620
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
movswl 0x8(%rax,%rcx), %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x24(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %esi
movl -0xc(%rbp), %edx
movl -0x10(%rbp), %ecx
callq 0xa8600
movl %eax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
movl -0xc(%rbp), %edx
movl -0x10(%rbp), %ecx
callq 0xa8600
movl %eax, -0x34(%rbp)
movl -0x30(%rbp), %eax
movl %eax, -0x38(%rbp)
testl %eax, %eax
je 0xa6363
jmp 0xa634f
movl -0x38(%rbp), %eax
subl $0x1, %eax
je 0xa637b
jmp 0xa6359
movl -0x38(%rbp), %eax
subl $0x2, %eax
je 0xa6393
jmp 0xa63ab
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x3, %edx
movl $0x2, %ecx
callq 0xa7430
jmp 0xa63ad
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x3, %edx
movl $0x4, %ecx
callq 0xa7430
jmp 0xa63ad
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x3, %edx
movl $0x6, %ecx
callq 0xa7430
jmp 0xa63ad
jmp 0xa63ad
movl -0x34(%rbp), %eax
movl %eax, -0x3c(%rbp)
testl %eax, %eax
je 0xa63cd
jmp 0xa63b9
movl -0x3c(%rbp), %eax
subl $0x1, %eax
je 0xa63e5
jmp 0xa63c3
movl -0x3c(%rbp), %eax
subl $0x2, %eax
je 0xa63fd
jmp 0xa6415
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x3, %edx
movl $0x2, %ecx
callq 0xa7430
jmp 0xa6417
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x3, %edx
movl $0x4, %ecx
callq 0xa7430
jmp 0xa6417
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x3, %edx
movl $0x6, %ecx
callq 0xa7430
jmp 0xa6417
jmp 0xa6417
movq -0x20(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x57c(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x20(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jg 0xa66ee
jmp 0xa6454
cmpl $0x11f, -0x2c(%rbp)     # imm = 0x11F
je 0xa66e9
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xa64da
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jg 0xa64c2
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
xorl %edx, %edx
movl $0x9, %ecx
callq 0xa7430
jmp 0xa64d5
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
xorl %edx, %edx
movl $0xb, %ecx
callq 0xa7430
jmp 0xa66c3
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x4(%rax)
jne 0xa66c1
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x24(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jg 0xa6607
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa6579
jmp 0xa6591
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0xb, %ecx
callq 0xa7430
jmp 0xa65a7
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0x3, %ecx
callq 0xa7430
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa65d4
jmp 0xa65ec
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0xb, %ecx
callq 0xa7430
jmp 0xa6602
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0x3, %ecx
callq 0xa7430
jmp 0xa66bf
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa6634
jmp 0xa664c
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0xd, %ecx
callq 0xa7430
jmp 0xa6662
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0x5, %ecx
callq 0xa7430
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa668f
jmp 0xa66a7
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0xd, %ecx
callq 0xa7430
jmp 0xa66bd
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0x5, %ecx
callq 0xa7430
jmp 0xa66bf
jmp 0xa66c1
jmp 0xa66c3
movq -0x20(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x2c(%rbp), %rcx
movswl 0x57c(%rax,%rcx,2), %eax
movl %eax, -0x2c(%rbp)
jmp 0xa6454
jmp 0xa6987
jmp 0xa66f0
cmpl $0x11f, -0x2c(%rbp)     # imm = 0x11F
je 0xa6985
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xa6776
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jg 0xa675e
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
xorl %edx, %edx
movl $0xd, %ecx
callq 0xa7430
jmp 0xa6771
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
xorl %edx, %edx
movl $0xe, %ecx
callq 0xa7430
jmp 0xa695f
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x4(%rax)
jne 0xa695d
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x24(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jg 0xa68a3
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa6815
jmp 0xa682d
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0xf, %ecx
callq 0xa7430
jmp 0xa6843
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0x7, %ecx
callq 0xa7430
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa6870
jmp 0xa6888
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0xf, %ecx
callq 0xa7430
jmp 0xa689e
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0x7, %ecx
callq 0xa7430
jmp 0xa695b
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa68d0
jmp 0xa68e8
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0x11, %ecx
callq 0xa7430
jmp 0xa68fe
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
movl $0x2, %edx
movl $0x9, %ecx
callq 0xa7430
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
movl -0xc(%rbp), %edx
movq -0x20(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movl 0x7bc(%rax), %ecx
callq 0xa7dc0
testb $0x1, %al
jne 0xa692b
jmp 0xa6943
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0x11, %ecx
callq 0xa7430
jmp 0xa6959
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
movl $0x2, %edx
movl $0x9, %ecx
callq 0xa7430
jmp 0xa695b
jmp 0xa695d
jmp 0xa695f
movq -0x20(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x2c(%rbp), %rcx
movswl 0x57c(%rax,%rcx,2), %eax
movl %eax, -0x2c(%rbp)
jmp 0xa66f0
jmp 0xa6987
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)