// File: kobanium[P]Ray/src/mcts/UctSearch.cpp
// Function: ExpandRoot(game_info_t*, int)
static int
ExpandRoot( game_info_t *game, int color )
{
  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;
  bool ladder[BOARD_MAX] = { false };

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

  // 9路盤でなければシチョウを調べる  
  if (pure_board_size != 9) {
    LadderExtension(game, color, ladder);
  }

  // 既に展開されていた時は, 探索結果を再利用する
  if (index != uct_hash_size) {
    std::vector<int> indexes;

    // 現局面の子ノード以外を削除する
    CorrectDescendentNodes(indexes, index);
    std::sort(indexes.begin(), indexes.end());
    ClearNotDescendentNodes(indexes);
    
    // 直前と2手前の着手を更新
    uct_node[index].previous_move1 = pm1;
    uct_node[index].previous_move2 = pm2;

    ReuseRootCandidateWithoutLadderMove(uct_node[index], ladder);

    // 展開されたノード数を1に初期化
    uct_node[index].width = 1;

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

    PrintReuseCount(uct_node[index].move_count);

    return index;
  } else {
    // 全ノードのクリア
    ClearUctHash();
    
    // 空のインデックスを探す
    index = SearchEmptyIndex(hash, color, moves);

    assert(index != uct_hash_size);    
    
    // ルートノードの初期化
    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, ladder[PASS]);
    
    // 候補手の展開
    if (moves == 1) {
      for (int i = 0; i < first_move_candidates; i++) {
        const int pos = first_move_candidate[i];
        // 探索候補かつ合法手であれば探索対象にする
        if (candidates[pos] && IsLegal(game, pos, color)) {
          InitializeCandidate(uct_child[child_num], child_num, pos, ladder[pos]);
        }
      }
    } else {
      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, ladder[pos]);
        }
      }
    }
    
    // 子ノード個数の設定
    uct_node[index].child_num = child_num;
    
    // 候補手のレーティング
    RatingNode(game, color, index);

    // セキの確認
    CheckSeki(game, uct_node[index].seki);
    
    uct_node[index].width++;
  }

  return index;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3f0, %rsp            # imm = 0x3F0
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rax
movl 0x43b0(%rax), %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x43f0(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
callq 0x9fc90
movl %eax, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
leaq -0x380(%rbp), %rdi
xorl %esi, %esi
movl $0x349, %edx            # imm = 0x349
callq 0x72b0
movq -0x10(%rbp), %rax
movl -0x18(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x28(%rbp)
cmpl $0x1, -0x18(%rbp)
jle 0x899cb
movq -0x10(%rbp), %rax
movl -0x18(%rbp), %ecx
subl $0x2, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0x2c(%rbp)
leaq 0x5e072(%rip), %rax     # 0xe7a44
cmpl $0x9, (%rax)
je 0x899ea
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
leaq -0x380(%rbp), %rdx
callq 0xaa650
movl -0x24(%rbp), %eax
leaq 0x5e06c(%rip), %rcx     # 0xe7a60
cmpl (%rcx), %eax
je 0x89b49
leaq -0x398(%rbp), %rdi
movq %rdi, -0x3e0(%rbp)
callq 0x56040
movq -0x3e0(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x8b210
jmp 0x89a20
leaq -0x398(%rbp), %rdi
movq %rdi, -0x3e8(%rbp)
callq 0x558e0
movq -0x3e8(%rbp), %rdi
movq %rax, -0x3b0(%rbp)
callq 0x55910
movq %rax, -0x3b8(%rbp)
movq -0x3b0(%rbp), %rdi
movq -0x3b8(%rbp), %rsi
callq 0x8d0e0
jmp 0x89a62
leaq -0x398(%rbp), %rdi
callq 0x9f970
jmp 0x89a70
movl -0x28(%rbp), %edx
movq 0x1aac3036(%rip), %rax  # 0x1ab4cab0
movl -0x24(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
movl %edx, (%rax,%rcx)
movl -0x2c(%rbp), %edx
movq 0x1aac301f(%rip), %rax  # 0x1ab4cab0
movl -0x24(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
movl %edx, 0x4(%rax,%rcx)
movq 0x1aac300a(%rip), %rdi  # 0x1ab4cab0
movl -0x24(%rbp), %eax
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rdi
leaq -0x380(%rbp), %rsi
callq 0x88100
jmp 0x89ac1
movq 0x1aac2fe8(%rip), %rax  # 0x1ab4cab0
movl -0x24(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
movl $0x1, 0x14(%rax,%rcx)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x24(%rbp), %edx
callq 0x8b2c0
jmp 0x89aeb
movq 0x1aac2fbe(%rip), %rax  # 0x1ab4cab0
movl -0x24(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
leaq 0x8(%rax,%rcx), %rdi
callq 0x25780
movl %eax, %edi
callq 0x22380
jmp 0x89b0f
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
leaq -0x398(%rbp), %rdi
callq 0x2d610
jmp 0x89df7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x3a0(%rbp)
movl %eax, -0x3a4(%rbp)
leaq -0x398(%rbp), %rdi
callq 0x2d610
jmp 0x89e03
callq 0x9f8d0
movq -0x20(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
callq 0x9fb80
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
leaq 0x5def6(%rip), %rcx     # 0xe7a60
cmpl (%rcx), %eax
je 0x89b70
jmp 0x89b8f
leaq 0x2566a(%rip), %rdi     # 0xaf1e1
leaq 0x2567a(%rip), %rsi     # 0xaf1f8
movl $0x2da, %edx            # imm = 0x2DA
leaq 0x25685(%rip), %rcx     # 0xaf20f
callq 0x7350
movq 0x1aac2f1a(%rip), %rdi  # 0x1ab4cab0
movl -0x24(%rbp), %eax
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rdi
movl -0x28(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x87ef0
movq 0x1aac2efb(%rip), %rax  # 0x1ab4cab0
movl -0x24(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
addq $0x1c, %rax
movq %rax, -0x3c0(%rbp)
movl $0x0, -0x3c4(%rbp)
movq -0x3c0(%rbp), %rdi
movb -0x380(%rbp), %al
leaq -0x3c4(%rbp), %rsi
xorl %edx, %edx
andb $0x1, %al
movzbl %al, %ecx
callq 0x87fa0
cmpl $0x1, -0x18(%rbp)
jne 0x89cb8
movl $0x0, -0x3c8(%rbp)
movl -0x3c8(%rbp), %eax
leaq 0x1aaf4468(%rip), %rcx  # 0x1ab7e080
cmpl (%rcx), %eax
jge 0x89cb3
movslq -0x3c8(%rbp), %rcx
leaq 0x1ab491f2(%rip), %rax  # 0x1abd2e20
movl (%rax,%rcx,4), %eax
movl %eax, -0x3cc(%rbp)
movslq -0x3cc(%rbp), %rcx
leaq 0x1aaecdbb(%rip), %rax  # 0x1ab76a00
testb $0x1, (%rax,%rcx)
je 0x89c9d
movq -0x10(%rbp), %rdi
movl -0x3cc(%rbp), %esi
movl -0x14(%rbp), %edx
callq 0x9d0b0
testb $0x1, %al
jne 0x89c63
jmp 0x89c9d
movq -0x3c0(%rbp), %rdi
movslq -0x3c4(%rbp), %rax
imulq $0x1c, %rax, %rax
addq %rax, %rdi
movl -0x3cc(%rbp), %edx
movslq -0x3cc(%rbp), %rax
movb -0x380(%rbp,%rax), %al
leaq -0x3c4(%rbp), %rsi
andb $0x1, %al
movzbl %al, %ecx
callq 0x87fa0
jmp 0x89c9f
movl -0x3c8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c8(%rbp)
jmp 0x89c0b
jmp 0x89d84
movl $0x0, -0x3d0(%rbp)
movl -0x3d0(%rbp), %eax
leaq 0x5dd71(%rip), %rcx     # 0xe7a40
cmpl (%rcx), %eax
jge 0x89d82
movslq -0x3d0(%rbp), %rcx
leaq 0x1ab48b8b(%rip), %rax  # 0x1abd2870
movl (%rax,%rcx,4), %eax
movl %eax, -0x3d4(%rbp)
movslq -0x3d4(%rbp), %rcx
leaq 0x1aaecd04(%rip), %rax  # 0x1ab76a00
testb $0x1, (%rax,%rcx)
je 0x89d6c
movq -0x10(%rbp), %rdi
movl -0x3d4(%rbp), %esi
movl -0x14(%rbp), %edx
callq 0x9d0b0
testb $0x1, %al
jne 0x89d1a
jmp 0x89d6c
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x3d4(%rbp), %edx
callq 0xa98d0
testb $0x1, %al
jne 0x89d32
jmp 0x89d6c
movq -0x3c0(%rbp), %rdi
movslq -0x3c4(%rbp), %rax
imulq $0x1c, %rax, %rax
addq %rax, %rdi
movl -0x3d4(%rbp), %edx
movslq -0x3d4(%rbp), %rax
movb -0x380(%rbp,%rax), %al
leaq -0x3c4(%rbp), %rsi
andb $0x1, %al
movzbl %al, %ecx
callq 0x87fa0
jmp 0x89d6e
movl -0x3d0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3d0(%rbp)
jmp 0x89cc2
jmp 0x89d84
movl -0x3c4(%rbp), %ecx
movq 0x1aac2d1f(%rip), %rax  # 0x1ab4cab0
movl -0x24(%rbp), %edx
imulq $0x4548, %rdx, %rdx     # imm = 0x4548
addq %rdx, %rax
movl %ecx, 0x18(%rax)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x24(%rbp), %edx
callq 0x8b2c0
movq -0x10(%rbp), %rdi
movq 0x1aac2cf5(%rip), %rsi  # 0x1ab4cab0
movl -0x24(%rbp), %eax
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rsi
addq $0x27b4, %rsi           # imm = 0x27B4
callq 0xa00f0
movq 0x1aac2cd5(%rip), %rax  # 0x1ab4cab0
movl -0x24(%rbp), %ecx
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
movl 0x14(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x14(%rax)
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x3f0, %rsp            # imm = 0x3F0
popq %rbp
retq
movq -0x3a0(%rbp), %rdi
callq 0x79b0
nop