// File: 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
movq %rsp, %rbp
subq $0x80, %rsp
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq -0x10(%rbp), %rax
addq $0x43cc, %rax           # imm = 0x43CC
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
addq $0x95f0, %rax           # imm = 0x95F0
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movl 0x956f0(%rax,%rcx,4), %eax
movl %eax, -0x2c(%rbp)
cmpl $0x64, -0x8(%rbp)
jge 0xaab3c
movq -0x10(%rbp), %rax
cmpl $0x43a, 0x43b0(%rax)    # imm = 0x43A
jl 0xaab45
movb $0x1, -0x1(%rbp)
jmp 0xaae68
movq -0x20(%rbp), %rax
movslq -0x14(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0xaab5f
movb $0x0, -0x1(%rbp)
jmp 0xaae68
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jl 0xaab80
movb $0x1, -0x1(%rbp)
jmp 0xaae68
jmp 0xaab82
movq -0x20(%rbp), %rax
movslq -0x14(%rbp), %rcx
movsbl (%rax,%rcx), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %edi
callq 0x25810
movl %eax, -0x34(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x30(%rbp), %eax
jne 0xaad81
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x57c(%rax), %eax
movl %eax, -0x40(%rbp)
cmpl $0x11f, -0x40(%rbp)     # imm = 0x11F
je 0xaacb5
movq -0x28(%rbp), %rax
movslq -0x40(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xaac8f
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rax
movslq -0x40(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %esi
movl -0x30(%rbp), %edx
callq 0x98540
testb $0x1, %al
jne 0xaac15
jmp 0xaac8d
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rax
movslq -0x40(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %esi
movl -0x30(%rbp), %edx
callq 0x98700
movl -0x8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x48(%rbp)
movl -0x18(%rbp), %edi
callq 0x25810
movl -0x54(%rbp), %edi
movq -0x50(%rbp), %rsi
movl -0x48(%rbp), %edx
movl %eax, %ecx
callq 0xaaae0
andb $0x1, %al
movb %al, -0x41(%rbp)
movq -0x10(%rbp), %rdi
callq 0x994b0
movb -0x41(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xaac8b
movb $0x1, -0x1(%rbp)
jmp 0xaae68
jmp 0xaac8d
jmp 0xaac8f
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x40(%rbp), %rcx
movswl 0x57c(%rax,%rcx,2), %eax
movl %eax, -0x40(%rbp)
jmp 0xaabc4
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x38(%rbp)
cmpl $0x2b7, -0x38(%rbp)     # imm = 0x2B7
je 0xaad78
movq -0x10(%rbp), %rdi
movl -0x38(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x98540
testb $0x1, %al
jne 0xaacf0
jmp 0xaad55
movq -0x10(%rbp), %rdi
movl -0x38(%rbp), %esi
movl -0x30(%rbp), %edx
callq 0x98700
movl -0x8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x18(%rbp), %edi
callq 0x25810
movl -0x64(%rbp), %edi
movq -0x60(%rbp), %rsi
movl -0x58(%rbp), %edx
movl %eax, %ecx
callq 0xaaae0
andb $0x1, %al
movb %al, -0x41(%rbp)
movq -0x10(%rbp), %rdi
callq 0x994b0
movb -0x41(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xaad53
movb $0x1, -0x1(%rbp)
jmp 0xaae68
jmp 0xaad55
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x38(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x38(%rbp)
jmp 0xaacce
movb $0x0, -0x1(%rbp)
jmp 0xaae68
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xaada2
movb $0x0, -0x1(%rbp)
jmp 0xaae68
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movswl 0x8(%rax), %eax
movl %eax, -0x3c(%rbp)
cmpl $0x2b7, -0x3c(%rbp)     # imm = 0x2B7
je 0xaae62
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl -0x34(%rbp), %edx
callq 0x98540
testb $0x1, %al
jne 0xaaddd
jmp 0xaae3f
movq -0x10(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl -0x34(%rbp), %edx
callq 0x98700
movl -0x8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x18(%rbp), %edi
callq 0x25810
movl -0x74(%rbp), %edi
movq -0x70(%rbp), %rsi
movl -0x68(%rbp), %edx
movl %eax, %ecx
callq 0xaaae0
andb $0x1, %al
movb %al, -0x41(%rbp)
movq -0x10(%rbp), %rdi
callq 0x994b0
movb -0x41(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xaae3d
movb $0x0, -0x1(%rbp)
jmp 0xaae68
jmp 0xaae3f
movq -0x28(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
movslq -0x3c(%rbp), %rcx
movswl 0x8(%rax,%rcx,2), %eax
movl %eax, -0x3c(%rbp)
jmp 0xaadbb
jmp 0xaae64
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)