// File: kobanium[P]Ray/src/learn/MinorizationMaximization.cpp
// Function: CheckAccuracy(game_info_t*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
static void
CheckAccuracy( game_info_t *game, const std::string filename )
{
  pattern_t *pat = game->pat;
  unsigned char *tactical_features = game->tactical_features;
  SGF_record_t kifu;
  std::array<std::pair<double, int>, PURE_BOARD_MAX> score_list;
  int color = S_BLACK;
  int update_pos[PURE_BOARD_MAX], update_num = 0;
  int previous_move = PASS;

  ExtractKifu(filename.c_str(), &kifu);

  for (int i = 0; i < kifu.moves; i++) {
    const int expert_move = GetKifuMove(&kifu, i);

    if (expert_move == PASS) {
      PutStone(game, expert_move, color);
      color = GetOppositeColor(color);
      previous_move = expert_move;
      continue;
    }

    for (std::pair<double, int> &score : score_list) {
      score.first = 0.0;
      score.second = 0;
    }

    for (int j = 0; j < pure_board_max; j++) {
      const int pos = onboard_pos[j];
      ClearTacticalFeatures(&tactical_features[pos * ALL_MAX]);
    }

    update_num = 0;

    CheckFeaturesForSimulation(game, color, update_pos, update_num);
    CheckRemove2StonesForSimulation(game, color, update_pos, update_num);
    if (game->ko_move == game->moves - 2) {
      CheckCaptureAfterKoForSimulation(game, color, update_pos, update_num);
    }

    for (int j = 0; j < pure_board_max; j++) {
      const int pos = onboard_pos[j];
      double gamma = 0.0;
      if (IsLegalNotEye(game, pos, color)) {
        CheckCaptureAndAtariForSimulation(game, color, pos);
        CheckSelfAtariForSimulation(game, color, pos);

        gamma  = GetTacticalFeatureGamma(capture[0], tactical_features, pos, CAPTURE);
        gamma *= GetTacticalFeatureGamma(save_extension[0], tactical_features, pos, SAVE_EXTENSION);
        gamma *= GetTacticalFeatureGamma(atari[0], tactical_features, pos, ATARI);
        gamma *= GetTacticalFeatureGamma(extension[0], tactical_features, pos, EXTENSION);
        gamma *= GetTacticalFeatureGamma(dame[0], tactical_features, pos, DAME);
        gamma *= GetTacticalFeatureGamma(throw_in[0], tactical_features, pos, THROW_IN);

        if (game->moves > 1 && previous_move != PASS) {
          const int dis = DIS(previous_move, pos);
          if (dis == 2) {
            gamma *= previous_distance[0][0].gamma;
          } else if (dis == 3) {
            gamma *= previous_distance[0][1].gamma;
          } else if (dis == 4) {
            gamma *= previous_distance[0][2].gamma;
          }
        }

        const int pat_md2 = md2_index[MD2(pat, pos)];
        const int pat_3x3 = pat3_index[Pat3(pat, pos)];
        if (md2_target[pat_md2]) {
          gamma *= md2[0][pat_md2].gamma;
        } else {
          gamma *= pat3[0][pat_3x3].gamma;
        }
      }
      score_list[j].first = gamma;
      score_list[j].second = pos;
    }

    std::sort(score_list.begin(), score_list.end(), std::greater<std::pair<double, int> >());

    int skip = 0;
    
    for (int j = 0; j < pure_board_max; j++) {
      if (j != 0 &&
          score_list[j].first == score_list[j - 1].first) {
        skip++;
      } else {
        skip = 0;
      }
      if (score_list[j].second == expert_move) {
        counter[j - skip]++;
        break;
      }
    }
    
    PutStone(game, expert_move, color);
    color = GetOppositeColor(color);
    previous_move = expert_move;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x5da0, %rsp           # imm = 0x5DA0
movq %rsi, -0x5d80(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
addq $0x4748, %rax           # imm = 0x4748
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
addq $0x97372, %rax          # imm = 0x97372
movq %rax, -0x20(%rbp)
leaq -0x5750(%rbp), %rdi
callq 0x79530
movq -0x5d80(%rbp), %rdi
movl $0x1, -0x5754(%rbp)
movl $0x0, -0x5d04(%rbp)
movl $0x0, -0x5d08(%rbp)
callq 0x71d0
movq %rax, %rdi
leaq -0x40c0(%rbp), %rsi
callq 0x818f0
movl $0x0, -0x5d0c(%rbp)
movl -0x5d0c(%rbp), %eax
cmpl -0x40bc(%rbp), %eax
jge 0x7769f
movl -0x5d0c(%rbp), %esi
leaq -0x40c0(%rbp), %rdi
callq 0x81830
movl %eax, -0x5d10(%rbp)
cmpl $0x0, -0x5d10(%rbp)
jne 0x76f7f
movq -0x8(%rbp), %rdi
movl -0x5d10(%rbp), %esi
movl -0x5754(%rbp), %edx
callq 0x9dbc0
movl -0x5754(%rbp), %edi
callq 0x25810
movl %eax, -0x5754(%rbp)
movl -0x5d10(%rbp), %eax
movl %eax, -0x5d08(%rbp)
jmp 0x7768b
leaq -0x5750(%rbp), %rax
movq %rax, -0x5d18(%rbp)
movq -0x5d18(%rbp), %rdi
callq 0x79580
movq %rax, -0x5d20(%rbp)
movq -0x5d18(%rbp), %rdi
callq 0x795a0
movq %rax, -0x5d28(%rbp)
movq -0x5d20(%rbp), %rax
cmpq -0x5d28(%rbp), %rax
je 0x77001
movq -0x5d20(%rbp), %rax
movq %rax, -0x5d30(%rbp)
movq -0x5d30(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movq -0x5d30(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x5d20(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x5d20(%rbp)
jmp 0x76fb3
movl $0x0, -0x5d34(%rbp)
movl -0x5d34(%rbp), %eax
leaq 0x70a28(%rip), %rcx     # 0xe7a40
cmpl (%rcx), %eax
jge 0x77059
movslq -0x5d34(%rbp), %rcx
leaq 0x1ab5b846(%rip), %rax  # 0x1abd2870
movl (%rax,%rcx,4), %eax
movl %eax, -0x5d38(%rbp)
movq -0x20(%rbp), %rdi
imull $0x6, -0x5d38(%rbp), %eax
cltq
addq %rax, %rdi
callq 0x79350
movl -0x5d34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5d34(%rbp)
jmp 0x7700b
movl $0x0, -0x5d04(%rbp)
movq -0x8(%rbp), %rdi
movl -0x5754(%rbp), %esi
leaq -0x5d00(%rbp), %rdx
leaq -0x5d04(%rbp), %rcx
callq 0xa0820
movq -0x8(%rbp), %rdi
movl -0x5754(%rbp), %esi
leaq -0x5d00(%rbp), %rdx
leaq -0x5d04(%rbp), %rcx
callq 0xa3400
movq -0x8(%rbp), %rax
movl 0x43c8(%rax), %eax
movq -0x8(%rbp), %rcx
movl 0x43b0(%rcx), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
jne 0x770d5
movq -0x8(%rbp), %rdi
movl -0x5754(%rbp), %esi
leaq -0x5d00(%rbp), %rdx
leaq -0x5d04(%rbp), %rcx
callq 0xa24d0
movl $0x0, -0x5d3c(%rbp)
movl -0x5d3c(%rbp), %eax
leaq 0x70954(%rip), %rcx     # 0xe7a40
cmpl (%rcx), %eax
jge 0x7753c
movslq -0x5d3c(%rbp), %rcx
leaq 0x1ab5b76e(%rip), %rax  # 0x1abd2870
movl (%rax,%rcx,4), %eax
movl %eax, -0x5d40(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x5d48(%rbp)
movq -0x8(%rbp), %rdi
movl -0x5d40(%rbp), %esi
movl -0x5754(%rbp), %edx
callq 0x9d460
testb $0x1, %al
jne 0x77134
jmp 0x774d1
movq -0x8(%rbp), %rdi
movl -0x5754(%rbp), %esi
movl -0x5d40(%rbp), %edx
callq 0xa3180
movq -0x8(%rbp), %rdi
movl -0x5754(%rbp), %esi
movl -0x5d40(%rbp), %edx
callq 0xa2830
leaq 0x731c3(%rip), %rdi     # 0xea328
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
movl -0x5d40(%rbp), %edx
xorl %ecx, %ecx
callq 0x767e0
movsd %xmm0, -0x5d48(%rbp)
leaq 0x731af(%rip), %rdi     # 0xea340
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
movl -0x5d40(%rbp), %edx
movl $0x1, %ecx
callq 0x767e0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
leaq 0x73190(%rip), %rdi     # 0xea358
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
movl -0x5d40(%rbp), %edx
movl $0x2, %ecx
callq 0x767e0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
leaq 0x73171(%rip), %rdi     # 0xea370
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
movl -0x5d40(%rbp), %edx
movl $0x3, %ecx
callq 0x767e0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
leaq 0x73152(%rip), %rdi     # 0xea388
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
movl -0x5d40(%rbp), %edx
movl $0x4, %ecx
callq 0x767e0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
leaq 0x73133(%rip), %rdi     # 0xea3a0
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
movl -0x5d40(%rbp), %edx
movl $0x5, %ecx
callq 0x767e0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x1, 0x43b0(%rax)
jle 0x773e4
cmpl $0x0, -0x5d08(%rbp)
je 0x773e4
movslq -0x5d08(%rbp), %rcx
leaq 0x1ab07b37(%rip), %rax  # 0x1ab7ee00
movl (%rax,%rcx,4), %eax
movslq -0x5d40(%rbp), %rdx
leaq 0x1ab07b26(%rip), %rcx  # 0x1ab7ee00
subl (%rcx,%rdx,4), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movslq %eax, %rcx
leaq 0x1ab5afd2(%rip), %rax  # 0x1abd22c0
imulq $0x4c, %rcx, %rcx
addq %rcx, %rax
movslq -0x5d08(%rbp), %rdx
leaq 0x1ab0882d(%rip), %rcx  # 0x1ab7fb30
movl (%rcx,%rdx,4), %ecx
movslq -0x5d40(%rbp), %rsi
leaq 0x1ab0881c(%rip), %rdx  # 0x1ab7fb30
subl (%rdx,%rsi,4), %ecx
movl %ecx, %edx
negl %edx
cmovnsl %edx, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x5d4c(%rbp)
cmpl $0x2, -0x5d4c(%rbp)
jne 0x77366
leaq 0x72fa6(%rip), %rdi     # 0xea2e0
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x792e0
movsd 0x18(%rax), %xmm0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
jmp 0x773e2
cmpl $0x3, -0x5d4c(%rbp)
jne 0x773a3
leaq 0x72f6a(%rip), %rdi     # 0xea2e0
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movl $0x1, %esi
callq 0x792e0
movsd 0x18(%rax), %xmm0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
jmp 0x773e0
cmpl $0x4, -0x5d4c(%rbp)
jne 0x773de
leaq 0x72f2d(%rip), %rdi     # 0xea2e0
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movl $0x2, %esi
callq 0x792e0
movsd 0x18(%rax), %xmm0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
jmp 0x773e0
jmp 0x773e2
jmp 0x773e4
movq -0x18(%rbp), %rdi
movl -0x5d40(%rbp), %esi
callq 0x93d60
movl %eax, %eax
movl %eax, %esi
leaq 0x72eca(%rip), %rdi     # 0xea2c8
callq 0x63590
movl (%rax), %eax
movl %eax, -0x5d50(%rbp)
movq -0x18(%rbp), %rdi
movl -0x5d40(%rbp), %esi
callq 0x93d30
movl %eax, %eax
movl %eax, %esi
leaq 0x72e8b(%rip), %rdi     # 0xea2b0
callq 0x63590
movl (%rax), %eax
movl %eax, -0x5d54(%rbp)
movslq -0x5d50(%rbp), %rsi
leaq 0x72f90(%rip), %rdi     # 0xea3d0
callq 0x67360
movq %rax, -0x5d68(%rbp)
movq %rdx, -0x5d60(%rbp)
leaq -0x5d68(%rbp), %rdi
callq 0x673c0
testb $0x1, %al
jne 0x77465
jmp 0x7749b
leaq 0x72ea4(%rip), %rdi     # 0xea310
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movslq -0x5d50(%rbp), %rsi
callq 0x792e0
movsd 0x18(%rax), %xmm0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
jmp 0x774cf
leaq 0x72e56(%rip), %rdi     # 0xea2f8
xorl %eax, %eax
movl %eax, %esi
callq 0x792c0
movq %rax, %rdi
movslq -0x5d54(%rbp), %rsi
callq 0x792e0
movsd 0x18(%rax), %xmm0
mulsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d48(%rbp)
jmp 0x774d1
movsd -0x5d48(%rbp), %xmm0
movsd %xmm0, -0x5d90(%rbp)
movslq -0x5d3c(%rbp), %rsi
leaq -0x5750(%rbp), %rdi
callq 0x795d0
movsd -0x5d90(%rbp), %xmm0
movsd %xmm0, (%rax)
movl -0x5d40(%rbp), %eax
movl %eax, -0x5d84(%rbp)
movslq -0x5d3c(%rbp), %rsi
leaq -0x5750(%rbp), %rdi
callq 0x795d0
movl -0x5d84(%rbp), %ecx
movl %ecx, 0x8(%rax)
movl -0x5d3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5d3c(%rbp)
jmp 0x770df
leaq -0x5750(%rbp), %rdi
callq 0x79580
movq %rax, -0x5d98(%rbp)
leaq -0x5750(%rbp), %rdi
callq 0x795a0
movq -0x5d98(%rbp), %rdi
movq %rax, %rsi
callq 0x79600
movl $0x0, -0x5d70(%rbp)
movl $0x0, -0x5d74(%rbp)
movl -0x5d74(%rbp), %eax
leaq 0x704b5(%rip), %rcx     # 0xe7a40
cmpl (%rcx), %eax
jge 0x77659
cmpl $0x0, -0x5d74(%rbp)
je 0x775f4
movslq -0x5d74(%rbp), %rsi
leaq -0x5750(%rbp), %rdi
callq 0x795d0
movsd (%rax), %xmm0
movsd %xmm0, -0x5da0(%rbp)
movl -0x5d74(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq -0x5750(%rbp), %rdi
callq 0x795d0
movsd -0x5da0(%rbp), %xmm0
ucomisd (%rax), %xmm0
jne 0x775f4
jp 0x775f4
movl -0x5d70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5d70(%rbp)
jmp 0x775fe
movl $0x0, -0x5d70(%rbp)
movslq -0x5d74(%rbp), %rsi
leaq -0x5750(%rbp), %rdi
callq 0x795d0
movl 0x8(%rax), %eax
cmpl -0x5d10(%rbp), %eax
jne 0x77643
movl -0x5d74(%rbp), %eax
subl -0x5d70(%rbp), %eax
movslq %eax, %rsi
leaq 0x72dc6(%rip), %rdi     # 0xea3f8
callq 0x794d0
movq %rax, %rdi
xorl %esi, %esi
callq 0x6c350
jmp 0x77659
jmp 0x77645
movl -0x5d74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5d74(%rbp)
jmp 0x7757e
movq -0x8(%rbp), %rdi
movl -0x5d10(%rbp), %esi
movl -0x5754(%rbp), %edx
callq 0x9dbc0
movl -0x5754(%rbp), %edi
callq 0x25810
movl %eax, -0x5754(%rbp)
movl -0x5d10(%rbp), %eax
movl %eax, -0x5d08(%rbp)
movl -0x5d0c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5d0c(%rbp)
jmp 0x76f15
addq $0x5da0, %rsp           # imm = 0x5DA0
popq %rbp
retq
nopl (%rax,%rax)