// File: /workspace/github_cpp_makefile_star2_O3/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:
cmpl $0x63, %edi
jle 0x5cafb
movb $0x1, %al
retq
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r14
cmpl $0x439, 0x43b0(%rsi)    # imm = 0x439
jg 0x5cb51
movl %edx, %ebp
movslq %edx, %rax
movsbl 0x43cc(%r14,%rax), %r12d
testl %r12d, %r12d
je 0x5cc8b
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
jle 0x5cb58
movb $0x1, %al
jmp 0x5cc8d
movl %edi, %r15d
addq %r13, %rcx
cmpl %ebx, %r12d
movq %rcx, 0x8(%rsp)
jne 0x5cc86
movl %ebp, 0x4(%rsp)
movzwl 0x57c(%rcx), %eax
cmpl $0x11f, %eax            # imm = 0x11F
je 0x5cc0c
leal 0x1(%r15), %edx
movl %edx, (%rsp)
movl %ebx, %edx
xorl $0x3, %edx
movl %edx, 0x14(%rsp)
movswq %ax, %rbp
imulq $0x7c8, %rbp, %r12      # imm = 0x7C8
cmpl $0x1, 0x4(%r13,%r12)
jne 0x5cbfd
addq %r13, %r12
movswl 0x8(%r12), %esi
movq %r14, %rdi
movl %ebx, %edx
callq 0x51ea8
movq 0x8(%rsp), %rcx
testb %al, %al
je 0x5cbfd
movswl 0x8(%r12), %esi
movq %r14, %rdi
movl %ebx, %edx
callq 0x51f85
movl (%rsp), %edi
movq %r14, %rsi
movl 0x4(%rsp), %edx
movl 0x14(%rsp), %ecx
callq 0x5caf3
movl %eax, %r12d
movq %r14, %rdi
callq 0x52beb
movq 0x8(%rsp), %rcx
testb %r12b, %r12b
jne 0x5cb51
movzwl 0x57c(%rcx,%rbp,2), %eax
cmpl $0x11f, %eax            # imm = 0x11F
jne 0x5cb92
movzwl 0x8(%rcx), %ecx
cmpl $0x2b7, %ecx            # imm = 0x2B7
je 0x5cc8b
incl %r15d
movl %ebx, %eax
xorl $0x3, %eax
movl %eax, (%rsp)
movl 0x4(%rsp), %ebp
movswl %cx, %r13d
movq %r14, %rdi
movl %r13d, %esi
movl %ebx, %edx
callq 0x51ea8
testb %al, %al
je 0x5cc6d
movq %r14, %rdi
movl %r13d, %esi
movl %ebx, %edx
callq 0x51f85
movl %r15d, %edi
movq %r14, %rsi
movl %ebp, %edx
movl (%rsp), %ecx
callq 0x5caf3
movl %eax, %r12d
movq %r14, %rdi
callq 0x52beb
testb %r12b, %r12b
jne 0x5cb51
movslq %r13d, %rax
movq 0x8(%rsp), %rcx
movzwl 0x8(%rcx,%rax,2), %ecx
xorl %eax, %eax
cmpl $0x2b7, %ecx            # imm = 0x2B7
jne 0x5cc27
jmp 0x5cc8d
cmpl $0x1, %eax
jne 0x5cc9c
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzwl 0x8(%rcx), %eax
cmpl $0x2b7, %eax            # imm = 0x2B7
je 0x5cb51
xorl $0x3, %r12d
incl %r15d
xorl $0x3, %ebx
movswl %ax, %r13d
movq %r14, %rdi
movl %r13d, %esi
movl %r12d, %edx
callq 0x51ea8
testb %al, %al
je 0x5ccf9
movq %r14, %rdi
movl %r13d, %esi
movl %r12d, %edx
callq 0x51f85
movl %r15d, %edi
movq %r14, %rsi
movl %ebp, %edx
movl %ebx, %ecx
callq 0x5caf3
movb %al, (%rsp)
movq %r14, %rdi
callq 0x52beb
cmpb $0x0, (%rsp)
je 0x5cc8b
movslq %r13d, %rax
movq 0x8(%rsp), %rcx
movzwl 0x8(%rcx,%rax,2), %eax
cmpl $0x2b7, %eax            # imm = 0x2B7
jne 0x5ccb5
jmp 0x5cb51