// File: /workspace/github_cpp_makefile_star2_O1/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
movl $0x0, 0x8(%rsp)
callq 0x53e60
movq %rax, %r14
cmpl $0x0, 0x8(%rbx)
je 0x4aeb7
leaq 0x8(%rsp), %r15
callq 0x4d5dd
movq (%rbx), %rsi
movq %r14, %rdi
callq 0x5432c
movslq 0x8(%rbx), %rax
imulq $0x9c8, %rax, %rdx      # imm = 0x9C8
leaq 0x1aa8faeb(%rip), %rax  # 0x1aada940
addq %rax, %rdx
movl 0x1aa8fada(%rip), %ecx  # 0x1aada938
movq %r14, %rdi
movl %ebp, %esi
movq %r15, %r8
callq 0x4bdbc
movslq 0x1aa8fac6(%rip), %rax  # 0x1aada938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa8fab0(%rip), %rdi  # 0x1aada930
callq 0x4d5e5
movl %eax, %r12d
callq 0x5630a
movl %eax, %r13d
callq 0x4d557
testb %al, %al
jne 0x4afd6
callq 0x4d599
andb %al, %r13b
xorb $0x1, %r13b
orb %r13b, %r12b
cmpb $0x1, %r12b
jne 0x4ae33
jmp 0x4afd6
movl %r15d, 0xc(%rsp)
movl $0x64, %r12d
callq 0x6070
movq %rax, 0x10(%rsp)
callq 0x4d5dd
movq (%rbx), %rsi
movq %r14, %rdi
callq 0x5432c
movslq 0x8(%rbx), %rax
imulq $0x9c8, %rax, %rdx      # imm = 0x9C8
leaq 0x1aa8fa52(%rip), %rax  # 0x1aada940
addq %rax, %rdx
movl 0x1aa8fa41(%rip), %ecx  # 0x1aada938
movq %r14, %rdi
movl %ebp, %esi
leaq 0x8(%rsp), %r8
callq 0x4bdbc
movslq 0x1aa8fa2b(%rip), %rax  # 0x1aada938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa8fa15(%rip), %rdi  # 0x1aada930
callq 0x4d5e5
movl %eax, %r13d
callq 0x5630a
movl %eax, %r15d
callq 0x4d5b2
cmpl %r12d, %eax
jle 0x4af47
movl %ebp, %edi
callq 0x4c382
movl %ebp, %edi
callq 0x4c436
addl $0x64, %r12d
cmpl $0x0, 0xc(%rsp)
jle 0x4afb8
callq 0x6070
subq 0x10(%rsp), %rax
movabsq $0x431bde82d7b634db, %rcx # imm = 0x431BDE82D7B634DB
imulq %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x12, %rdx
addq %rax, %rdx
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
divsd 0x14fed(%rip), %xmm0    # 0x5ff70
mulsd 0x1208d(%rip), %xmm0    # 0x5d018
cvttsd2si %xmm0, %eax
cmpl %eax, 0x10(%rbx)
jge 0x4afb8
callq 0x6070
movq %rax, 0x10(%rsp)
movslq 0x1aa8f993(%rip), %rax  # 0x1aada938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa8f97d(%rip), %rdi  # 0x1aada930
callq 0x1efbb
callq 0x4d557
testb %al, %al
jne 0x4afd6
callq 0x4d599
andb %al, %r15b
xorb $0x1, %r15b
orb %r15b, %r13b
je 0x4aecc
movq %r14, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x53e7b