// File: /workspace/github_cpp_makefile_star2_O2/kobanium[P]Ray/src/feature/Ladder.cpp
// Function: IsLadderCaptured(int, search_game_info_t*, int, int)
static bool
IsLadderCaptured( const int depth, search_game_info_t *game, const int ren_xy, const int turn_color )
{
  const char *board = game->board;
  const string_t *string = game->string;
  const int str = game->string_id[ren_xy];
  int escape_color, capture_color, escape_xy, capture_xy, neighbor;
  bool result;
  
  if (depth >= 100 || game->moves >= MAX_RECORDS - 1) {
    return ALIVE;
  }

  if (board[ren_xy] == S_EMPTY) {
    return DEAD;
  } else if (string[str].libs >= 3) {
    return ALIVE;
  }

  escape_color = board[ren_xy];
  capture_color = GetOppositeColor(escape_color);

  if (turn_color == escape_color) {
    // 周囲の敵連が取れるか確認し,
    // 取れるなら取って探索を続ける
    neighbor = string[str].neighbor[0];
    while (neighbor != NEIGHBOR_END) {
      if (string[neighbor].libs == 1) {
        if (IsLegalForSearch(game, string[neighbor].lib[0], escape_color)) {
          PutStoneForSearch(game, string[neighbor].lib[0], escape_color);
          result = IsLadderCaptured(depth + 1, game, ren_xy, GetOppositeColor(turn_color));
          Undo(game);
          if (result == ALIVE) {
            return ALIVE;
          }
        }
      }
      neighbor = string[str].neighbor[neighbor];
    }
    
    // 逃げる手を打ってみて探索を続ける
    escape_xy = string[str].lib[0];
    while (escape_xy != LIBERTY_END) {
      if (IsLegalForSearch(game, escape_xy, escape_color)) {
        PutStoneForSearch(game, escape_xy, escape_color);
        result = IsLadderCaptured(depth + 1, game, ren_xy, GetOppositeColor(turn_color));
        Undo(game);
        if (result == ALIVE) {
          return ALIVE;
        }
      }
      escape_xy = string[str].lib[escape_xy];
    }
    return DEAD;
  } else {
    if (string[str].libs == 1) {
      return DEAD;
    }
    // 追いかける側なのでアタリにする手を打ってみる
    capture_xy = string[str].lib[0];
    while (capture_xy != LIBERTY_END) {
      if (IsLegalForSearch(game, capture_xy, capture_color)) {
        PutStoneForSearch(game, capture_xy, capture_color);
        result = IsLadderCaptured(depth + 1, game, ren_xy, GetOppositeColor(turn_color));
        Undo(game);
        if (result == DEAD) {
          return DEAD;
        }
      }
      capture_xy = string[str].lib[capture_xy];
    }
  }

  return ALIVE;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movb $0x1, %r12b
movl %edi, 0xc(%rsp)
cmpl $0x63, %edi
jg 0x42fb8
movq %rsi, %r14
cmpl $0x439, 0x43b0(%rsi)    # imm = 0x439
jg 0x42fb8
movl %edx, %r15d
movslq %edx, %rax
movsbl 0x43cc(%r14,%rax), %edx
testl %edx, %edx
je 0x42fb5
movl %ecx, %ebx
leaq 0x95f0(%r14), %r13
movslq 0x956f0(%r14,%rax,4), %rax
imulq $0x7c8, %rax, %rcx      # imm = 0x7C8
movl 0x4(%r13,%rcx), %eax
cmpl $0x2, %eax
jg 0x42fb8
addq %r13, %rcx
cmpl %ebx, %edx
jne 0x42fb0
movl %r15d, 0x14(%rsp)
movq %rcx, 0x18(%rsp)
addq $0x57c, %rcx            # imm = 0x57C
incl 0xc(%rsp)
movl %ebx, %eax
xorl $0x3, %eax
movl %eax, 0x10(%rsp)
movq %rcx, 0x20(%rsp)
movq %rcx, %rax
movswq (%rax), %r15
cmpq $0x11f, %r15            # imm = 0x11F
je 0x42fca
imulq $0x7c8, %r15, %rbp      # imm = 0x7C8
cmpl $0x1, 0x4(%r13,%rbp)
jne 0x42fa5
addq %r13, %rbp
movswl 0x8(%rbp), %esi
movq %r14, %rdi
movl %ebx, %edx
callq 0x3940e
testb %al, %al
je 0x42fa5
movswl 0x8(%rbp), %esi
movq %r14, %rdi
movl %ebx, %edx
callq 0x394df
movl 0xc(%rsp), %edi
movq %r14, %rsi
movl 0x14(%rsp), %edx
movl 0x10(%rsp), %ecx
callq 0x42ea4
movl %eax, %ebp
movq %r14, %rdi
callq 0x39e87
testb %bpl, %bpl
jne 0x42fb8
movq 0x20(%rsp), %rax
leaq (%rax,%r15,2), %rax
jmp 0x42f43
cmpl $0x1, %eax
jne 0x43031
xorl %r12d, %r12d
movl %r12d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x18(%rsp), %rax
addq $0x8, %rax
movq %rax, %r15
movswl (%rax), %r13d
cmpl $0x2b7, %r13d           # imm = 0x2B7
setne %r12b
je 0x42fb8
movq %r14, %rdi
movl %r13d, %esi
movl %ebx, %edx
callq 0x3940e
testb %al, %al
je 0x43028
movq %r14, %rdi
movl %r13d, %esi
movl %ebx, %edx
callq 0x394df
movl 0xc(%rsp), %edi
movq %r14, %rsi
movl 0x14(%rsp), %edx
movl 0x10(%rsp), %ecx
callq 0x42ea4
movl %eax, %ebp
movq %r14, %rdi
callq 0x39e87
testb %bpl, %bpl
jne 0x42fb8
movslq %r13d, %rax
leaq (%r15,%rax,2), %rax
jmp 0x42fd6
movl %edx, %r13d
xorl $0x3, %r13d
addq $0x8, %rcx
incl 0xc(%rsp)
xorl $0x3, %ebx
movq %rcx, %rax
movq %rcx, 0x18(%rsp)
movl %r13d, 0x20(%rsp)
movswl (%rax), %ebp
cmpl $0x2b7, %ebp            # imm = 0x2B7
sete %r12b
je 0x42fb8
movq %r14, %rdi
movl %ebp, %esi
movl %r13d, %edx
callq 0x3940e
testb %al, %al
je 0x430ab
movq %r14, %rdi
movl %ebp, %esi
movl %r13d, %edx
callq 0x394df
movl 0xc(%rsp), %edi
movq %r14, %rsi
movl %r15d, %edx
movl %ebx, %ecx
callq 0x42ea4
movl %eax, %r13d
movq %r14, %rdi
callq 0x39e87
testb %r13b, %r13b
movl 0x20(%rsp), %r13d
je 0x42fb8
movslq %ebp, %rax
movq 0x18(%rsp), %rcx
leaq (%rcx,%rax,2), %rax
jmp 0x43050