// File: /workspace/github_cpp_makefile_star2_O1/kobanium[P]Ray/src/learn/FactorizationMachines.cpp
// Function: CalculateMoveScore(game_info_t*, int, unsigned int const*, int)
static double
CalculateMoveScore( 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<btfm_t*> active_features;
  pattern_hash_t hash_pat;

  if (pos == PASS) {
    if (moves > 1 && pm1 == PASS) {
      active_features.push_back(&pass[UCT_PASS_AFTER_PASS]);
    } else {
      active_features.push_back(&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(&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(&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(&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(&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(&capture[features[UCT_CAPTURE_INDEX]]);
    if (features[UCT_SAVE_EXTENSION_INDEX] > 0) active_features.push_back(&save_extension[features[UCT_SAVE_EXTENSION_INDEX]]);
    if (features[UCT_ATARI_INDEX]          > 0) active_features.push_back(&atari[features[UCT_ATARI_INDEX]]);
    if (features[UCT_EXTENSION_INDEX]      > 0) active_features.push_back(&extension[features[UCT_EXTENSION_INDEX]]);
    if (features[UCT_DAME_INDEX]           > 0) active_features.push_back(&dame[features[UCT_DAME_INDEX]]);
    if (features[UCT_CONNECT_INDEX]        > 0) active_features.push_back(&connect[features[UCT_CONNECT_INDEX]]);
    if (features[UCT_THROW_IN_INDEX]       > 0) active_features.push_back(&throw_in[features[UCT_THROW_IN_INDEX]]);

    active_features.push_back(&pos_id[board_pos_id[pos]]);

    PatternHash(&game->pat[pos], &hash_pat);
    const int pat_3x3 = pat3_index[Pat3(game->pat, pos)];
    const int pat_md2 = md2_index[MD2(game->pat, pos)];
    const int md3_idx = SearchIndex(md3_index.data(), hash_pat.list[MD_3]);
    const int md4_idx = SearchIndex(md4_index.data(), hash_pat.list[MD_4]);
    const int md5_idx = SearchIndex(md5_index.data(), hash_pat.list[MD_5 + MD_MAX]);

    if (md5_idx != -1 && md5_target[md5_idx]) {
      active_features.push_back(&md5[md5_idx]);
    } else if (md4_idx != -1 && md4_target[md4_idx]) {
      active_features.push_back(&md4[md4_idx]);
    } else if (md3_idx != -1 && md3_target[md3_idx]) {
      active_features.push_back(&md3[md3_idx]);
    } else if (pat_md2 != 0 && md2_target[pat_md2]) {
      active_features.push_back(&md2[pat_md2]);
    } else {
      active_features.push_back(&pat3[pat_3x3]);
    }
  }

  if (moves > 1 && game->ko_move == game->moves - 1) {
    active_features.push_back(&ko_exist[0]);
  }

  const int feature_num = active_features.size();
  const double gamma = CalculateFirstTerm(active_features, feature_num);
  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 *= CalculateSecondTerm(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
movl %esi, %r12d
movq %rdi, %r13
movl 0x43b0(%rdi), %edx
xorl %r14d, %r14d
movl $0x0, %eax
cmpl $0x2, %edx
jl 0x39178
leal -0x1(%rdx), %eax
shlq $0x4, %rax
movl 0x4(%r13,%rax), %eax
cmpl $0x3, %edx
jl 0x39189
leal -0x2(%rdx), %ecx
shlq $0x4, %rcx
movl 0x4(%r13,%rcx), %r14d
xorl %ebx, %ebx
movl $0x0, %ebp
cmpl $0x4, %edx
jl 0x391a1
leal -0x3(%rdx), %ecx
shlq $0x4, %rcx
movl 0x4(%r13,%rcx), %ebp
cmpl $0x5, %edx
jl 0x391b2
leal -0x4(%rdx), %ecx
shlq $0x4, %rcx
movl 0x4(%r13,%rcx), %ebx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movq %r12, %rcx
testl %ecx, %ecx
je 0x39676
movq %rdx, 0x38(%rsp)
movq %r13, 0x30(%rsp)
movslq %ecx, %r13
testl %eax, %eax
movl %r8d, 0x40(%rsp)
je 0x39254
leaq 0x1aad3a95(%rip), %rcx  # 0x1ab0cc80
movl (%rcx,%r13,4), %edx
cltq
subl (%rcx,%rax,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
leaq 0x1aad47ae(%rip), %rdx  # 0x1ab0d9b0
movl (%rdx,%r13,4), %esi
subl (%rdx,%rax,4), %esi
movl %esi, %eax
negl %eax
cmovsl %esi, %eax
imulq $0x4c, %rcx, %rcx
addq 0x3bd55(%rip), %rcx     # 0x74f70
movl (%rcx,%rax,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dfb3(%rip), %rax     # 0x771f0
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x40(%rsp), %r8d
testl %r14d, %r14d
je 0x392ca
leaq 0x1aad3a20(%rip), %rax  # 0x1ab0cc80
movl (%rax,%r13,4), %ecx
movslq %r14d, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aad4738(%rip), %rcx  # 0x1ab0d9b0
movl (%rcx,%r13,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x3bcdf(%rip), %rax     # 0x74f70
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3df55(%rip), %rax     # 0x77208
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x40(%rsp), %r8d
testl %ebp, %ebp
je 0x3933f
leaq 0x1aad39ab(%rip), %rax  # 0x1ab0cc80
movl (%rax,%r13,4), %ecx
movslq %ebp, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aad46c3(%rip), %rcx  # 0x1ab0d9b0
movl (%rcx,%r13,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x3bc6a(%rip), %rax     # 0x74f70
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3def8(%rip), %rax     # 0x77220
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x40(%rsp), %r8d
testl %ebx, %ebx
je 0x393af
leaq 0x1aad3936(%rip), %rax  # 0x1ab0cc80
movl (%rax,%r13,4), %ecx
movslq %ebx, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aad464e(%rip), %rcx  # 0x1ab0d9b0
movl (%rcx,%r13,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x3bbf5(%rip), %rax     # 0x74f70
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
movl $0xf, %ecx
cmovll %eax, %ecx
addl %r8d, %ecx
movslq %ecx, %rax
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3de9b(%rip), %rax     # 0x77238
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
leal (,%r12,8), %eax
subl %r12d, %eax
movslq %eax, %rbx
movl (%r15,%rbx,4), %eax
testq %rax, %rax
je 0x393e6
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd74(%rip), %rax     # 0x77148
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x4(%r15,%rbx,4), %eax
testq %rax, %rax
je 0x39410
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd62(%rip), %rax     # 0x77160
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x8(%r15,%rbx,4), %eax
testq %rax, %rax
je 0x3943a
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd50(%rip), %rax     # 0x77178
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0xc(%r15,%rbx,4), %eax
testq %rax, %rax
je 0x39464
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd3e(%rip), %rax     # 0x77190
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x10(%r15,%rbx,4), %eax
testq %rax, %rax
je 0x3948e
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd2c(%rip), %rax     # 0x771a8
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x14(%r15,%rbx,4), %eax
testq %rax, %rax
je 0x394b8
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd1a(%rip), %rax     # 0x771c0
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movl 0x18(%r15,%rbx,4), %eax
testq %rax, %rax
je 0x394e2
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd08(%rip), %rax     # 0x771d8
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
leaq 0x1aad2a67(%rip), %rax  # 0x1ab0bf50
movslq (%rax,%r13,4), %rax
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dc35(%rip), %rax     # 0x77130
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
leaq (,%r13,2), %rax
addq %r13, %rax
movq 0x30(%rsp), %rbx
leaq (%rbx,%rax,8), %rdi
addq $0x4748, %rdi           # imm = 0x4748
leaq 0x48(%rsp), %rsi
callq 0x51654
leaq 0x4748(%rbx), %r15
movq %r15, %rdi
movl %r12d, %esi
callq 0x4f84b
movl %eax, %eax
movq 0x3daf3(%rip), %rcx     # 0x77040
movslq (%rcx,%rax,4), %rbx
movq %r15, %rdi
movl %r12d, %esi
callq 0x4f857
movl %eax, %eax
movq 0x3daf3(%rip), %rcx     # 0x77058
movslq (%rcx,%rax,4), %r13
movq 0x3db00(%rip), %rdi     # 0x77070
movq 0x50(%rsp), %rsi
callq 0x51931
movl %eax, %r14d
movq 0x3db04(%rip), %rdi     # 0x77088
movq 0x58(%rsp), %rsi
callq 0x51931
movl %eax, %r15d
movq 0x3db08(%rip), %rdi     # 0x770a0
movq 0x60(%rsp), %rsi
callq 0x51931
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
cmpl $-0x1, %eax
je 0x3960f
movslq %eax, %rdx
leaq 0x3f(%rdx), %rsi
testq %rdx, %rdx
cmovnsq %rdx, %rsi
sarq $0x6, %rsi
shlq $0x3, %rsi
addq 0x3dd8a(%rip), %rsi     # 0x77358
leaq 0x3f(%rcx), %rdi
andq %rdx, %rdi
xorl %r8d, %r8d
cmpq %rcx, %rdi
setbe %r8b
movq -0x8(%rsi,%r8,8), %rsi
btq %rax, %rsi
jae 0x3960f
imulq $0x218, %rdx, %rax      # imm = 0x218
addq 0x3db20(%rip), %rax     # 0x77118
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
jmp 0x3978a
cmpl $-0x1, %r15d
je 0x396ad
movslq %r15d, %rax
leaq 0x3f(%rax), %rdx
testq %rax, %rax
cmovnsq %rax, %rdx
sarq $0x6, %rdx
shlq $0x3, %rdx
addq 0x3dcfa(%rip), %rdx     # 0x77330
leaq 0x3f(%rcx), %rsi
andq %rax, %rsi
xorl %edi, %edi
cmpq %rcx, %rsi
setbe %dil
movq -0x8(%rdx,%rdi,8), %rdx
btq %r15, %rdx
jae 0x396ad
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3daa1(%rip), %rax     # 0x77100
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
jmp 0x3978a
movq %rdx, %rbx
cmpl $0x2, %edx
jl 0x3970d
testl %eax, %eax
jne 0x3970d
movl $0x218, %eax            # imm = 0x218
addq 0x3dbba(%rip), %rax     # 0x77250
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
jmp 0x39794
cmpl $-0x1, %r14d
je 0x39728
movslq %r14d, %rax
leaq 0x3f(%rax), %rdx
testq %rax, %rax
cmovnsq %rax, %rdx
sarq $0x6, %rdx
shlq $0x3, %rdx
addq 0x3dc38(%rip), %rdx     # 0x77308
leaq 0x3f(%rcx), %rsi
andq %rax, %rsi
xorl %edi, %edi
cmpq %rcx, %rsi
setbe %dil
movq -0x8(%rdx,%rdi,8), %rdx
btq %r14, %rdx
jae 0x39728
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3d9ef(%rip), %rax     # 0x770e8
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
jmp 0x3978a
movq 0x3db3c(%rip), %rax     # 0x77250
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
jmp 0x39794
testl %r13d, %r13d
je 0x398af
leaq 0x3f(%r13), %rax
testq %r13, %r13
cmovnsq %r13, %rax
sarq $0x6, %rax
shlq $0x3, %rax
addq 0x3db95(%rip), %rax     # 0x772e0
leaq 0x3f(%rcx), %rdx
andq %r13, %rdx
xorl %esi, %esi
cmpq %rcx, %rdx
setbe %sil
movq -0x8(%rax,%rsi,8), %rax
btq %r13, %rax
jae 0x398af
imulq $0x218, %r13, %rax      # imm = 0x218
addq 0x3d958(%rip), %rax     # 0x770d0
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movq 0x30(%rsp), %r13
movq 0x38(%rsp), %rbx
cmpl $0x2, %ebx
jl 0x397c4
movl 0x43b0(%r13), %eax
decl %eax
cmpl %eax, 0x43c8(%r13)
jne 0x397c4
movq 0x3dab6(%rip), %rax     # 0x77268
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rax
subq %rdi, %rax
shrq $0x3, %rax
movsd 0x2382b(%rip), %xmm3    # 0x5d008
movapd %xmm3, %xmm0
testl %eax, %eax
jle 0x39807
movl %eax, %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
movsd 0x23813(%rip), %xmm0    # 0x5d008
xorl %edx, %edx
movq (%rdi,%rdx,8), %rsi
mulsd (%rsi), %xmm0
incq %rdx
cmpq %rdx, %rcx
jne 0x397f7
cmpl $0x2, %eax
jge 0x39810
xorpd %xmm3, %xmm3
jl 0x39872
leal -0x1(%rax), %ecx
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl $0x1, %edx
xorl %esi, %esi
movsd 0x25657(%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 0x39841
mulsd %xmm4, %xmm1
mulsd %xmm1, %xmm3
incq %r9
cmpq %rax, %r9
jne 0x39833
incq %rdx
cmpq %rcx, %rsi
jne 0x39829
testq %rdi, %rdi
je 0x3989c
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
movsd %xmm3, 0x30(%rsp)
movsd %xmm0, 0x40(%rsp)
callq 0x6420
movsd 0x40(%rsp), %xmm0
movsd 0x30(%rsp), %xmm3
addsd %xmm3, %xmm0
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
imulq $0x218, %rbx, %rax      # imm = 0x218
addq 0x3d7fb(%rip), %rax     # 0x770b8
leaq 0x8(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x3a9ac
movq 0x30(%rsp), %r13
jmp 0x3978f
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
jmp 0x3990b
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x39925
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x6420
movq %rbx, %rdi
callq 0x6770
nop