// File: /workspace/github_cpp_makefile_star2_O3/kobanium[P]Ray/src/mcts/UctSearch.cpp
// Function: UctSearch(game_info_t*, int, std::mersenne_twister_engine<unsigned long, 64ul, 312ul, 156ul, 31ul, 13043109905998158313ul, 29ul, 6148914691236517205ul, 17ul, 8202884508482404352ul, 37ul, 18444473444759240704ul, 43ul, 6364136223846793005ul>&, int, int&)
static int 
UctSearch( game_info_t *game, int color, std::mt19937_64 &mt, int current, int &winner )
{
  int result = 0, next_index;
  double score;
  child_node_t *uct_child = uct_node[current].child;  

  // 現在見ているノードをロック
  mutex_nodes[current].lock();
  // UCB値最大の手を求める
  next_index = SelectMaxUcbChild(current, color, mt);
  // 選んだ手を着手
  PutStone(game, uct_child[next_index].pos, color);
  // 色を入れ替える
  color = GetOppositeColor(color);

  if ((uct_child[next_index].move_count + uct_child[next_index].virtual_loss) < GetExpandThreshold(game)) {
    AddVirtualLoss(uct_node[current], uct_child[next_index]);

    memcpy(game->seki, uct_node[current].seki, sizeof(bool) * BOARD_MAX);
    
    // 現在見ているノードのロックを解除
    mutex_nodes[current].unlock();

    // 終局まで対局のシミュレーション
    Simulation(game, color, mt);

    // 隅の曲がり四目の確認
    CheckBentFourInTheCorner(game);
    
    // コミを含めない盤面のスコアを求める
    score = static_cast<double>(CalculateScore(game));
    
    // コミを考慮した勝敗
    if (my_color == S_BLACK) {
      if (score - dynamic_komi[my_color] >= 0) {
        result = (color == S_BLACK ? 0 : 1);
        winner = S_BLACK;
      } else {
        result = (color == S_WHITE ? 0 : 1);
        winner = S_WHITE;
      }
    } else {
      if (score - dynamic_komi[my_color] > 0) {
        result = (color == S_BLACK ? 0 : 1);
        winner = S_BLACK;
      } else {
        result = (color == S_WHITE ? 0 : 1);
        winner = S_WHITE;
      }
    }
    // 統計情報の記録
    Statistic(game, winner);
  } else {
    // Virtual Lossを加算
    AddVirtualLoss(uct_node[current], uct_child[next_index]);
    // ノードの展開の確認
    if (uct_child[next_index].index == -1) {
      // ノードの展開中はロック
      mutex_expand.lock();
      // ノードの展開
      uct_child[next_index].index = ExpandNode(game, color, current);
      // ノード展開のロックの解除
      mutex_expand.unlock();
    }
    // 現在見ているノードのロックを解除
    mutex_nodes[current].unlock();
    // 手番を入れ替えて1手深く読む
    result = UctSearch(game, color, mt, uct_child[next_index].index, winner);
  }

  // 探索結果の反映
  UpdateResult(uct_node[current], uct_child[next_index], result);

  mutex_nodes[current].lock();
  UpdateOwnership(uct_node[current], game, GetOppositeColor(color));
  mutex_nodes[current].unlock();

  return 1 - result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r8, 0x10(%rsp)
movq %rdx, %rbp
movl %esi, %r13d
movq %rdi, %r14
movq 0x1aa8f7fe(%rip), %rbx  # 0x1aadb930
movslq %ecx, %r15
leaq (%r15,%r15,4), %r12
shlq $0x3, %r12
movq 0x1aab6fb4(%rip), %rdi  # 0x1ab030f8
addq %r12, %rdi
callq 0x65f0
testl %eax, %eax
jne 0x4c6af
imulq $0x4548, %r15, %rax     # imm = 0x4548
movq %rax, 0x28(%rsp)
addq %rax, %rbx
movl %r15d, %edi
movl %r13d, %esi
movq %rbp, 0x18(%rsp)
movq %rbp, %rdx
callq 0x4c8c0
cltq
leaq (%rax,%rax,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %rax, %rcx
addq %rcx, %rbx
addq $0x1c, %rbx
movswl (%rbx), %esi
movq %r14, %rdi
movl %r13d, %edx
callq 0x55ae8
movl 0x4(%rbx), %eax
movq %rbx, 0x38(%rsp)
movl 0x8(%rbx), %ebp
addl %eax, %ebp
movl 0x43b0(%r14), %eax
cmpl $0x3, %eax
movq %r14, (%rsp)
jl 0x4c1d7
leal -0x1(%rax), %ecx
shlq $0x4, %rcx
cmpl $0x0, 0x4(%r14,%rcx)
jne 0x4c1d7
addl $-0x2, %eax
shlq $0x4, %rax
cmpl $0x0, 0x4(%r14,%rax)
je 0x4c5e7
movl 0x2a69e(%rip), %r14d    # 0x7687c
movl %r13d, 0x8(%rsp)
xorl $0x3, %r13d
movq 0x1aa8f742(%rip), %rdi  # 0x1aadb930
movq 0x28(%rsp), %r15
addq %r15, %rdi
movq 0x38(%rsp), %rbx
movq %rbx, %rsi
callq 0x4a0a9
cmpl %r14d, %ebp
jge 0x4c29f
movq (%rsp), %rbx
leaq 0x97029(%rbx), %rdi
movq 0x1aa8f712(%rip), %rax  # 0x1aadb930
leaq (%rax,%r15), %rsi
addq $0x27b4, %rsi           # imm = 0x27B4
movl $0x349, %edx            # imm = 0x349
callq 0x6320
movq 0x1aab6ebe(%rip), %rdi  # 0x1ab030f8
movq %r12, 0x30(%rsp)
addq %r12, %rdi
callq 0x62e0
movq %rbx, %rdi
movl %r13d, %esi
movq 0x18(%rsp), %rdx
callq 0x48458
movq %rbx, %rdi
callq 0x561ed
movq %rbx, %rdi
callq 0x56321
cvtsi2sd %eax, %xmm0
movslq 0x1aabf776(%rip), %rcx  # 0x1ab0b9e8
cmpq $0x1, %rcx
jne 0x4c512
leaq 0x1aac0cad(%rip), %rax  # 0x1ab0cf30
xorl %r12d, %r12d
ucomisd 0x8(%rax), %xmm0
setb %r12b
movl $0x2, %eax
subl %r12d, %eax
incl %r12d
jmp 0x4c52e
movl %r13d, %r14d
cmpl $-0x1, 0x10(%rbx)
movq 0x18(%rsp), %rbp
movl 0x8(%rsp), %r13d
jne 0x4c627
leaq 0x1aabfd33(%rip), %rdi  # 0x1ab0bff0
callq 0x65f0
testl %eax, %eax
jne 0x4c6af
movq (%rsp), %rax
movl 0x43b0(%rax), %r13d
movq 0x43f0(%rax), %r15
movq %r15, %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x56c69
leaq 0x2a5df(%rip), %rbx     # 0x768d0
cmpl (%rbx), %eax
jne 0x4c609
movq %r15, %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x56bf4
cmpl (%rbx), %eax
je 0x4c6b6
movq %r12, 0x30(%rsp)
movslq %r13d, %rdx
shlq $0x4, %rdx
movq (%rsp), %rcx
movl -0xc(%rdx,%rcx), %esi
xorl %edx, %edx
cmpl $0x2, %r13d
jl 0x4c338
addl $-0x2, %r13d
shlq $0x4, %r13
movl 0x4(%rcx,%r13), %edx
movl %eax, 0x24(%rsp)
movl %eax, %eax
imulq $0x4548, %rax, %r15     # imm = 0x4548
movq 0x1aa8f5e4(%rip), %rdi  # 0x1aadb930
addq %r15, %rdi
movl %esi, 0x44(%rsp)
callq 0x4a038
movq 0x1aa8f5d1(%rip), %rcx  # 0x1aadb930
movq %r15, 0x50(%rsp)
movq %rcx, 0x48(%rsp)
leaq (%rcx,%r15), %rdi
addq $0x1c, %rdi
leaq 0xc(%rsp), %rsi
movl $0x0, (%rsi)
movq %rdi, %rbx
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x4a082
movq (%rsp), %rdx
leaq 0x2a51d(%rip), %rax     # 0x768b0
cmpl $0x0, (%rax)
jle 0x4c41c
movq %rax, %rbp
xorl %r15d, %r15d
leaq 0x1aab94d7(%rip), %r12  # 0x1ab05880
leaq 0x1ab15340(%rip), %rax  # 0x1ab616f0
movslq (%rax,%r15,4), %r13
cmpb $0x1, (%r13,%r12)
jne 0x4c410
movq (%rsp), %rdi
movl %r13d, %esi
movl %r14d, %edx
callq 0x55478
movq (%rsp), %rdx
testb %al, %al
je 0x4c410
movq (%rsp), %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x5c3e4
movq (%rsp), %rdx
testb %al, %al
je 0x4c410
movslq 0xc(%rsp), %rdi
leaq (%rdi,%rdi,8), %rax
leaq (%rax,%rax,2), %rax
addq %rbx, %rdi
addq %rax, %rdi
leaq 0xc(%rsp), %rsi
movl %r13d, %edx
xorl %ecx, %ecx
callq 0x4a082
movq (%rsp), %rdx
incq %r15
movslq (%rbp), %rax
cmpq %rax, %r15
jl 0x4c3a9
movl 0xc(%rsp), %eax
movq 0x1aa8f509(%rip), %rcx  # 0x1aadb930
movq 0x50(%rsp), %r13
movl %eax, 0x18(%rcx,%r13)
movq %rdx, %r15
movq %rdx, %rdi
movl %r14d, %esi
movl 0x24(%rsp), %edx
callq 0x4be91
movq 0x1aa8f4e6(%rip), %rax  # 0x1aadb930
leaq (%rax,%r13), %rsi
addq $0x27b4, %rsi           # imm = 0x27B4
movq %r15, %rdi
callq 0x56d88
movq 0x1aa8f4cc(%rip), %rcx  # 0x1aadb930
incl 0x14(%rcx,%r13)
movq 0x28(%rsp), %rsi
movslq 0x18(%rcx,%rsi), %rdx
testq %rdx, %rdx
movq 0x30(%rsp), %r12
movl 0x44(%rsp), %edi
movl $0x0, %r8d
movq 0x18(%rsp), %rbp
jle 0x4c4ce
leaq (%rdx,%rdx,8), %rax
leaq (%rax,%rax,2), %rax
addq %rdx, %rax
addq %rsi, %rcx
addq $0x30, %rcx
xorpd %xmm0, %xmm0
xorl %edx, %edx
xorl %r8d, %r8d
movswl -0x14(%rcx,%rdx), %esi
cmpl %esi, %edi
je 0x4c4c5
xorps %xmm1, %xmm1
cvtss2sd (%rcx,%rdx), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x4c4c5
movapd %xmm1, %xmm0
movl %esi, %r8d
addq $0x1c, %rdx
cmpq %rdx, %rax
jne 0x4c4a7
movslq 0xc(%rsp), %rax
testq %rax, %rax
jle 0x4c605
leaq (%rax,%rax,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %rax, %rcx
movq 0x48(%rsp), %rax
leaq (%rax,%r13), %rdx
addq $0x35, %rdx
xorl %eax, %eax
movswl -0x19(%rdx,%rax), %esi
cmpl %esi, %r8d
je 0x4c5f2
addq $0x1c, %rax
cmpq %rax, %rcx
jne 0x4c4f6
jmp 0x4c605
leaq 0x1aac0a17(%rip), %rdx  # 0x1ab0cf30
xorl %eax, %eax
ucomisd (%rdx,%rcx,8), %xmm0
seta %al
movl $0x2, %r12d
subl %eax, %r12d
incl %eax
movq 0x10(%rsp), %rcx
movl 0x8(%rsp), %edx
cmpl %edx, %eax
setne 0x10(%rsp)
movl %r12d, (%rcx)
leaq 0x2a368(%rip), %rbx     # 0x768b0
cmpl $0x0, (%rbx)
movq (%rsp), %rcx
jle 0x4c5c1
leaq 0x4748(%rcx), %rax
movq %rax, 0x18(%rsp)
xorl %r14d, %r14d
leaq 0x1ab15189(%rip), %rbp  # 0x1ab616f0
leaq 0x1aab9862(%rip), %r13  # 0x1ab05dd0
movslq (%rbp,%r14,4), %r15
movsbl 0x43f8(%rcx,%r15), %eax
testl %eax, %eax
jne 0x4c59e
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x4fc2a
movq (%rsp), %rcx
movl %eax, %eax
leaq 0x1aae3146(%rip), %rdx  # 0x1ab2f6e0
movzbl (%rdx,%rax), %eax
shlq $0x4, %r15
addq %r13, %r15
cltq
lock
incl (%r15,%rax,4)
cmpl %r12d, %eax
jne 0x4c5b6
lock
incl 0xc(%r15)
incq %r14
movslq (%rbx), %rax
cmpq %rax, %r14
jl 0x4c56e
xorl %ebp, %ebp
movb 0x10(%rsp), %al
movb %al, %bpl
lock
incl 0x1aabcc8f(%rip)        # 0x1ab09260
movq 0x30(%rsp), %r12
movl 0x8(%rsp), %r13d
movq 0x28(%rsp), %r15
movq 0x38(%rsp), %rbx
jmp 0x4c64f
movl $0x7ffffffe, %r14d      # imm = 0x7FFFFFFE
jmp 0x4c1de
addq 0x48(%rsp), %r13
cmpb $0x0, 0x34(%rax,%r13)
jne 0x4c605
movb $0x1, 0x35(%rax,%r13)
movl 0x24(%rsp), %eax
movq 0x38(%rsp), %rbx
movl %eax, 0x10(%rbx)
leaq 0x1aabf9d8(%rip), %rdi  # 0x1ab0bff0
callq 0x62e0
movl 0x8(%rsp), %r13d
movq 0x28(%rsp), %r15
movq 0x1aab6aca(%rip), %rdi  # 0x1ab030f8
addq %r12, %rdi
callq 0x62e0
movl 0x10(%rbx), %ecx
movq (%rsp), %rdi
movl %r14d, %esi
movq %rbp, %rdx
movq 0x10(%rsp), %r8
callq 0x4c10f
movl %eax, %ebp
movq 0x1aa8f2da(%rip), %rdi  # 0x1aadb930
addq %r15, %rdi
movq %rbx, %rsi
movl %ebp, %edx
callq 0x4a0b2
movq 0x1aab6a8e(%rip), %rdi  # 0x1ab030f8
addq %r12, %rdi
callq 0x65f0
testl %eax, %eax
jne 0x4c6af
addq 0x1aa8f2b3(%rip), %r15  # 0x1aadb930
movq %r15, %rdi
movq (%rsp), %rsi
movl %r13d, %edx
callq 0x4a173
addq 0x1aab6a65(%rip), %r12  # 0x1ab030f8
movq %r12, %rdi
callq 0x62e0
xorl $0x1, %ebp
movl %ebp, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %edi
callq 0x6260
leaq 0x13a28(%rip), %rdi     # 0x600e5
leaq 0x13a38(%rip), %rsi     # 0x600fc
leaq 0x13a6b(%rip), %rcx     # 0x60136
movl $0x328, %edx            # imm = 0x328
callq 0x6240