// File: kobanium[P]Ray/src/feature/Ladder.cpp
// Function: LadderExtension(game_info_t*, int, bool*)
void
LadderExtension( game_info_t *game, int color, bool *ladder_pos )
{
  const string_t *string = game->string;
  std::unique_ptr<search_game_info_t> search_game;
  bool checked[BOARD_MAX] = { false };

  for (int i = 0; i < MAX_STRING; i++) {
    if (!string[i].flag ||
        string[i].color != color) {
      continue;
    }
    // アタリから逃げる着手箇所
    int ladder = string[i].lib[0];

    bool flag = false;

    // アタリを逃げる手で未探索のものを確認
    if (!checked[ladder] && string[i].libs == 1) {
      if (!search_game)
        search_game.reset(new search_game_info_t(game));
      search_game_info_t *ladder_game = search_game.get();
      // 隣接する敵連を取って助かるかを確認
      int neighbor = string[i].neighbor[0];
      while (neighbor != NEIGHBOR_END && !flag) {
        if (string[neighbor].libs == 1) {
          if (IsLegal(game, string[neighbor].lib[0], color)) {
            PutStoneForSearch(ladder_game, string[neighbor].lib[0], color);
            if (IsLadderCaptured(0, ladder_game, string[i].origin, GetOppositeColor(color)) == DEAD) {
              if (string[i].size >= 2) {
                ladder_pos[string[neighbor].lib[0]] = true;
              }
            } else {
              flag = true;
            }
            Undo(ladder_game);
          }
        }
        neighbor = string[i].neighbor[neighbor];
      }

      // 取って助からない時は逃げてみる
      if (!flag) {
        if (IsLegal(game, ladder, color)) {
          PutStoneForSearch(ladder_game, ladder, color);
          if (string[i].size >= 2 &&
              IsLadderCaptured(0, ladder_game, ladder, GetOppositeColor(color)) == DEAD) {
            ladder_pos[ladder] = true;
          }
          Undo(ladder_game);
        }
      }
      checked[ladder] = true;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3f0, %rsp            # imm = 0x3F0
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
addq $0x9620, %rax           # imm = 0x9620
movq %rax, -0x20(%rbp)
leaq -0x28(%rbp), %rdi
callq 0xab040
leaq -0x380(%rbp), %rdi
xorl %esi, %esi
movl $0x349, %edx            # imm = 0x349
callq 0x72b0
movl $0x0, -0x384(%rbp)
cmpl $0x120, -0x384(%rbp)    # imm = 0x120
jge 0xaaab1
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
testb $0x1, 0x7c4(%rax)
je 0xaa6e5
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movsbl (%rax), %eax
cmpl -0xc(%rbp), %eax
je 0xaa6ea
jmp 0xaaa9d
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x388(%rbp)
movb $0x0, -0x389(%rbp)
movslq -0x388(%rbp), %rax
testb $0x1, -0x380(%rbp,%rax)
jne 0xaaa9b
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xaaa9b
leaq -0x28(%rbp), %rdi
callq 0xab070
testb $0x1, %al
jne 0xaa7c7
movl $0x69ae40, %edi         # imm = 0x69AE40
callq 0x7550
movq %rax, -0x3b8(%rbp)
jmp 0xaa764
movq -0x3b8(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x98300
jmp 0xaa776
movq -0x3b8(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0xab0a0
jmp 0xaa7c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x398(%rbp)
movl %eax, -0x39c(%rbp)
jmp 0xaaac3
movq -0x3b8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x398(%rbp)
movl %eax, -0x39c(%rbp)
movl $0x69ae40, %esi         # imm = 0x69AE40
callq 0x7560
jmp 0xaaac3
leaq -0x28(%rbp), %rdi
callq 0xaa280
movq %rax, -0x3a8(%rbp)
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x57c(%rax), %eax
movl %eax, -0x3ac(%rbp)
xorl %eax, %eax
cmpl $0x11f, -0x3ac(%rbp)    # imm = 0x11F
movb %al, -0x3b9(%rbp)
je 0xaa81b
movb -0x389(%rbp), %al
xorb $-0x1, %al
movb %al, -0x3b9(%rbp)
movb -0x3b9(%rbp), %al
testb $0x1, %al
jne 0xaa82a
jmp 0xaa9a4
movq -0x20(%rbp), %rax
movslq -0x3ac(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xaa975
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movslq -0x3ac(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
movswl 0x8(%rax,%rcx), %esi
movl -0xc(%rbp), %edx
callq 0x9d0b0
movb %al, -0x3ba(%rbp)
jmp 0xaa874
movb -0x3ba(%rbp), %al
testb $0x1, %al
jne 0xaa883
jmp 0xaa973
movq -0x3a8(%rbp), %rdi
movq -0x20(%rbp), %rax
movslq -0x3ac(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
movswl 0x8(%rax,%rcx), %esi
movl -0xc(%rbp), %edx
callq 0x98700
jmp 0xaa8ab
movq -0x3a8(%rbp), %rax
movq %rax, -0x3d0(%rbp)
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
movl 0x7bc(%rax,%rcx), %eax
movl %eax, -0x3c4(%rbp)
movl -0xc(%rbp), %edi
callq 0x25810
movl %eax, -0x3c0(%rbp)
jmp 0xaa8e8
movl -0x3c0(%rbp), %ecx
movl -0x3c4(%rbp), %edx
movq -0x3d0(%rbp), %rsi
xorl %edi, %edi
callq 0xaaae0
movb %al, -0x3d1(%rbp)
jmp 0xaa90a
movb -0x3d1(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xaa95c
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jl 0xaa95a
movq -0x18(%rbp), %rax
movq -0x20(%rbp), %rcx
movslq -0x3ac(%rbp), %rdx
imulq $0x7c8, %rdx, %rdx      # imm = 0x7C8
addq %rdx, %rcx
movswq 0x8(%rcx), %rcx
movb $0x1, (%rax,%rcx)
jmp 0xaa963
movb $0x1, -0x389(%rbp)
movq -0x3a8(%rbp), %rdi
callq 0x994b0
jmp 0xaa971
jmp 0xaa973
jmp 0xaa975
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x3ac(%rbp), %rcx
movswl 0x57c(%rax,%rcx,2), %eax
movl %eax, -0x3ac(%rbp)
jmp 0xaa7f9
testb $0x1, -0x389(%rbp)
jne 0xaaa8c
movq -0x8(%rbp), %rdi
movl -0x388(%rbp), %esi
movl -0xc(%rbp), %edx
callq 0x9d0b0
movb %al, -0x3d2(%rbp)
jmp 0xaa9cb
movb -0x3d2(%rbp), %al
testb $0x1, %al
jne 0xaa9da
jmp 0xaaa8a
movq -0x3a8(%rbp), %rdi
movl -0x388(%rbp), %esi
movl -0xc(%rbp), %edx
callq 0x98700
jmp 0xaa9f1
movq -0x20(%rbp), %rax
movslq -0x384(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x7c0(%rax)
jl 0xaaa7a
movq -0x3a8(%rbp), %rax
movq %rax, -0x3e8(%rbp)
movl -0x388(%rbp), %eax
movl %eax, -0x3dc(%rbp)
movl -0xc(%rbp), %edi
callq 0x25810
movl %eax, -0x3d8(%rbp)
jmp 0xaaa39
movl -0x3d8(%rbp), %ecx
movl -0x3dc(%rbp), %edx
movq -0x3e8(%rbp), %rsi
xorl %edi, %edi
callq 0xaaae0
movb %al, -0x3e9(%rbp)
jmp 0xaaa5b
movb -0x3e9(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xaaa7a
movq -0x18(%rbp), %rax
movslq -0x388(%rbp), %rcx
movb $0x1, (%rax,%rcx)
movq -0x3a8(%rbp), %rdi
callq 0x994b0
jmp 0xaaa88
jmp 0xaaa8a
jmp 0xaaa8c
movslq -0x388(%rbp), %rax
movb $0x1, -0x380(%rbp,%rax)
jmp 0xaaa9d
movl -0x384(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x384(%rbp)
jmp 0xaa69a
leaq -0x28(%rbp), %rdi
callq 0xaa2b0
addq $0x3f0, %rsp            # imm = 0x3F0
popq %rbp
retq
leaq -0x28(%rbp), %rdi
callq 0xaa2b0
movq -0x398(%rbp), %rdi
callq 0x79b0
nopl (%rax,%rax)