// File: /workspace/github_cpp_makefile_star2_O2/kobanium[P]Ray/src/mcts/UctSearch.cpp
// Function: ParallelUctSearch(thread_arg_t*)
static void
ParallelUctSearch( thread_arg_t *arg )
{
  const thread_arg_t *targ = (thread_arg_t *)arg;
  const int color = targ->color;
  bool interruption = false, enough_size = true;
  bool use_analysis = targ->lz_analysis_cs > 0 ? true : false;
  int winner = 0, interval = CRITICALITY_INTERVAL;
  game_info_t *game = AllocateGame();
  ray_clock::time_point analysis_timer;

  // スレッドIDが0のスレッドだけ別の処理をする
  // 探索回数が閾値を超える, または探索が打ち切られたらループを抜ける
  if (targ->thread_id == 0) {
    analysis_timer = ray_clock::now();

    do {
      // 探索回数を1回増やす
      IncrementPoCount();
      // 盤面のコピー
      CopyGame(game, targ->game);
      // 1回プレイアウトする
      UctSearch(game, color, mt[targ->thread_id], current_root, winner);
      // 探索を打ち切るか確認
      interruption = CheckInterruption(uct_node[current_root]);
      //interruption = InterruptionCheck();
      // ハッシュに余裕があるか確認
      enough_size = CheckRemainingHashSize();
      // OwnerとCriticalityを計算する
      if (GetPoCount() > interval) {
        CalculateOwner(color);
        CalculateCriticality(color);
        interval += CRITICALITY_INTERVAL;
      }

      if (use_analysis &&
          static_cast<int>(100 * GetSpendTime(analysis_timer)) > targ->lz_analysis_cs) {
        analysis_timer = ray_clock::now();
        PrintLeelaZeroAnalyze(&uct_node[current_root]);
      }

      if (IsTimeOver()) break;
    } while (IsSearchContinue() && !interruption && enough_size);
  } else {
    do {
      // 探索回数を1回増やす
      IncrementPoCount();
      // 盤面のコピー
      CopyGame(game, targ->game);
      // 1回プレイアウトする
      UctSearch(game, color, mt[targ->thread_id], current_root, winner);
      // 探索を打ち切るか確認
      interruption = CheckInterruption(uct_node[current_root]);
      //interruption = InterruptionCheck();
      // ハッシュに余裕があるか確認
      enough_size = CheckRemainingHashSize();

      if (IsTimeOver()) break;
    } while (IsSearchContinue() && !interruption && enough_size);
  }

  // メモリの解放
  FreeGame(game);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl 0xc(%rdi), %ebp
movl 0x10(%rdi), %r15d
callq 0x3b148
andq $0x0, 0x8(%rsp)
movq %rax, %r14
cmpl $0x0, 0x8(%rbx)
je 0x336ec
leaq 0x14(%rsp), %r15
callq 0x35c74
movq (%rbx), %rsi
movq %r14, %rdi
callq 0x3b5f2
movslq 0x8(%rbx), %rax
imulq $0x9c8, %rax, %rdx      # imm = 0x9C8
leaq 0x1aa932b6(%rip), %rax  # 0x1aac6940
addq %rax, %rdx
movl 0x1aa932a5(%rip), %ecx  # 0x1aac6938
movq %r14, %rdi
movl %ebp, %esi
movq %r15, %r8
callq 0x344ff
movslq 0x1aa93291(%rip), %rax  # 0x1aac6938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa9327b(%rip), %rdi  # 0x1aac6930
callq 0x35c7c
movl %eax, %r12d
callq 0x3d2a4
movl %eax, %r13d
callq 0x35c1d
testb %al, %al
jne 0x337e1
callq 0x35c30
andb %al, %r13b
xorb $0x1, %r13b
orb %r13b, %r12b
cmpb $0x1, %r12b
jne 0x33668
jmp 0x337e1
movl %r15d, 0x10(%rsp)
callq 0x6060
leaq 0x8(%rsp), %rcx
movq %rax, (%rcx)
pushq $0x64
popq %r12
callq 0x35c74
movq (%rbx), %rsi
movq %r14, %rdi
callq 0x3b5f2
movslq 0x8(%rbx), %rax
imulq $0x9c8, %rax, %rdx      # imm = 0x9C8
leaq 0x1aa9321c(%rip), %rax  # 0x1aac6940
addq %rax, %rdx
movl 0x1aa9320b(%rip), %ecx  # 0x1aac6938
movq %r14, %rdi
movl %ebp, %esi
leaq 0x14(%rsp), %r8
callq 0x344ff
movslq 0x1aa931f5(%rip), %rax  # 0x1aac6938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa931df(%rip), %rdi  # 0x1aac6930
callq 0x35c7c
movl %eax, %r13d
callq 0x3d2a4
movl %eax, %r15d
callq 0x35c49
cmpl %r12d, %eax
jle 0x3377d
movl %ebp, %edi
callq 0x34a61
movl %ebp, %edi
callq 0x34b0d
addl $0x64, %r12d
cmpl $0x0, 0x10(%rsp)
jle 0x337c3
leaq 0x8(%rsp), %rdi
callq 0x355d9
mulsd 0x10882(%rip), %xmm0    # 0x44018
cvttsd2si %xmm0, %eax
cmpl %eax, 0x10(%rbx)
jge 0x337c3
callq 0x6060
movq %rax, 0x8(%rsp)
movslq 0x1aa93188(%rip), %rax  # 0x1aac6938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa93172(%rip), %rdi  # 0x1aac6930
callq 0x108dc
callq 0x35c1d
testb %al, %al
jne 0x337e1
callq 0x35c30
andb %al, %r15b
xorb $0x1, %r15b
orb %r15b, %r13b
je 0x33702
movq %r14, %rdi
callq 0x3b163
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq