// File: /workspace/github_cpp_makefile_star2_O1/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 0x1aa8eb51(%rip), %rbx  # 0x1aada930
movslq %ecx, %r15
leaq (%r15,%r15,4), %r12
shlq $0x3, %r12
movq 0x1aab6307(%rip), %rdi  # 0x1ab020f8
addq %r12, %rdi
callq 0x6600
testl %eax, %eax
jne 0x4c35c
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 0x4c56d
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 0x55134
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 0x4be84
leal -0x1(%rax), %ecx
shlq $0x4, %rcx
cmpl $0x0, 0x4(%r14,%rcx)
jne 0x4be84
addl $-0x2, %eax
shlq $0x4, %rax
cmpl $0x0, 0x4(%r14,%rax)
je 0x4c294
movl 0x299f1(%rip), %r14d    # 0x7587c
movl %r13d, 0x8(%rsp)
xorl $0x3, %r13d
movq 0x1aa8ea95(%rip), %rdi  # 0x1aada930
movq 0x28(%rsp), %r15
addq %r15, %rdi
movq 0x38(%rsp), %rbx
movq %rbx, %rsi
callq 0x49e31
cmpl %r14d, %ebp
jge 0x4bf4c
movq (%rsp), %rbx
leaq 0x97029(%rbx), %rdi
movq 0x1aa8ea65(%rip), %rax  # 0x1aada930
leaq (%rax,%r15), %rsi
addq $0x27b4, %rsi           # imm = 0x27B4
movl $0x349, %edx            # imm = 0x349
callq 0x6330
movq 0x1aab6211(%rip), %rdi  # 0x1ab020f8
movq %r12, 0x30(%rsp)
addq %r12, %rdi
callq 0x62f0
movq %rbx, %rdi
movl %r13d, %esi
movq 0x18(%rsp), %rdx
callq 0x481fc
movq %rbx, %rdi
callq 0x55830
movq %rbx, %rdi
callq 0x5595f
cvtsi2sd %eax, %xmm0
movslq 0x1aabeac9(%rip), %rcx  # 0x1ab0a9e8
cmpq $0x1, %rcx
jne 0x4c1bf
leaq 0x1aac0000(%rip), %rax  # 0x1ab0bf30
xorl %r12d, %r12d
ucomisd 0x8(%rax), %xmm0
setb %r12b
movl $0x2, %eax
subl %r12d, %eax
incl %r12d
jmp 0x4c1db
movl %r13d, %r14d
cmpl $-0x1, 0x10(%rbx)
movq 0x18(%rsp), %rbp
movl 0x8(%rsp), %r13d
jne 0x4c2d4
leaq 0x1aabf086(%rip), %rdi  # 0x1ab0aff0
callq 0x6600
testl %eax, %eax
jne 0x4c35c
movq (%rsp), %rax
movl 0x43b0(%rax), %r13d
movq 0x43f0(%rax), %r15
movq %r15, %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x562af
leaq 0x29932(%rip), %rbx     # 0x758d0
cmpl (%rbx), %eax
jne 0x4c2b6
movq %r15, %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x5623a
cmpl (%rbx), %eax
je 0x4c363
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 0x4bfe5
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 0x1aa8e937(%rip), %rdi  # 0x1aada930
addq %r15, %rdi
movl %esi, 0x44(%rsp)
callq 0x49dc0
movq 0x1aa8e924(%rip), %rcx  # 0x1aada930
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 0x49e0a
movq (%rsp), %rdx
leaq 0x29870(%rip), %rax     # 0x758b0
cmpl $0x0, (%rax)
jle 0x4c0c9
movq %rax, %rbp
xorl %r15d, %r15d
leaq 0x1aab882a(%rip), %r12  # 0x1ab04880
leaq 0x1ab14693(%rip), %rax  # 0x1ab606f0
movslq (%rax,%r15,4), %r13
cmpb $0x1, (%r13,%r12)
jne 0x4c0bd
movq (%rsp), %rdi
movl %r13d, %esi
movl %r14d, %edx
callq 0x54a9c
movq (%rsp), %rdx
testb %al, %al
je 0x4c0bd
movq (%rsp), %rdi
movl %r14d, %esi
movl %r13d, %edx
callq 0x5bb5d
movq (%rsp), %rdx
testb %al, %al
je 0x4c0bd
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 0x49e0a
movq (%rsp), %rdx
incq %r15
movslq (%rbp), %rax
cmpq %rax, %r15
jl 0x4c056
movl 0xc(%rsp), %eax
movq 0x1aa8e85c(%rip), %rcx  # 0x1aada930
movq 0x50(%rsp), %r13
movl %eax, 0x18(%rcx,%r13)
movq %rdx, %r15
movq %rdx, %rdi
movl %r14d, %esi
movl 0x24(%rsp), %edx
callq 0x4bb3e
movq 0x1aa8e839(%rip), %rax  # 0x1aada930
leaq (%rax,%r13), %rsi
addq $0x27b4, %rsi           # imm = 0x27B4
movq %r15, %rdi
callq 0x563dc
movq 0x1aa8e81f(%rip), %rcx  # 0x1aada930
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 0x4c17b
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 0x4c172
xorps %xmm1, %xmm1
cvtss2sd (%rcx,%rdx), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x4c172
movapd %xmm1, %xmm0
movl %esi, %r8d
addq $0x1c, %rdx
cmpq %rdx, %rax
jne 0x4c154
movslq 0xc(%rsp), %rax
testq %rax, %rax
jle 0x4c2b2
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 0x4c29f
addq $0x1c, %rax
cmpq %rax, %rcx
jne 0x4c1a3
jmp 0x4c2b2
leaq 0x1aabfd6a(%rip), %rdx  # 0x1ab0bf30
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 0x296bb(%rip), %rbx     # 0x758b0
cmpl $0x0, (%rbx)
movq (%rsp), %rcx
jle 0x4c26e
leaq 0x4748(%rcx), %rax
movq %rax, 0x18(%rsp)
xorl %r14d, %r14d
leaq 0x1ab144dc(%rip), %rbp  # 0x1ab606f0
leaq 0x1aab8bb5(%rip), %r13  # 0x1ab04dd0
movslq (%rbp,%r14,4), %r15
movsbl 0x43f8(%rcx,%r15), %eax
testl %eax, %eax
jne 0x4c24b
movq 0x18(%rsp), %rdi
movl %r15d, %esi
callq 0x4f84b
movq (%rsp), %rcx
movl %eax, %eax
leaq 0x1aae2499(%rip), %rdx  # 0x1ab2e6e0
movzbl (%rdx,%rax), %eax
shlq $0x4, %r15
addq %r13, %r15
cltq
lock
incl (%r15,%rax,4)
cmpl %r12d, %eax
jne 0x4c263
lock
incl 0xc(%r15)
incq %r14
movslq (%rbx), %rax
cmpq %rax, %r14
jl 0x4c21b
xorl %ebp, %ebp
movb 0x10(%rsp), %al
movb %al, %bpl
lock
incl 0x1aabbfe2(%rip)        # 0x1ab08260
movq 0x30(%rsp), %r12
movl 0x8(%rsp), %r13d
movq 0x28(%rsp), %r15
movq 0x38(%rsp), %rbx
jmp 0x4c2fc
movl $0x7ffffffe, %r14d      # imm = 0x7FFFFFFE
jmp 0x4be8b
addq 0x48(%rsp), %r13
cmpb $0x0, 0x34(%rax,%r13)
jne 0x4c2b2
movb $0x1, 0x35(%rax,%r13)
movl 0x24(%rsp), %eax
movq 0x38(%rsp), %rbx
movl %eax, 0x10(%rbx)
leaq 0x1aabed2b(%rip), %rdi  # 0x1ab0aff0
callq 0x62f0
movl 0x8(%rsp), %r13d
movq 0x28(%rsp), %r15
movq 0x1aab5e1d(%rip), %rdi  # 0x1ab020f8
addq %r12, %rdi
callq 0x62f0
movl 0x10(%rbx), %ecx
movq (%rsp), %rdi
movl %r14d, %esi
movq %rbp, %rdx
movq 0x10(%rsp), %r8
callq 0x4bdbc
movl %eax, %ebp
movq 0x1aa8e62d(%rip), %rdi  # 0x1aada930
addq %r15, %rdi
movq %rbx, %rsi
movl %ebp, %edx
callq 0x49e3a
movq 0x1aab5de1(%rip), %rdi  # 0x1ab020f8
addq %r12, %rdi
callq 0x6600
testl %eax, %eax
jne 0x4c35c
addq 0x1aa8e606(%rip), %r15  # 0x1aada930
movq %r15, %rdi
movq (%rsp), %rsi
movl %r13d, %edx
callq 0x49ef5
addq 0x1aab5db8(%rip), %r12  # 0x1ab020f8
movq %r12, %rdi
callq 0x62f0
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 0x6270
leaq 0x13c93(%rip), %rdi     # 0x5fffd
leaq 0x13ca3(%rip), %rsi     # 0x60014
leaq 0x13cd6(%rip), %rcx     # 0x6004e
movl $0x328, %edx            # imm = 0x328
callq 0x6250