// File: kobanium[P]Ray/src/feature/SimulationFeature.cpp
// Function: CheckFeatureLib2ForSimulation(game_info_t*, int, int, int*, int&)
static void
CheckFeatureLib2ForSimulation( game_info_t *game, const int color, const int id, int update[], int &update_num )
{
  const int *string_id = game->string_id;
  const string_t *string = game->string;
  const char *board = game->board;
  int neighbor = string[id].neighbor[0];
  int lib1, lib2;
  bool capturable1, capturable2;

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

  // 呼吸点の周囲が空点3つ, または呼吸点が3つ以上の自分の連に接続できるかで特徴を判定
  if (nb4_empty[Pat3(game->pat, lib1)] == 3 ||
      (board[NORTH(lib1)] == color && string_id[NORTH(lib1)] != id &&
       string[string_id[NORTH(lib1)]].libs >= 3) ||
      (board[ WEST(lib1)] == color && string_id[ WEST(lib1)] != id &&
       string[string_id[WEST(lib1)]].libs >= 3) ||
      (board[ EAST(lib1)] == color && string_id[ EAST(lib1)] != id &&
       string[string_id[EAST(lib1)]].libs >= 3) ||
      (board[SOUTH(lib1)] == color && string_id[SOUTH(lib1)] != id &&
       string[string_id[SOUTH(lib1)]].libs >= 3)) {
    CompareSwapFeature(game->tactical_features, lib1, EXTENSION, SIM_2POINT_EXTENSION_SAFELY);
  } else {
    CompareSwapFeature(game->tactical_features, lib1, EXTENSION, SIM_2POINT_EXTENSION);
  }

  // 呼吸点の周囲が空点3つ, または呼吸点が3つ以上の自分の連に接続できるかで特徴を判定
  if (nb4_empty[Pat3(game->pat, lib2)] == 3 ||
      (board[NORTH(lib2)] == color && string_id[NORTH(lib2)] != id &&
       string[string_id[NORTH(lib2)]].libs >= 3) ||
      (board[ WEST(lib2)] == color && string_id[ WEST(lib2)] != id &&
       string[string_id[WEST(lib2)]].libs >= 3) ||
      (board[ EAST(lib2)] == color && string_id[ EAST(lib2)] != id &&
       string[string_id[EAST(lib2)]].libs >= 3) ||
      (board[SOUTH(lib2)] == color && string_id[SOUTH(lib2)] != id &&
       string[string_id[SOUTH(lib2)]].libs >= 3)) {
    CompareSwapFeature(game->tactical_features, lib2, EXTENSION, SIM_2POINT_EXTENSION_SAFELY);
  } else {
    CompareSwapFeature(game->tactical_features, lib2, EXTENSION, SIM_2POINT_EXTENSION);
  }

  // レートの更新対象に入れる
  update[update_num++] = lib1;
  update[update_num++] = lib2;

  // 呼吸点が2つになった連の周囲の敵連を調べる
  // 1. 呼吸点が1つの敵連
  // 2. 呼吸点が2つの敵連
  // それぞれに対して, 特徴を判定する
  while (neighbor != NEIGHBOR_END) {
    if (string[neighbor].libs == 1) {
      lib1 = string[neighbor].lib[0];
      update[update_num++] = lib1;
      if (string[neighbor].size <= 2) {
        CompareSwapFeature(game->tactical_features, lib1, CAPTURE, SIM_2POINT_CAPTURE_SMALL);
      } else {
        CompareSwapFeature(game->tactical_features, lib1, CAPTURE, SIM_2POINT_CAPTURE_LARGE);
      }
    } else if (string[neighbor].libs == 2) {
      lib1 = string[neighbor].lib[0];
      lib2 = string[neighbor].lib[lib1];
      update[update_num++] = lib1;
      update[update_num++] = lib2;
      capturable1 = IsCapturableAtariForSimulation(game, lib1, color, neighbor);
      capturable2 = IsCapturableAtariForSimulation(game, lib2, color, neighbor);
      if (string[neighbor].size <= 2) {
        if (capturable1) {
          CompareSwapFeature(game->tactical_features, lib1, ATARI, SIM_2POINT_C_ATARI_SMALL);
        } else {
          CompareSwapFeature(game->tactical_features, lib1, ATARI, SIM_2POINT_ATARI_SMALL);
        }
        if (capturable2) {
          CompareSwapFeature(game->tactical_features, lib2, ATARI, SIM_2POINT_C_ATARI_SMALL);
        } else {
          CompareSwapFeature(game->tactical_features, lib2, ATARI, SIM_2POINT_ATARI_SMALL);
        }
      } else {
        if (capturable1) {
          CompareSwapFeature(game->tactical_features, lib1, ATARI, SIM_2POINT_C_ATARI_LARGE);
        } else {
          CompareSwapFeature(game->tactical_features, lib1, ATARI, SIM_2POINT_ATARI_LARGE);
        }
        if (capturable2) {
          CompareSwapFeature(game->tactical_features, lib2, ATARI, SIM_2POINT_C_ATARI_LARGE);
        } else {
          CompareSwapFeature(game->tactical_features, lib2, ATARI, SIM_2POINT_ATARI_LARGE);
        }
      }
    }
    neighbor = string[id].neighbor[neighbor];
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movq %r8, -0x20(%rbp)
movq -0x8(%rbp), %rax
addq $0x95720, %rax          # imm = 0x95720
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
addq $0x9620, %rax           # imm = 0x9620
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
addq $0x43f8, %rax           # imm = 0x43F8
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x57c(%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x30(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x40(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x44(%rbp)
movq -0x8(%rbp), %rdi
addq $0x4748, %rdi           # imm = 0x4748
movl -0x40(%rbp), %esi
callq 0x93d30
movl %eax, %eax
movl %eax, %ecx
leaq 0x1ab0f4eb(%rip), %rax  # 0x1abb0860
movzbl (%rax,%rcx), %eax
cmpl $0x3, %eax
je 0xa14ee
movq -0x38(%rbp), %rax
movl -0x40(%rbp), %ecx
leaq 0x466bc(%rip), %rdx     # 0xe7a4c
subl (%rdx), %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa13e8
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
leaq 0x466a0(%rip), %rdx     # 0xe7a4c
subl (%rdx), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa13e8
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x40(%rbp), %edx
leaq 0x46681(%rip), %rsi     # 0xe7a4c
subl (%rsi), %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jge 0xa14ee
movq -0x38(%rbp), %rax
movl -0x40(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa143c
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa143c
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x40(%rbp), %edx
subl $0x1, %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jge 0xa14ee
movq -0x38(%rbp), %rax
movl -0x40(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa148c
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa148c
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x40(%rbp), %edx
addl $0x1, %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jge 0xa14ee
movq -0x38(%rbp), %rax
movl -0x40(%rbp), %ecx
leaq 0x465b2(%rip), %rdx     # 0xe7a4c
addl (%rdx), %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa150d
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
leaq 0x46596(%rip), %rdx     # 0xe7a4c
addl (%rdx), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa150d
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x40(%rbp), %edx
leaq 0x46577(%rip), %rsi     # 0xe7a4c
addl (%rsi), %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jl 0xa150d
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
movl $0x3, %edx
movl $0x4, %ecx
callq 0xa35f0
jmp 0xa152a
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
movl $0x3, %edx
movl $0x2, %ecx
callq 0xa35f0
movq -0x8(%rbp), %rdi
addq $0x4748, %rdi           # imm = 0x4748
movl -0x44(%rbp), %esi
callq 0x93d30
movl %eax, %eax
movl %eax, %ecx
leaq 0x1ab0f318(%rip), %rax  # 0x1abb0860
movzbl (%rax,%rcx), %eax
cmpl $0x3, %eax
je 0xa16c1
movq -0x38(%rbp), %rax
movl -0x44(%rbp), %ecx
leaq 0x464e9(%rip), %rdx     # 0xe7a4c
subl (%rdx), %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa15bb
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
leaq 0x464cd(%rip), %rdx     # 0xe7a4c
subl (%rdx), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa15bb
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x44(%rbp), %edx
leaq 0x464ae(%rip), %rsi     # 0xe7a4c
subl (%rsi), %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jge 0xa16c1
movq -0x38(%rbp), %rax
movl -0x44(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa160f
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa160f
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x44(%rbp), %edx
subl $0x1, %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jge 0xa16c1
movq -0x38(%rbp), %rax
movl -0x44(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa165f
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa165f
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x44(%rbp), %edx
addl $0x1, %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jge 0xa16c1
movq -0x38(%rbp), %rax
movl -0x44(%rbp), %ecx
leaq 0x463df(%rip), %rdx     # 0xe7a4c
addl (%rdx), %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl -0xc(%rbp), %eax
jne 0xa16e0
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
leaq 0x463c3(%rip), %rdx     # 0xe7a4c
addl (%rdx), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x10(%rbp), %eax
je 0xa16e0
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movl -0x44(%rbp), %edx
leaq 0x463a4(%rip), %rsi     # 0xe7a4c
addl (%rsi), %edx
movslq %edx, %rdx
movslq (%rcx,%rdx,4), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jl 0xa16e0
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x44(%rbp), %esi
movl $0x3, %edx
movl $0x4, %ecx
callq 0xa35f0
jmp 0xa16fd
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x44(%rbp), %esi
movl $0x3, %edx
movl $0x2, %ecx
callq 0xa35f0
movl -0x40(%rbp), %edx
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl -0x44(%rbp), %edx
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
cmpl $0x11f, -0x3c(%rbp)     # imm = 0x11F
je 0xa19f0
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xa17e3
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %edx
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jg 0xa17c4
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
xorl %edx, %edx
movl $0x6, %ecx
callq 0xa35f0
jmp 0xa17de
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
xorl %edx, %edx
movl $0x8, %ecx
callq 0xa35f0
jmp 0xa19ca
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x4(%rax)
jne 0xa19c8
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x40(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x44(%rbp)
movl -0x40(%rbp), %edx
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl -0x44(%rbp), %edx
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movq -0x8(%rbp), %rdi
movl -0x40(%rbp), %esi
movl -0xc(%rbp), %edx
movl -0x3c(%rbp), %ecx
callq 0xa8790
andb $0x1, %al
movb %al, -0x45(%rbp)
movq -0x8(%rbp), %rdi
movl -0x44(%rbp), %esi
movl -0xc(%rbp), %edx
movl -0x3c(%rbp), %ecx
callq 0xa8790
andb $0x1, %al
movb %al, -0x46(%rbp)
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jg 0xa1940
testb $0x1, -0x45(%rbp)
je 0xa18dc
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
movl $0x2, %edx
movl $0x7, %ecx
callq 0xa35f0
jmp 0xa18f9
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
movl $0x2, %edx
movl $0x3, %ecx
callq 0xa35f0
testb $0x1, -0x46(%rbp)
je 0xa191e
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x44(%rbp), %esi
movl $0x2, %edx
movl $0x7, %ecx
callq 0xa35f0
jmp 0xa193b
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x44(%rbp), %esi
movl $0x2, %edx
movl $0x3, %ecx
callq 0xa35f0
jmp 0xa19c6
testb $0x1, -0x45(%rbp)
je 0xa1965
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
movl $0x2, %edx
movl $0x9, %ecx
callq 0xa35f0
jmp 0xa1982
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x40(%rbp), %esi
movl $0x2, %edx
movl $0x5, %ecx
callq 0xa35f0
testb $0x1, -0x46(%rbp)
je 0xa19a7
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x44(%rbp), %esi
movl $0x2, %edx
movl $0x9, %ecx
callq 0xa35f0
jmp 0xa19c4
movq -0x8(%rbp), %rdi
addq $0x97372, %rdi          # imm = 0x97372
movl -0x44(%rbp), %esi
movl $0x2, %edx
movl $0x5, %ecx
callq 0xa35f0
jmp 0xa19c6
jmp 0xa19c8
jmp 0xa19ca
movq -0x30(%rbp), %rax
movslq -0x10(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x3c(%rbp), %rcx
movswl 0x57c(%rax,%rcx,2), %eax
movl %eax, -0x3c(%rbp)
jmp 0xa1731
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)