// File: kobanium[P]Ray/src/mcts/UctSearch.cpp
// Function: UctSearchGenmoveCleanUp(game_info_t*, int)
int
UctSearchGenmoveCleanUp( game_info_t *game, int color )
{
  int pos;
  double wp;
  std::thread *worker[THREAD_MAX];

  for (int i = 0; i < board_max; i++) {
    statistic[i].clear();
  }
  statistic_count = 0;
  std::fill_n(criticality_index, board_max, 0); 
  for (int i = 0; i < board_max; i++) {
    criticality[i] = 0.0;
  }

  StartTimer();

  ResetPoCount();

  current_root = ExpandRoot(game, color);

  if (uct_node[current_root].child_num <= 1) {
    return PASS;
  }

  for (int i = 0; i < pure_board_max; i++) {
    pos = onboard_pos[i];
    owner[pos] = 50.0;
  }

  SetPoHalt(GetPoNum());

  DynamicKomi(game, &uct_node[current_root], color);

  for (int i = 0; i < threads; i++) {
    t_arg[i].thread_id = i;
    t_arg[i].game = game;
    t_arg[i].color = color;
    t_arg[i].lz_analysis_cs = -1;
    worker[i] = new std::thread(ParallelUctSearch, &t_arg[i]);
  }

  for (int i = 0; i < threads; i++) {
    worker[i]->join();
    delete worker[i];
  }

  child_node_t *uct_child = uct_node[current_root].child;

  const int select_index = SelectMaxVisitChild(uct_node[current_root]);

  const double finish_time = CalculateElapsedTime();

  wp = (double)uct_node[current_root].win / uct_node[current_root].move_count;

  const int po_speed = static_cast<int>(CalculatePlayoutSpeed(finish_time, threads));

  PrintPlayoutInformation(&uct_node[current_root], po_speed, finish_time, 0);
  PrintOwner(&uct_node[current_root], statistic, color, statistic_count.load(), owner);

  PrintBestSequence(game, uct_node, current_root, color);

  CalculateNextPlayouts(game, color, wp, finish_time, threads);

  int count = 0;

  for (int i = 0; i < pure_board_max; i++) {
    pos = onboard_pos[i];

    if (owner[pos] >= 5 && owner[pos] <= 95) {
      candidates[pos] = true;
      count++;
    } else {
      candidates[pos] = false;
    }
  }

  if (count == 0) {
    pos = PASS;
  } else {
    pos = uct_child[select_index].pos;
  }
  
  if (static_cast<double>(uct_child[select_index].win) / uct_child[select_index].move_count < RESIGN_THRESHOLD) {
    return PASS;
  } else {
    return pos;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rdi, -0x20(%rbp)
movl %esi, -0x24(%rbp)
movl $0x0, -0x234(%rbp)
movl -0x234(%rbp), %eax
leaq 0x5ce9f(%rip), %rcx     # 0xe7a48
cmpl (%rcx), %eax
jge 0x8abd8
movslq -0x234(%rbp), %rax
leaq 0x1aaec395(%rip), %rdi  # 0x1ab76f50
shlq $0x4, %rax
addq %rax, %rdi
callq 0x8cf10
movl -0x234(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x234(%rbp)
jmp 0x8ab9c
leaq 0x1aaef801(%rip), %rdi  # 0x1ab7a3e0
xorl %esi, %esi
callq 0x88450
leaq 0x5ce5b(%rip), %rax     # 0xe7a48
movl (%rax), %esi
movl $0x0, -0x238(%rbp)
leaq 0x1aaef7f0(%rip), %rdi  # 0x1ab7a3f0
leaq -0x238(%rbp), %rdx
callq 0x80790
movl $0x0, -0x23c(%rbp)
movl -0x23c(%rbp), %eax
leaq 0x5ce25(%rip), %rcx     # 0xe7a48
cmpl (%rcx), %eax
jge 0x8ac4e
movslq -0x23c(%rbp), %rcx
leaq 0x1aaf04eb(%rip), %rax  # 0x1ab7b120
xorps %xmm0, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl -0x23c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x23c(%rbp)
jmp 0x8ac16
callq 0x8f7d0
callq 0x8f880
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x89930
movl %eax, 0x1aac1e4e(%rip)  # 0x1ab4cab8
movq 0x1aac1e3f(%rip), %rax  # 0x1ab4cab0
movslq 0x1aac1e40(%rip), %rcx  # 0x1ab4cab8
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
cmpl $0x1, 0x18(%rax)
jg 0x8ac94
movl $0x0, -0x18(%rbp)
jmp 0x8b1ef
movl $0x0, -0x240(%rbp)
movl -0x240(%rbp), %eax
leaq 0x5cd95(%rip), %rcx     # 0xe7a40
cmpl (%rcx), %eax
jge 0x8acec
movslq -0x240(%rbp), %rcx
leaq 0x1ab47bb3(%rip), %rax  # 0x1abd2870
movl (%rax,%rcx,4), %eax
movl %eax, -0x28(%rbp)
movslq -0x28(%rbp), %rcx
leaq 0x1aae95b2(%rip), %rax  # 0x1ab74280
movsd 0x24492(%rip), %xmm0    # 0xaf168
movsd %xmm0, (%rax,%rcx,8)
movl -0x240(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x240(%rbp)
jmp 0x8ac9e
callq 0x8f8d0
movl %eax, %edi
callq 0x8f910
movq -0x20(%rbp), %rdi
movq 0x1aac1dad(%rip), %rsi  # 0x1ab4cab0
movslq 0x1aac1dae(%rip), %rax  # 0x1ab4cab8
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rsi
movl -0x24(%rbp), %edx
callq 0x9fe50
movl $0x0, -0x244(%rbp)
movl -0x244(%rbp), %eax
cmpl 0x5ccce(%rip), %eax     # 0xe7a00
jge 0x8ae2a
movslq -0x244(%rbp), %rax
movl %eax, %edx
leaq (%rax,%rax,2), %rcx
leaq 0x1aaf1e24(%rip), %rax  # 0x1ab7cb70
movq %rax, -0x298(%rbp)
movl %edx, 0x8(%rax,%rcx,8)
movq -0x20(%rbp), %rdx
movslq -0x244(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x24(%rbp), %edx
movslq -0x244(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
movl %edx, 0xc(%rax,%rcx,8)
movslq -0x244(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
movl $0xffffffff, 0x10(%rax,%rcx,8) # imm = 0xFFFFFFFF
movl $0x8, %edi
callq 0x7550
movq %rax, %rdi
movq -0x298(%rbp), %rax
movq %rdi, %rcx
movq %rcx, -0x290(%rbp)
movslq -0x244(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, -0x250(%rbp)
leaq -0xfba(%rip), %rsi      # 0x89e10
leaq -0x250(%rbp), %rdx
callq 0x8cf60
jmp 0x8add8
movq -0x290(%rbp), %rcx
movslq -0x244(%rbp), %rax
movq %rcx, -0x230(%rbp,%rax,8)
movl -0x244(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x244(%rbp)
jmp 0x8ad26
movq -0x290(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x258(%rbp)
movl %eax, -0x25c(%rbp)
movl $0x8, %esi
callq 0x7560
jmp 0x8b1fb
movl $0x0, -0x260(%rbp)
movl -0x260(%rbp), %eax
cmpl 0x5cbc0(%rip), %eax     # 0xe7a00
jge 0x8aea2
movslq -0x260(%rbp), %rax
movq -0x230(%rbp,%rax,8), %rdi
callq 0x7940
movslq -0x260(%rbp), %rax
movq -0x230(%rbp,%rax,8), %rax
movq %rax, -0x2a0(%rbp)
cmpq $0x0, %rax
je 0x8ae8f
movq -0x2a0(%rbp), %rdi
callq 0x66080
movq -0x2a0(%rbp), %rdi
movl $0x8, %esi
callq 0x7560
jmp 0x8ae91
movl -0x260(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x260(%rbp)
jmp 0x8ae34
movq 0x1aac1c07(%rip), %rax  # 0x1ab4cab0
movslq 0x1aac1c08(%rip), %rcx  # 0x1ab4cab8
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
leaq 0x1c(%rax,%rcx), %rax
movq %rax, -0x268(%rbp)
movq 0x1aac1be6(%rip), %rdi  # 0x1ab4cab0
movslq 0x1aac1be7(%rip), %rax  # 0x1ab4cab8
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rdi
callq 0x8ece0
movl %eax, -0x26c(%rbp)
callq 0x8f800
movsd %xmm0, -0x278(%rbp)
movq 0x1aac1bb6(%rip), %rax  # 0x1ab4cab0
movslq 0x1aac1bb7(%rip), %rcx  # 0x1ab4cab8
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
leaq 0xc(%rax,%rcx), %rdi
callq 0x25780
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x2c8(%rbp)
movq 0x1aac1b8b(%rip), %rax  # 0x1ab4cab0
movslq 0x1aac1b8c(%rip), %rcx  # 0x1ab4cab8
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
leaq 0x8(%rax,%rcx), %rdi
callq 0x25780
movsd -0x2c8(%rbp), %xmm0
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rbp)
movsd -0x278(%rbp), %xmm0
movl 0x5caa0(%rip), %edi     # 0xe7a00
callq 0x8f770
cvttsd2si %xmm0, %eax
movl %eax, -0x27c(%rbp)
movq 0x1aac1b3a(%rip), %rdi  # 0x1ab4cab0
movslq 0x1aac1b3b(%rip), %rax  # 0x1ab4cab8
imulq $0x4548, %rax, %rax     # imm = 0x4548
addq %rax, %rdi
movl -0x27c(%rbp), %esi
movsd -0x278(%rbp), %xmm0
xorl %edx, %edx
callq 0x21ea0
movq 0x1aac1b0d(%rip), %rax  # 0x1ab4cab0
movslq 0x1aac1b0e(%rip), %rcx  # 0x1ab4cab8
imulq $0x4548, %rcx, %rcx     # imm = 0x4548
addq %rcx, %rax
movq %rax, -0x2c0(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x2b4(%rbp)
leaq 0x1aaef415(%rip), %rax  # 0x1ab7a3e0
movq %rax, -0x8(%rbp)
movl $0x5, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movl -0xc(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x25b00
movl %eax, -0x10(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x2a4(%rbp)
decl %eax
subl $0x2, %eax
jb 0x8b01e
jmp 0x8b003
movl -0x2a4(%rbp), %eax
subl $0x5, %eax
je 0x8b02c
jmp 0x8b010
movq -0x2b0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x14(%rbp)
jmp 0x8b038
movq -0x2b0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x14(%rbp)
jmp 0x8b038
movq -0x2b0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x14(%rbp)
movl -0x2b4(%rbp), %edx
movq -0x2c0(%rbp), %rdi
movl -0x14(%rbp), %ecx
leaq 0x1aaebf01(%rip), %rsi  # 0x1ab76f50
leaq 0x1aae922a(%rip), %r8   # 0x1ab74280
callq 0x211f0
movq -0x20(%rbp), %rdi
movq 0x1aac1a4a(%rip), %rsi  # 0x1ab4cab0
movl 0x1aac1a4c(%rip), %edx  # 0x1ab4cab8
movl -0x24(%rbp), %ecx
callq 0x21960
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
movsd -0x30(%rbp), %xmm0
movsd -0x278(%rbp), %xmm1
movl 0x5c972(%rip), %edx     # 0xe7a00
callq 0x8f420
movl $0x0, -0x280(%rbp)
movl $0x0, -0x284(%rbp)
movl -0x284(%rbp), %eax
leaq 0x5c98c(%rip), %rcx     # 0xe7a40
cmpl (%rcx), %eax
jge 0x8b14d
movslq -0x284(%rbp), %rcx
leaq 0x1ab477a6(%rip), %rax  # 0x1abd2870
movl (%rax,%rcx,4), %eax
movl %eax, -0x28(%rbp)
movslq -0x28(%rbp), %rcx
leaq 0x1aae91a5(%rip), %rax  # 0x1ab74280
movsd (%rax,%rcx,8), %xmm0
movsd 0x22e40(%rip), %xmm1    # 0xadf28
ucomisd %xmm1, %xmm0
jb 0x8b128
movslq -0x28(%rbp), %rcx
movsd 0x24076(%rip), %xmm0    # 0xaf170
leaq 0x1aae917f(%rip), %rax  # 0x1ab74280
ucomisd (%rax,%rcx,8), %xmm0
jb 0x8b128
movslq -0x28(%rbp), %rcx
leaq 0x1aaeb8ed(%rip), %rax  # 0x1ab76a00
movb $0x1, (%rax,%rcx)
movl -0x280(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x280(%rbp)
jmp 0x8b137
movslq -0x28(%rbp), %rcx
leaq 0x1aaeb8cd(%rip), %rax  # 0x1ab76a00
movb $0x0, (%rax,%rcx)
jmp 0x8b139
movl -0x284(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x284(%rbp)
jmp 0x8b0a7
cmpl $0x0, -0x280(%rbp)
jne 0x8b15f
movl $0x0, -0x28(%rbp)
jmp 0x8b17a
movq -0x268(%rbp), %rax
movslq -0x26c(%rbp), %rcx
imulq $0x1c, %rcx, %rcx
addq %rcx, %rax
movswl (%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x268(%rbp), %rdi
movslq -0x26c(%rbp), %rax
imulq $0x1c, %rax, %rax
addq %rax, %rdi
addq $0xc, %rdi
callq 0x25780
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x2d0(%rbp)
movq -0x268(%rbp), %rdi
movslq -0x26c(%rbp), %rax
imulq $0x1c, %rax, %rax
addq %rax, %rdi
addq $0x4, %rdi
callq 0x25780
movsd -0x2d0(%rbp), %xmm1
cvtsi2sd %eax, %xmm0
divsd %xmm0, %xmm1
movsd 0x22d66(%rip), %xmm0    # 0xadf40
ucomisd %xmm1, %xmm0
jbe 0x8b1e9
movl $0x0, -0x18(%rbp)
jmp 0x8b1ef
movl -0x28(%rbp), %eax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
movq -0x258(%rbp), %rdi
callq 0x79b0
nopw (%rax,%rax)