// File: /workspace/github_cpp_makefile_star2_O2/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, %r15d
movq %rdx, %r14
movl 0x43b0(%rdi), %ebx
movl $0x0, 0x44(%rsp)
cmpl $0x2, %ebx
movq %rdi, 0x8(%rsp)
jl 0x2534b
leal -0x1(%rbx), %eax
shlq $0x4, %rax
movl 0x4(%rdi,%rax), %eax
cmpl $0x2, %ebx
jne 0x257b3
xorl %r13d, %r13d
jmp 0x25350
xorl %r13d, %r13d
xorl %eax, %eax
xorl %ebp, %ebp
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rsp)
andq $0x0, 0x20(%rsp)
testl %esi, %esi
je 0x2577c
movq %rbx, 0x38(%rsp)
movl %esi, 0x30(%rsp)
movslq %esi, %r12
pushq $0xf
popq %rbx
testl %eax, %eax
je 0x253e0
leaq 0x1aad38fc(%rip), %rcx  # 0x1aaf8c80
movl (%rcx,%r12,4), %edx
cltq
subl (%rcx,%rax,4), %edx
movl %edx, %ecx
negl %ecx
cmovsl %edx, %ecx
leaq 0x1aad4615(%rip), %rdx  # 0x1aaf99b0
movl (%rdx,%r12,4), %esi
subl (%rdx,%rax,4), %esi
movl %esi, %eax
negl %eax
cmovsl %esi, %eax
imulq $0x4c, %rcx, %rcx
addq 0x3bbd4(%rip), %rcx     # 0x60f88
movl (%rcx,%rax,4), %eax
cmpl $0xf, %eax
cmovgel %ebx, %eax
addl %r15d, %eax
cltq
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3de20(%rip), %rax     # 0x631f0
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
testl %ebp, %ebp
je 0x25448
leaq 0x1aad3895(%rip), %rax  # 0x1aaf8c80
movl (%rax,%r12,4), %ecx
movslq %ebp, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aad45ad(%rip), %rcx  # 0x1aaf99b0
movl (%rcx,%r12,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x3bb6c(%rip), %rax     # 0x60f88
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
cmovgel %ebx, %eax
addl %r15d, %eax
cltq
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3ddd0(%rip), %rax     # 0x63208
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
testl %r13d, %r13d
je 0x254b1
leaq 0x1aad382c(%rip), %rax  # 0x1aaf8c80
movl (%rax,%r12,4), %ecx
movslq %r13d, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aad4544(%rip), %rcx  # 0x1aaf99b0
movl (%rcx,%r12,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x3bb03(%rip), %rax     # 0x60f88
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
cmovgel %ebx, %eax
addl %r15d, %eax
cltq
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd7f(%rip), %rax     # 0x63220
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movl 0x44(%rsp), %edx
testl %edx, %edx
movq 0x8(%rsp), %r13
je 0x25523
leaq 0x1aad37bb(%rip), %rax  # 0x1aaf8c80
movl (%rax,%r12,4), %ecx
movslq %edx, %rdx
subl (%rax,%rdx,4), %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
leaq 0x1aad44d3(%rip), %rcx  # 0x1aaf99b0
movl (%rcx,%r12,4), %esi
subl (%rcx,%rdx,4), %esi
movl %esi, %ecx
negl %ecx
cmovsl %esi, %ecx
imulq $0x4c, %rax, %rax
addq 0x3ba92(%rip), %rax     # 0x60f88
movl (%rax,%rcx,4), %eax
cmpl $0xf, %eax
cmovll %eax, %ebx
addl %r15d, %ebx
movslq %ebx, %rax
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dd25(%rip), %rax     # 0x63238
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
imull $0x7, 0x30(%rsp), %eax
movslq %eax, %rbx
movl (%r14,%rbx,4), %eax
testq %rax, %rax
je 0x25552
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dc06(%rip), %rax     # 0x63148
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movl 0x4(%r14,%rbx,4), %eax
testq %rax, %rax
je 0x2557a
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dbf6(%rip), %rax     # 0x63160
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movl 0x8(%r14,%rbx,4), %eax
testq %rax, %rax
je 0x255a2
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dbe6(%rip), %rax     # 0x63178
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movl 0xc(%r14,%rbx,4), %eax
testq %rax, %rax
je 0x255ca
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dbd6(%rip), %rax     # 0x63190
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movl 0x10(%r14,%rbx,4), %eax
testq %rax, %rax
je 0x255f2
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dbc6(%rip), %rax     # 0x631a8
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movl 0x14(%r14,%rbx,4), %eax
testq %rax, %rax
je 0x2561a
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dbb6(%rip), %rax     # 0x631c0
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movl 0x18(%r14,%rbx,4), %eax
testq %rax, %rax
je 0x25642
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dba6(%rip), %rax     # 0x631d8
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
leaq 0x1aad2907(%rip), %rax  # 0x1aaf7f50
movslq (%rax,%r12,4), %rax
imulq $0x218, %rax, %rax      # imm = 0x218
addq 0x3dad5(%rip), %rax     # 0x63130
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
imulq $0x18, %r12, %rax
leaq (%rax,%r13), %rdi
addq $0x4748, %rdi           # imm = 0x4748
leaq 0x48(%rsp), %rsi
callq 0x39038
leaq 0x4748(%r13), %r14
movq %r14, %rdi
movl 0x30(%rsp), %ebp
movl %ebp, %esi
callq 0x37bc6
movl %eax, %eax
movq 0x3d99e(%rip), %rcx     # 0x63040
movslq (%rcx,%rax,4), %rbx
movq %r14, %rdi
movl %ebp, %esi
callq 0x37bd2
movl %eax, %eax
movq 0x3d99f(%rip), %rcx     # 0x63058
movslq (%rcx,%rax,4), %r14
movq 0x3d9ac(%rip), %rdi     # 0x63070
movq 0x50(%rsp), %rsi
callq 0x3926f
movl %eax, %ebp
movq 0x3d9b1(%rip), %rdi     # 0x63088
movq 0x58(%rsp), %rsi
callq 0x3926f
movl %eax, %r15d
movq 0x3d9b5(%rip), %rdi     # 0x630a0
movq 0x60(%rsp), %rsi
callq 0x3926f
cmpl $-0x1, %eax
je 0x25734
movslq %eax, %r12
leaq 0x3dc54(%rip), %rdi     # 0x63358
movq %r12, %rsi
callq 0x26ccc
testq %rdx, (%rax)
je 0x25734
imulq $0x218, %r12, %rax      # imm = 0x218
addq 0x3d9f9(%rip), %rax     # 0x63118
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
jmp 0x258b1
cmpl $-0x1, %r15d
je 0x257f0
movslq %r15d, %r15
leaq 0x3dbe8(%rip), %rdi     # 0x63330
movq %r15, %rsi
callq 0x26ccc
testq %rdx, (%rax)
je 0x257f0
imulq $0x218, %r15, %rax      # imm = 0x218
addq 0x3d999(%rip), %rax     # 0x63100
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
jmp 0x258b1
cmpl $0x2, %ebx
jl 0x2582f
testl %eax, %eax
jne 0x2582f
movl $0x218, %eax            # imm = 0x218
addq 0x3dab7(%rip), %rax     # 0x63250
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movq 0x8(%rsp), %r13
jmp 0x258bb
leal -0x2(%rbx), %ecx
shlq $0x4, %rcx
movl 0x4(%rdi,%rcx), %ebp
cmpl $0x4, %ebx
jb 0x2588b
leal -0x3(%rbx), %ecx
shlq $0x4, %rcx
movl 0x4(%rdi,%rcx), %r13d
cmpl $0x4, %ebx
je 0x25352
leal -0x4(%rbx), %ecx
shlq $0x4, %rcx
movl 0x4(%rdi,%rcx), %ecx
movl %ecx, 0x44(%rsp)
jmp 0x25352
cmpl $-0x1, %ebp
je 0x2584d
movslq %ebp, %r15
leaq 0x3db09(%rip), %rdi     # 0x63308
movq %r15, %rsi
callq 0x26ccc
testq %rdx, (%rax)
je 0x2584d
imulq $0x218, %r15, %rax      # imm = 0x218
addq 0x3d8ce(%rip), %rax     # 0x630e8
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
jmp 0x258b1
movq 0x3da1a(%rip), %rax     # 0x63250
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movq 0x8(%rsp), %r13
jmp 0x258b6
testl %r14d, %r14d
je 0x25893
leaq 0x3da87(%rip), %rdi     # 0x632e0
movq %r14, %rsi
callq 0x26ccc
testq %rdx, (%rax)
je 0x25893
imulq $0x218, %r14, %rax      # imm = 0x218
addq 0x3d85c(%rip), %rax     # 0x630d0
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movq 0x38(%rsp), %rbx
jmp 0x258b6
xorl %r13d, %r13d
jmp 0x25352
imulq $0x218, %rbx, %rax      # imm = 0x218
addq 0x3d817(%rip), %rax     # 0x630b8
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
movq 0x38(%rsp), %rbx
cmpl $0x2, %ebx
jl 0x258e4
movl 0x43b0(%r13), %eax
decl %eax
cmpl %eax, 0x43c8(%r13)
jne 0x258e4
movq 0x3d994(%rip), %rax     # 0x63268
movq %rsp, %rsi
movq %rax, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x26cea
leaq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rbx
subq (%rdi), %rbx
shrq $0x3, %rbx
movl %ebx, %esi
callq 0x25058
movsd %xmm0, 0x30(%rsp)
cmpl $0x2, %ebx
jge 0x2590c
xorpd %xmm0, %xmm0
jmp 0x25914
movsd 0x1e6f4(%rip), %xmm0    # 0x44008
movsd %xmm0, 0x8(%rsp)
pushq $0x1
popq %r12
cmovgel %ebx, %r12d
decl %r12d
xorl %r15d, %r15d
leaq 0x10(%rsp), %r14
cmpl %r12d, %r15d
je 0x25963
leal 0x1(%r15), %r13d
movl %r13d, %ebp
cmpl %ebp, %ebx
je 0x2595e
movq %r14, %rdi
movl %r15d, %esi
movl %ebp, %edx
callq 0x2507d
movsd 0x8(%rsp), %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
incl %ebp
jmp 0x25939
movl %r13d, %r15d
jmp 0x2592d
movsd 0x30(%rsp), %xmm0
addsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x27770
movsd 0x30(%rsp), %xmm0
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
jmp 0x259ce
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x27770
movq %rbx, %rdi
callq 0x6740
nop