// File: /workspace/github_cpp_makefile_star2_O3/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 $0x58, %rsp
movq %rdx, %r15
movl %esi, %r14d
movq %rdi, %rbx
movl 0x43b0(%rdi), %r13d
cmpl $0x2, %r13d
jl 0x493b7
movl %ecx, %ebp
leal -0x1(%r13), %eax
shlq $0x4, %rax
movl $0x0, 0x18(%rsp)
cmpl $0x2, %r13d
jne 0x493d6
xorl %esi, %esi
xorl %r12d, %r12d
jmp 0x4940f
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
testl %r14d, %r14d
jne 0x4960e
jmp 0x4988d
leal -0x2(%r13), %ecx
shlq $0x4, %rcx
movl 0x4(%rbx,%rcx), %r12d
cmpl $0x4, %r13d
jb 0x4940d
leal -0x3(%r13), %ecx
shlq $0x4, %rcx
movl 0x4(%rbx,%rcx), %esi
cmpl $0x4, %r13d
je 0x4940f
leal -0x4(%r13), %ecx
shlq $0x4, %rcx
movl 0x4(%rbx,%rcx), %ecx
movl %ecx, 0x18(%rsp)
jmp 0x4940f
xorl %esi, %esi
movslq 0x4(%rbx,%rax), %rax
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movq $0x0, 0x30(%rsp)
testl %r14d, %r14d
je 0x49889
testl %eax, %eax
movl %esi, 0x10(%rsp)
je 0x494a7
movslq %r14d, %rcx
leaq 0x1aac4840(%rip), %rdx  # 0x1ab0dc80
movl (%rdx,%rcx,4), %esi
subl (%rdx,%rax,4), %esi
movl %esi, %edx
negl %edx
cmovsl %esi, %edx
leaq 0x1aac555c(%rip), %rsi  # 0x1ab0e9b0
movl (%rsi,%rcx,4), %ecx
subl (%rsi,%rax,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
imulq $0x4c, %rdx, %rcx
addq 0x2cb04(%rip), %rcx     # 0x75f70
movl (%rcx,%rax,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %ebp, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x80723a2(%rip), %rcx   # 0x80bb830
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0x10(%rsp), %esi
testl %r12d, %r12d
je 0x49520
movslq %r14d, %rax
leaq 0x1aac47ca(%rip), %rcx  # 0x1ab0dc80
movl (%rcx,%rax,4), %edx
movslq %r12d, %rsi
subl (%rcx,%rsi,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
leaq 0x1aac54e3(%rip), %rdx  # 0x1ab0e9b0
movl (%rdx,%rax,4), %eax
subl (%rdx,%rsi,4), %eax
movl %eax, %edx
negl %edx
cmovsl %eax, %edx
imulq $0x4c, %rcx, %rax
addq 0x2ca8b(%rip), %rax     # 0x75f70
movl (%rax,%rdx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %ebp, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8072f29(%rip), %rcx   # 0x80bc430
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0x10(%rsp), %esi
testl %esi, %esi
movl 0x18(%rsp), %r12d
je 0x49599
movslq %r14d, %rax
leaq 0x1aac474d(%rip), %rcx  # 0x1ab0dc80
movl (%rcx,%rax,4), %edx
movslq %esi, %rsi
subl (%rcx,%rsi,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
leaq 0x1aac5466(%rip), %rdx  # 0x1ab0e9b0
movl (%rdx,%rax,4), %eax
subl (%rdx,%rsi,4), %eax
movl %eax, %edx
negl %edx
cmovsl %eax, %edx
imulq $0x4c, %rcx, %rax
addq 0x2ca0e(%rip), %rax     # 0x75f70
movl (%rax,%rdx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %ebp, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8073aac(%rip), %rcx   # 0x80bd030
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
testl %r12d, %r12d
je 0x4960e
movslq %r14d, %rax
leaq 0x1aac46d8(%rip), %rcx  # 0x1ab0dc80
movl (%rcx,%rax,4), %edx
movslq %r12d, %rsi
subl (%rcx,%rsi,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
leaq 0x1aac53f1(%rip), %rdx  # 0x1ab0e9b0
movl (%rdx,%rax,4), %eax
subl (%rdx,%rsi,4), %eax
movl %eax, %edx
negl %edx
cmovsl %eax, %edx
imulq $0x4c, %rcx, %rax
addq 0x2c999(%rip), %rax     # 0x75f70
movl (%rax,%rdx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %ebp, %ecx
movslq %ecx, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8074637(%rip), %rcx   # 0x80bdc30
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
leal (,%r14,8), %eax
subl %r14d, %eax
movslq %eax, %r12
movl (%r15,%r12,4), %eax
testq %rax, %rax
je 0x49649
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x80751fc(%rip), %rcx   # 0x80be830
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0x4(%r15,%r12,4), %eax
testq %rax, %rax
je 0x49677
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x80756de(%rip), %rcx   # 0x80bed40
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0x8(%r15,%r12,4), %eax
testq %rax, %rax
je 0x496a5
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x80757a0(%rip), %rcx   # 0x80bee30
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0xc(%r15,%r12,4), %eax
testq %rax, %rax
je 0x496d3
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8075ad2(%rip), %rcx   # 0x80bf190
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0x10(%r15,%r12,4), %eax
testq %rax, %rax
je 0x49701
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8075bf4(%rip), %rcx   # 0x80bf2e0
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0x14(%r15,%r12,4), %eax
testq %rax, %rax
je 0x4972f
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8075cb6(%rip), %rcx   # 0x80bf3d0
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movl 0x18(%r15,%r12,4), %eax
testq %rax, %rax
je 0x4975d
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x8075ce8(%rip), %rcx   # 0x80bf430
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movslq %r14d, %rbp
leaq (,%rbp,2), %rax
addq %rbp, %rax
leaq (%rbx,%rax,8), %rdi
addq $0x4748, %rdi           # imm = 0x4748
leaq 0x38(%rsp), %rsi
callq 0x51a30
leaq 0x4748(%rbx), %r15
movq %r15, %rdi
movl %r14d, %esi
callq 0x4fc2a
movl %eax, %r12d
movq %rbx, 0x10(%rsp)
movq %r13, 0x18(%rsp)
movq %r15, %rdi
movl %r14d, %esi
callq 0x4fc36
movl %eax, %eax
leaq 0x8075cdd(%rip), %rcx   # 0x80bf490
movslq (%rcx,%rax,4), %rbx
movq 0x40(%rsp), %rsi
leaq 0xc075ccd(%rip), %rdi   # 0xc0bf490
callq 0x51d0d
movl %eax, %r14d
movl %r12d, %r13d
movq 0x48(%rsp), %rsi
leaq 0xd075cb6(%rip), %rdi   # 0xd0bf490
callq 0x51d0d
movl %eax, %r15d
movq 0x50(%rsp), %rsi
leaq 0xe075ca2(%rip), %rdi   # 0xe0bf490
callq 0x51d0d
movl %eax, %r12d
leaq 0x1aac3753(%rip), %rax  # 0x1ab0cf50
movslq (%rax,%rbp,4), %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0xf075c80(%rip), %rcx   # 0xf0bf490
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
cmpl $-0x1, %r12d
je 0x49857
movslq %r12d, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0xf076853(%rip), %rcx   # 0xf0c0090
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
jmp 0x49922
cmpl $-0x1, %r15d
je 0x498ab
movslq %r15d, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x11e3d421(%rip), %rcx  # 0x11e86c90
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
jmp 0x49922
testl %eax, %eax
je 0x498da
leaq 0x8071f3c(%rip), %rax   # 0x80bb7d0
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
jmp 0x4992c
cmpl $-0x1, %r14d
je 0x498f5
movslq %r14d, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x14c03fcd(%rip), %rcx  # 0x14c4d890
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
jmp 0x49922
leaq 0x8071f1f(%rip), %rax   # 0x80bb800
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
jmp 0x49932
cmpl $-0x1, %ebx
je 0x49a3d
leaq (%rbx,%rbx,2), %rax
shlq $0x4, %rax
leaq 0x179cab83(%rip), %rcx  # 0x17a14490
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movq 0x18(%rsp), %r13
movq 0x10(%rsp), %rbx
cmpl $0x2, %r13d
jl 0x4995b
movl 0x43b0(%rbx), %eax
decl %eax
cmpl %eax, 0x43c8(%rbx)
jne 0x4995b
leaq 0x1aa91747(%rip), %rax  # 0x1aadb090
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rcx
movq %rcx, %rax
subq %rdi, %rax
shrq $0x3, %rax
movsd 0x13691(%rip), %xmm0    # 0x5d008
cmpq %rdi, %rcx
je 0x4998f
movq %rdi, %rdx
movq (%rdx), %rsi
mulsd (%rsi), %xmm0
addq $0x8, %rdx
cmpq %rcx, %rdx
jne 0x4997f
xorpd %xmm4, %xmm4
cmpl $0x2, %eax
jl 0x49a00
leal -0x1(%rax), %ecx
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movsd 0x13660(%rip), %xmm4    # 0x5d008
movl $0x1, %edx
xorl %esi, %esi
movsd 0x154d1(%rip), %xmm3    # 0x5ee88
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 0x499cf
mulsd %xmm3, %xmm1
mulsd %xmm1, %xmm4
incq %r9
cmpq %rax, %r9
jne 0x499c1
incq %rdx
cmpq %rcx, %rsi
jne 0x499b7
testq %rdi, %rdi
je 0x49a2a
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
movsd %xmm0, 0x18(%rsp)
movsd %xmm4, 0x10(%rsp)
callq 0x6410
movsd 0x10(%rsp), %xmm4
movsd 0x18(%rsp), %xmm0
addsd %xmm4, %xmm0
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movslq %r13d, %rax
leaq (%rax,%rax,2), %rax
shlq $0x4, %rax
leaq 0x1a791641(%rip), %rcx  # 0x1a7db090
addq %rax, %rcx
leaq 0x8(%rsp), %rsi
movq %rcx, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x49ec2
movq 0x18(%rsp), %r13
movq 0x10(%rsp), %rbx
jmp 0x4992c
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
jmp 0x49aa5
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x49abf
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x6410
movq %rbx, %rdi
callq 0x6760