// File: /workspace/github_cpp_makefile_star2_O1/kobanium[P]Ray/src/mcts/UctRating.cpp
// Function: CalculateMoveScoreWithBTFM(game_info_t const*, int, unsigned int const*, int)
double
CalculateMoveScoreWithBTFM( const game_info_t *game, const int pos, const unsigned int *tactical_features, const int distance_index )
{
  const int moves = game->moves;
  const int pm1 = (moves > 1) ? game->record[moves - 1].pos : PASS;
  const int pm2 = (moves > 2) ? game->record[moves - 2].pos : PASS;
  const int pm3 = (moves > 3) ? game->record[moves - 3].pos : PASS;
  const int pm4 = (moves > 4) ? game->record[moves - 4].pos : PASS;
  int dis = 0;
  std::vector<fm_t*> active_features;
  pattern_hash_t hash_pat;

  if (pos == PASS) {
    if (moves > 1 && pm1 == PASS) {
      active_features.push_back(&uct_pass[UCT_PASS_AFTER_PASS]);
    } else {
      active_features.push_back(&uct_pass[UCT_PASS_AFTER_MOVE]);
    }
  } else {
    if (pm1 != PASS) {
      dis = DIS(pos, pm1);
      if (dis >= MOVE_DISTANCE_MAX - 1) {
        dis = MOVE_DISTANCE_MAX - 1;
      }
      active_features.push_back(&uct_move_distance_1[dis + distance_index]);
    }

    if (pm2 != PASS) {
      dis = DIS(pos, pm2);
      if (dis >= MOVE_DISTANCE_MAX - 1) {
        dis = MOVE_DISTANCE_MAX - 1;
      }
      active_features.push_back(&uct_move_distance_2[dis + distance_index]);
    }

    if (pm3 != PASS) {
      dis = DIS(pos, pm3);
      if (dis >= MOVE_DISTANCE_MAX - 1) {
        dis = MOVE_DISTANCE_MAX - 1;
      }
      active_features.push_back(&uct_move_distance_3[dis + distance_index]);
    }

    if (pm4 != PASS) {
      dis = DIS(pos, pm4);
      if (dis >= MOVE_DISTANCE_MAX - 1) {
        dis = MOVE_DISTANCE_MAX - 1;
      }
      active_features.push_back(&uct_move_distance_4[dis + distance_index]);
    }

    const unsigned int *features = &tactical_features[pos * UCT_INDEX_MAX];

    if (features[UCT_CAPTURE_INDEX]        > 0) active_features.push_back(&uct_capture[features[UCT_CAPTURE_INDEX]]);
    if (features[UCT_SAVE_EXTENSION_INDEX] > 0) active_features.push_back(&uct_save_extension[features[UCT_SAVE_EXTENSION_INDEX]]);
    if (features[UCT_ATARI_INDEX]          > 0) active_features.push_back(&uct_atari[features[UCT_ATARI_INDEX]]);
    if (features[UCT_EXTENSION_INDEX]      > 0) active_features.push_back(&uct_extension[features[UCT_EXTENSION_INDEX]]);
    if (features[UCT_DAME_INDEX]           > 0) active_features.push_back(&uct_dame[features[UCT_DAME_INDEX]]);
    if (features[UCT_CONNECT_INDEX]        > 0) active_features.push_back(&uct_connect[features[UCT_CONNECT_INDEX]]);
    if (features[UCT_THROW_IN_INDEX]       > 0) active_features.push_back(&uct_throw_in[features[UCT_THROW_IN_INDEX]]);

    PatternHash(&game->pat[pos], &hash_pat);
    const int pat3_idx = Pat3(game->pat, pos);
    const int md2_idx = md2_index[MD2(game->pat, pos)];
    const int md3_idx = SearchIndex(md3_index, hash_pat.list[MD_3]);
    const int md4_idx = SearchIndex(md4_index, hash_pat.list[MD_4]);
    const int md5_idx = SearchIndex(md5_index, hash_pat.list[MD_5 + MD_MAX]);

    // 盤上の位置
    active_features.push_back(&uct_pos_id[board_pos_id[pos]]);

    // パターン
    if (md5_idx != -1) {
      active_features.push_back(&uct_md5[md5_idx]);
    } else if (md4_idx != -1) {
      active_features.push_back(&uct_md4[md4_idx]);
    } else if (md3_idx != -1) {
      active_features.push_back(&uct_md3[md3_idx]);
    } else if (md2_idx != -1) {
      active_features.push_back(&uct_md2[md2_idx]);
    } else {
      active_features.push_back(&uct_pat3[pat3_idx]);
    }
  }

  if (moves > 1 && game->ko_move == game->moves - 1) {
    active_features.push_back(&uct_ko_exist);
  }

  const int feature_num = active_features.size();
  const double gamma = Gamma(active_features);
  double theta = feature_num > 1 ? 1.0 : 0.0;

  for (int i = 0; i < feature_num - 1; i++) {
    for (int j = i + 1; j < feature_num; j++) {
      theta *= Theta(active_features, i, j);
    }
  }

  return gamma + theta;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %ecx, %r8d
movq %rdx, %r15
movq %rdi, %rbx
movl 0x43b0(%rdi), %r13d
xorl %r14d, %r14d
movl $0x0, %eax
cmpl $0x2, %r13d
jl 0x49168
leal -0x1(%r13), %eax
shlq $0x4, %rax
movl 0x4(%rbx,%rax), %eax
movq %rsi, 0x38(%rsp)
cmpl $0x3, %r13d
jl 0x49180
leal -0x2(%r13), %ecx
shlq $0x4, %rcx
movl 0x4(%rbx,%rcx), %r14d
xorl %r12d, %r12d
movl $0x0, %ebp
cmpl $0x4, %r13d
jl 0x4919a
leal -0x3(%r13), %ecx
shlq $0x4, %rcx
movl 0x4(%rbx,%rcx), %ebp
cmpl $0x5, %r13d
jl 0x491ad
leal -0x4(%r13), %ecx
shlq $0x4, %rcx
movl 0x4(%rbx,%rcx), %r12d
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movq 0x38(%rsp), %rcx
testl %ecx, %ecx
je 0x495f5
movq %rbx, 0x40(%rsp)
movslq %ecx, %rbx
testl %eax, %eax
movl %r8d, 0x34(%rsp)
je 0x4924e
leaq 0x1aac3a9d(%rip), %rcx  # 0x1ab0cc80
movl (%rcx,%rbx,4), %edx
cltq
subl (%rcx,%rax,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
leaq 0x1aac47b7(%rip), %rdx  # 0x1ab0d9b0
movl (%rdx,%rbx,4), %esi
subl (%rdx,%rax,4), %esi
movl %esi, %eax
negl %eax
cmovsl %esi, %eax
imulq $0x4c, %rcx, %rcx
addq 0x2bd5f(%rip), %rcx     # 0x74f70
movl (%rcx,%rax,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x80715fc(%rip), %rcx   # 0x80ba830
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x34(%rsp), %r8d
testl %r14d, %r14d
je 0x492c6
leaq 0x1aac3a26(%rip), %rax  # 0x1ab0cc80
movl (%rax,%rbx,4), %ecx
movslq %r14d, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aac473f(%rip), %rcx  # 0x1ab0d9b0
movl (%rcx,%rbx,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x2bce7(%rip), %rax     # 0x74f70
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8072184(%rip), %rcx   # 0x80bb430
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x34(%rsp), %r8d
testl %ebp, %ebp
je 0x4933d
leaq 0x1aac39af(%rip), %rax  # 0x1ab0cc80
movl (%rax,%rbx,4), %ecx
movslq %ebp, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aac46c8(%rip), %rcx  # 0x1ab0d9b0
movl (%rcx,%rbx,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x2bc70(%rip), %rax     # 0x74f70
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8072d0d(%rip), %rcx   # 0x80bc030
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x34(%rsp), %r8d
testl %r12d, %r12d
movq 0x38(%rsp), %rbp
je 0x493b5
leaq 0x1aac3932(%rip), %rax  # 0x1ab0cc80
movl (%rax,%rbx,4), %ecx
movslq %r12d, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aac464b(%rip), %rcx  # 0x1ab0d9b0
movl (%rcx,%rbx,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x2bbf3(%rip), %rax     # 0x74f70
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8073890(%rip), %rcx   # 0x80bcc30
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
leal (,%rbp,8), %eax
subl %ebp, %eax
movslq %eax, %r12
movl (%r15,%r12,4), %eax
testq %rax, %rax
je 0x493ee
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8074457(%rip), %rcx   # 0x80bd830
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x4(%r15,%r12,4), %eax
testq %rax, %rax
je 0x4941c
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8074939(%rip), %rcx   # 0x80bdd40
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x8(%r15,%r12,4), %eax
testq %rax, %rax
je 0x4944a
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x80749fb(%rip), %rcx   # 0x80bde30
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0xc(%r15,%r12,4), %eax
testq %rax, %rax
je 0x49478
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8074d2d(%rip), %rcx   # 0x80be190
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x10(%r15,%r12,4), %eax
testq %rax, %rax
je 0x494a6
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8074e4f(%rip), %rcx   # 0x80be2e0
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x14(%r15,%r12,4), %eax
testq %rax, %rax
je 0x494d4
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8074f11(%rip), %rcx   # 0x80be3d0
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movl 0x18(%r15,%r12,4), %eax
testq %rax, %rax
je 0x49502
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8074f43(%rip), %rcx   # 0x80be430
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
leaq (%rbx,%rbx,2), %rax
movq 0x40(%rsp), %r14
leaq (%r14,%rax,8), %rdi
addq $0x4748, %rdi           # imm = 0x4748
leaq 0x48(%rsp), %rsi
callq 0x51654
leaq 0x4748(%r14), %r15
movq %r15, %rdi
movl %ebp, %esi
callq 0x4f84b
movl %eax, %r12d
movq %r15, %rdi
movl %ebp, %esi
callq 0x4f857
movl %eax, %eax
leaq 0x8074f49(%rip), %rcx   # 0x80be490
movslq (%rcx,%rax,4), %rax
movq %rax, 0x38(%rsp)
movq 0x50(%rsp), %rsi
leaq 0xc074f34(%rip), %rdi   # 0xc0be490
callq 0x51931
movl %eax, %r14d
movl %r12d, %ebp
movq 0x58(%rsp), %rsi
leaq 0xd074f1d(%rip), %rdi   # 0xd0be490
callq 0x51931
movl %eax, %r15d
movq 0x60(%rsp), %rsi
leaq 0xe074f09(%rip), %rdi   # 0xe0be490
callq 0x51931
movl %eax, %r12d
leaq 0x1aac29ba(%rip), %rax  # 0x1ab0bf50
movslq (%rax,%rbx,4), %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0xf074ee7(%rip), %rcx   # 0xf0be490
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
cmpl $-0x1, %r12d
movq 0x40(%rsp), %rbx
je 0x4961d
movslq %r12d, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0xf075ab5(%rip), %rcx   # 0xf0bf090
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
jmp 0x496f3
cmpl $0x2, %r13d
jl 0x4964f
testl %eax, %eax
jne 0x4964f
leaq 0x80711fa(%rip), %rax   # 0x80ba800
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
jmp 0x496f3
cmpl $-0x1, %r15d
je 0x4966d
movslq %r15d, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x11e3c65b(%rip), %rcx  # 0x11e85c90
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
jmp 0x496f3
leaq 0x807117a(%rip), %rax   # 0x80ba7d0
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
jmp 0x496f3
cmpl $-0x1, %r14d
je 0x4969c
movslq %r14d, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x14c0320b(%rip), %rcx  # 0x14c4c890
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
jmp 0x496f3
movq 0x38(%rsp), %rax
cmpl $-0x1, %eax
je 0x496cc
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x179c9ddb(%rip), %rcx  # 0x17a13490
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
jmp 0x496f3
movslq %ebp, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x1a7909b2(%rip), %rcx  # 0x1a7da090
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
cmpl $0x2, %r13d
jl 0x49722
movl 0x43b0(%rbx), %eax
decl %eax
cmpl %eax, 0x43c8(%rbx)
jne 0x49722
leaq 0x1aa90980(%rip), %rax  # 0x1aada090
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x49c54
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rcx
movq %rcx, %rax
subq %rdi, %rax
shrq $0x3, %rax
movsd 0x138ca(%rip), %xmm3    # 0x5d008
movapd %xmm3, %xmm0
cmpq %rdi, %rcx
je 0x49762
movsd 0x138b9(%rip), %xmm0    # 0x5d008
movq %rdi, %rdx
movq (%rdx), %rsi
mulsd (%rsi), %xmm0
addq $0x8, %rdx
cmpq %rcx, %rdx
jne 0x49752
cmpl $0x2, %eax
jge 0x4976b
xorpd %xmm3, %xmm3
jl 0x497cd
leal -0x1(%rax), %ecx
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl $0x1, %edx
xorl %esi, %esi
movsd 0x156fc(%rip), %xmm4    # 0x5ee80
movq (%rdi,%rsi,8), %r8
incq %rsi
movq %rdx, %r9
movq (%rdi,%r9,8), %r10
xorpd %xmm1, %xmm1
movl $0x1, %r11d
movsd (%r8,%r11,8), %xmm2
mulsd (%r10,%r11,8), %xmm2
addsd %xmm2, %xmm1
incq %r11
cmpq $0x6, %r11
jne 0x4979c
mulsd %xmm4, %xmm1
mulsd %xmm1, %xmm3
incq %r9
cmpq %rax, %r9
jne 0x4978e
incq %rdx
cmpq %rcx, %rsi
jne 0x49784
testq %rdi, %rdi
je 0x497f7
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
movsd %xmm3, 0x38(%rsp)
movsd %xmm0, 0x40(%rsp)
callq 0x6420
movsd 0x40(%rsp), %xmm0
movsd 0x38(%rsp), %xmm3
addsd %xmm3, %xmm0
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
jmp 0x4983c
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x49856
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x6420
movq %rbx, %rdi
callq 0x6770