// File: kobanium[P]Ray/src/feature/UctFeature.cpp
// Function: CheckFeaturesForTree(game_info_t const*, int, unsigned int*)
int
CheckFeaturesForTree( const game_info_t *game, const int color, unsigned int *tactical_features )
{
  const char *board = game->board;
  const string_t *string = game->string;
  const int *string_id = game->string_id;
  int status = 0;
  int checked = 0, previous_move = PASS, id;
  int neighbor4[4], check[4] = { 0 };
  bool ladder, already_checked;

  if (game->moves > 1) previous_move = game->record[game->moves - 1].pos;

  if (previous_move == PASS) return status;

  GetNeighbor4(neighbor4, previous_move);

  for (int i = 0; i < 4; i++) {
    if (board[neighbor4[i]] == color) {
      id = string_id[neighbor4[i]];
      already_checked = false;
      for (int j = 0; j < checked; j++) {
        if (check[j] == id) {
          already_checked = true;
          break;
        }
      }
      if (already_checked) continue;
      if (string[id].libs == 1) {
        ladder = CheckLadderExtension(game, color, neighbor4[i]);
        CheckFeaturesLib1ForTree(game, color, id, ladder, tactical_features);
        status = MOVE_DISTANCE_MAX * 3;
      } else if (string[id].libs == 2) {
        CheckFeaturesLib2ForTree(game, color, id, tactical_features);
        status = (status <= MOVE_DISTANCE_MAX * 1) ? MOVE_DISTANCE_MAX * 2 : status;
      } else if (string[id].libs == 3) {
        CheckFeaturesLib3ForTree(game, color, id, tactical_features);
        status = (status <= MOVE_DISTANCE_MAX * 0) ? MOVE_DISTANCE_MAX * 1 : status;
      }
      check[checked++] = id;
    }
  }

  return status;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
addq $0x43f8, %rax           # imm = 0x43F8
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
addq $0x9620, %rax           # imm = 0x9620
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
addq $0x95720, %rax          # imm = 0x95720
movq %rax, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
leaq -0x70(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x72b0
movq -0x10(%rbp), %rax
cmpl $0x1, 0x43b0(%rax)
jle 0xa5d83
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movl 0x43b0(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x44(%rbp)
jne 0xa5d94
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xa5f3b
leaq -0x60(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x9bc90
movl $0x0, -0x78(%rbp)
cmpl $0x4, -0x78(%rbp)
jge 0xa5f35
movq -0x28(%rbp), %rax
movslq -0x78(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movsbl (%rax,%rcx), %eax
cmpl -0x14(%rbp), %eax
jne 0xa5f25
movq -0x38(%rbp), %rax
movslq -0x78(%rbp), %rcx
movslq -0x60(%rbp,%rcx,4), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x48(%rbp)
movb $0x0, -0x72(%rbp)
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x40(%rbp), %eax
jge 0xa5e11
movslq -0x7c(%rbp), %rax
movl -0x70(%rbp,%rax,4), %eax
cmpl -0x48(%rbp), %eax
jne 0xa5e04
movb $0x1, -0x72(%rbp)
jmp 0xa5e11
jmp 0xa5e06
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0xa5de9
testb $0x1, -0x72(%rbp)
je 0xa5e1c
jmp 0xa5f27
movq -0x30(%rbp), %rax
movslq -0x48(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x1, 0x4(%rax)
jne 0xa5e74
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movslq -0x78(%rbp), %rax
movl -0x60(%rbp,%rax,4), %edx
callq 0xaae80
andb $0x1, %al
movb %al, -0x71(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x48(%rbp), %edx
movb -0x71(%rbp), %al
movq -0x20(%rbp), %r8
andb $0x1, %al
movzbl %al, %ecx
callq 0xa5f50
movl $0x30, -0x3c(%rbp)
jmp 0xa5f11
movq -0x30(%rbp), %rax
movslq -0x48(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x2, 0x4(%rax)
jne 0xa5ebd
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x48(%rbp), %edx
movq -0x20(%rbp), %rcx
callq 0xa62c0
cmpl $0x10, -0x3c(%rbp)
jg 0xa5eaf
movl $0x20, %eax
movl %eax, -0x80(%rbp)
jmp 0xa5eb5
movl -0x3c(%rbp), %eax
movl %eax, -0x80(%rbp)
movl -0x80(%rbp), %eax
movl %eax, -0x3c(%rbp)
jmp 0xa5f0f
movq -0x30(%rbp), %rax
movslq -0x48(%rbp), %rcx
imulq $0x7c8, %rcx, %rcx      # imm = 0x7C8
addq %rcx, %rax
cmpl $0x3, 0x4(%rax)
jne 0xa5f0d
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x48(%rbp), %edx
movq -0x20(%rbp), %rcx
callq 0xa6990
cmpl $0x0, -0x3c(%rbp)
jg 0xa5efb
movl $0x10, %eax
movl %eax, -0x84(%rbp)
jmp 0xa5f04
movl -0x3c(%rbp), %eax
movl %eax, -0x84(%rbp)
movl -0x84(%rbp), %eax
movl %eax, -0x3c(%rbp)
jmp 0xa5f0f
jmp 0xa5f11
movl -0x48(%rbp), %ecx
movl -0x40(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x40(%rbp)
cltq
movl %ecx, -0x70(%rbp,%rax,4)
jmp 0xa5f27
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0xa5da7
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw (%rax,%rax)