// File: kobanium[P]Ray/src/mcts/UctSearch.cpp
// Function: ExpandNode(game_info_t*, int, int)
static int
ExpandNode( game_info_t *game, int color, int current )
{
  const int moves = game->moves;
  const unsigned long long hash = game->move_hash;
  unsigned int index = FindSameHashIndex(hash, color, moves);
  int pm1 = PASS, pm2 = PASS;
  
  // 合流先が検知できれば, それを返す
  if (index != uct_hash_size) {
    return index;
  }

  // 空のインデックスを探す
  index = SearchEmptyIndex(hash, color, moves);

  assert(index != uct_hash_size);    

  // 直前の着手の座標を取り出す
  pm1 = game->record[moves - 1].pos;
  // 2手前の着手の座標を取り出す
  if (moves > 1) pm2 = game->record[moves - 2].pos;

  // 現在のノードの初期化
  InitializeNode(uct_node[index], pm1, pm2);

  child_node_t *uct_child = uct_node[index].child;
  int child_num = 0;

  // パスノードの展開
  InitializeCandidate(uct_child[PASS_INDEX], child_num, PASS, false);

  // 候補手の展開
  for (int i = 0; i < pure_board_max; i++) {
    const int pos = onboard_pos[i];
    // 探索候補でなければ除外
    if (candidates[pos] &&
        IsLegal(game, pos, color) &&
        IsMeaningfulSelfAtari(game, color, pos)) {
      InitializeCandidate(uct_child[child_num], child_num, pos, false);
    }
  }

  // 子ノードの個数を設定
  uct_node[index].child_num = child_num;

  // 候補手のレーティング
  RatingNode(game, color, index);

  // セキの確認
  CheckSeki(game, uct_node[index].seki);
  
  // 探索幅を1つ増やす
  uct_node[index].width++;

  // 兄弟ノードで一番レートの高い手を求める
  const int sibling_num = uct_node[current].child_num;
  child_node_t *uct_sibling = uct_node[current].child;
  double max_rate = 0.0;
  int max_pos = PASS;

  for (int i = 0; i < sibling_num; i++) {
    if (uct_sibling[i].pos != pm1) {
      if (uct_sibling[i].rate > max_rate) {
        max_rate = uct_sibling[i].rate;
        max_pos = uct_sibling[i].pos;
      }
    }
  }

  // 兄弟ノードで一番レートの高い手を展開する
  for (int i = 0; i < child_num; i++) {
    if (uct_child[i].pos == max_pos) {
      if (!uct_child[i].pw) {
        uct_child[i].open = true;
      }
      break;
    }
  }

  return index;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl 0x43b0(%rax), %eax
movl %eax, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq 0x43f0(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x1c(%rbp), %edx
callq 0x9fc90
movl %eax, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x2c(%rbp), %eax
leaq 0x5b4f8(%rip), %rcx     # 0xe7a60
cmpl (%rcx), %eax
je 0x8c577
movl -0x2c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x8c86d
movq -0x28(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x1c(%rbp), %edx
callq 0x9fb80
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
leaq 0x5b4cd(%rip), %rcx     # 0xe7a60
cmpl (%rcx), %eax
je 0x8c599
jmp 0x8c5b8
leaq 0x22c41(%rip), %rdi     # 0xaf1e1
leaq 0x22c51(%rip), %rsi     # 0xaf1f8
movl $0x328, %edx            # imm = 0x328
leaq 0x22c7f(%rip), %rcx     # 0xaf232
callq 0x7350
movq -0x10(%rbp), %rax
movl -0x1c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x30(%rbp)
cmpl $0x1, -0x1c(%rbp)
jle 0x8c5f2
movq -0x10(%rbp), %rax
movl -0x1c(%rbp), %ecx
subl $0x2, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x34(%rbp)
movq 0x1aac04b7(%rip), %rdi  # 0x1ab4cab0
movl -0x2c(%rbp), %eax
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rdi
movl -0x30(%rbp), %esi
movl -0x34(%rbp), %edx
callq 0x87ef0
movq 0x1aac0498(%rip), %rax  # 0x1ab4cab0
movl -0x2c(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
addq $0x1c, %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
movq -0x40(%rbp), %rdi
leaq -0x44(%rbp), %rsi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x87fa0
movl $0x0, -0x48(%rbp)
movl -0x48(%rbp), %eax
leaq 0x5b3ea(%rip), %rcx     # 0xe7a40
cmpl (%rcx), %eax
jge 0x8c6d3
movslq -0x48(%rbp), %rcx
leaq 0x1ab4620b(%rip), %rax  # 0x1abd2870
movl (%rax,%rcx,4), %eax
movl %eax, -0x4c(%rbp)
movslq -0x4c(%rbp), %rcx
leaq 0x1aaea38a(%rip), %rax  # 0x1ab76a00
testb $0x1, (%rax,%rcx)
je 0x8c6c3
movq -0x10(%rbp), %rdi
movl -0x4c(%rbp), %esi
movl -0x14(%rbp), %edx
callq 0x9d0b0
testb $0x1, %al
jne 0x8c691
jmp 0x8c6c3
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x4c(%rbp), %edx
callq 0xa98d0
testb $0x1, %al
jne 0x8c6a6
jmp 0x8c6c3
movq -0x40(%rbp), %rdi
movslq -0x44(%rbp), %rax
imulq $0x1c, %rax, %rax
addq %rax, %rdi
movl -0x4c(%rbp), %edx
leaq -0x44(%rbp), %rsi
xorl %ecx, %ecx
callq 0x87fa0
jmp 0x8c6c5
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x8c64c
movl -0x44(%rbp), %ecx
movq 0x1aac03d3(%rip), %rax  # 0x1ab4cab0
movl -0x2c(%rbp), %edx
imulq $0x4548, %rdx, %rdx     # imm = 0x4548
addq %rdx, %rax
movl %ecx, 0x18(%rax)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x8b2c0
movq -0x10(%rbp), %rdi
movq 0x1aac03a9(%rip), %rsi  # 0x1ab4cab0
movl -0x2c(%rbp), %eax
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rsi
addq $0x27b4, %rsi           # imm = 0x27B4
callq 0xa00f0
movq 0x1aac0389(%rip), %rax  # 0x1ab4cab0
movl -0x2c(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
movl 0x14(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x14(%rax)
movq 0x1aac036c(%rip), %rax  # 0x1ab4cab0
movslq -0x18(%rbp), %rcx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
movl 0x18(%rax), %eax
movl %eax, -0x50(%rbp)
movq 0x1aac0351(%rip), %rax  # 0x1ab4cab0
movslq -0x18(%rbp), %rcx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
addq $0x1c, %rax
movq %rax, -0x58(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
movl $0x0, -0x68(%rbp)
movl -0x68(%rbp), %eax
cmpl -0x50(%rbp), %eax
jge 0x8c80a
movq -0x58(%rbp), %rax
movslq -0x68(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movswl (%rax), %eax
cmpl -0x30(%rbp), %eax
je 0x8c7fd
movq -0x58(%rbp), %rax
movslq -0x68(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movss 0x14(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
ucomisd -0x60(%rbp), %xmm0
jbe 0x8c7fb
movq -0x58(%rbp), %rax
movslq -0x68(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movss 0x14(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x60(%rbp)
movq -0x58(%rbp), %rax
movslq -0x68(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movswl (%rax), %eax
movl %eax, -0x64(%rbp)
jmp 0x8c7fd
jmp 0x8c7ff
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x8c78b
movl $0x0, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x44(%rbp), %eax
jge 0x8c867
movq -0x40(%rbp), %rax
movslq -0x6c(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movswl (%rax), %eax
cmpl -0x64(%rbp), %eax
jne 0x8c85a
movq -0x40(%rbp), %rax
movslq -0x6c(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
testb $0x1, 0x18(%rax)
jne 0x8c858
movq -0x40(%rbp), %rax
movslq -0x6c(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movb $0x1, 0x19(%rax)
jmp 0x8c867
jmp 0x8c85c
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x8c811
movl -0x2c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)