// File: antoniogarro[P]Hara/engine.cpp
// Function: Engine::generate_move(bool)
int Engine::generate_move(bool early_pass)
{
  const int EXPAND = 8;
  const double RESIGN_THRESHOLD = 0.10, PASS_THRESHOLD = 0.90;
  
  bool side = main_goban->get_side();
  Node *root = tree.get_root();
  rand_movs = 0, discarded = 0;
  fin_clock = clock();

  while (root->get_visits() < max_playouts && clock() - fin_clock < max_time) {
    Node *node_history[3*MAXSIZE2];
    int nnode_hist = 0, pass = 0;
    simul_len = 0;
    amaf.set_up(main_goban->get_side(), main_goban->get_size());
    Node *node = root;
    while (node->has_childs() && pass < 2) {
      node_history[nnode_hist++] = node;
      node = node->select_child();
      int move = node->get_move();
      if(move == Goban::PASS) pass++;
      else pass = 0;
      main_goban->play_move(move);
      amaf.play(move, ++simul_len);
    }
    if (node->get_visits() >= EXPAND || node == root) {
      Prior priors[MAXSIZE2+1] = {{0,0}};
      int legal_moves[MAXSIZE2+1];
      int nlegal = main_goban->legal_moves(legal_moves);
      //main_goban->init_priors(priors);
      tree.expand(node, legal_moves, nlegal, priors); //TODO: break if expand fails.
    }
    node_history[nnode_hist++] = node;
    int result = play_random_game(HEAVY); //Black wins.
#ifdef DEBUG_INFO
      main_goban->print_goban();
      std::cerr << result << "\n";
#endif
    main_goban->restore();
    if (result == -1) continue;
    if (side) result = 1-result;    
    back_up_results(result, node_history, nnode_hist, side);
#ifdef DEBUG_INFO
      tree.print();
#endif
  }
  Node *best = tree.get_best();
  print_PV();
  if (best->get_move() == Goban::PASS) return Goban::PASS;
  if (best->get_value(1) < RESIGN_THRESHOLD) return -1;
  if (early_pass && best->get_value(1) >= PASS_THRESHOLD && !root->get_move()) return Goban::PASS;
  return best->get_move();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3eb0, %rsp           # imm = 0x3EB0
movb %sil, %al
movq %rdi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x3e98(%rbp)
movl $0x8, -0x18(%rbp)
movsd 0x10397(%rip), %xmm0    # 0x14018
movsd %xmm0, -0x20(%rbp)
movsd 0x10382(%rip), %xmm0    # 0x14010
movsd %xmm0, -0x28(%rbp)
movq 0x8(%rax), %rdi
callq 0x45e0
movq -0x3e98(%rbp), %rdi
andb $0x1, %al
movb %al, -0x29(%rbp)
addq $0x28, %rdi
callq 0x46e0
movq %rax, %rcx
movq -0x3e98(%rbp), %rax
movq %rcx, -0x38(%rbp)
movl $0x0, 0x18(%rax)
movl $0x0, 0x20(%rax)
callq 0x3170
movq %rax, %rcx
movq -0x3e98(%rbp), %rax
movq %rcx, 0x600(%rax)
movq -0x38(%rbp), %rdi
callq 0x4700
movq -0x3e98(%rbp), %rax
movaps %xmm0, %xmm1
cvtsi2sdl 0x14(%rax), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
movb %al, -0x3e99(%rbp)
jbe 0x3d2c
callq 0x3170
movq -0x3e98(%rbp), %rcx
subq 0x600(%rcx), %rax
cmpq 0x608(%rcx), %rax
setl %al
movb %al, -0x3e99(%rbp)
movb -0x3e99(%rbp), %al
testb $0x1, %al
jne 0x3d3b
jmp 0x3fb6
movq -0x3e98(%rbp), %rax
movl $0x0, -0x2214(%rbp)
movl $0x0, -0x2218(%rbp)
movl $0x0, 0x1c(%rax)
movq %rax, %rcx
addq $0x50, %rcx
movq %rcx, -0x3ea8(%rbp)
movq 0x8(%rax), %rdi
callq 0x45e0
movb %al, %cl
movq -0x3e98(%rbp), %rax
movb %cl, -0x3e9a(%rbp)
movq 0x8(%rax), %rdi
callq 0x4530
movq -0x3ea8(%rbp), %rdi
movl %eax, %edx
movb -0x3e9a(%rbp), %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x45a0
movq -0x38(%rbp), %rax
movq %rax, -0x2220(%rbp)
movq -0x2220(%rbp), %rdi
callq 0x4720
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x3ea9(%rbp)
jne 0x3dce
jmp 0x3dde
cmpl $0x2, -0x2218(%rbp)
setl %al
movb %al, -0x3ea9(%rbp)
movb -0x3ea9(%rbp), %al
testb $0x1, %al
jne 0x3ded
jmp 0x3e95
movq -0x2220(%rbp), %rcx
movl -0x2214(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x2214(%rbp)
cltq
movq %rcx, -0x2210(%rbp,%rax,8)
movq -0x2220(%rbp), %rdi
callq 0x12130
movq %rax, -0x2220(%rbp)
movq -0x2220(%rbp), %rdi
callq 0x4740
movl %eax, -0x2224(%rbp)
cmpl $0x0, -0x2224(%rbp)
jne 0x3e4e
movl -0x2218(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2218(%rbp)
jmp 0x3e58
movl $0x0, -0x2218(%rbp)
movq -0x3e98(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x2224(%rbp), %esi
callq 0x6e80
movq -0x3e98(%rbp), %rax
movq %rax, %rdi
addq $0x50, %rdi
movl -0x2224(%rbp), %esi
movl 0x1c(%rax), %edx
addl $0x1, %edx
movl %edx, 0x1c(%rax)
callq 0x4630
jmp 0x3db1
movq -0x2220(%rbp), %rdi
callq 0x4700
movsd 0x1017f(%rip), %xmm1    # 0x14028
ucomisd %xmm1, %xmm0
jae 0x3ebc
movq -0x2220(%rbp), %rax
cmpq -0x38(%rbp), %rax
jne 0x3f17
leaq -0x38d0(%rbp), %rdi
xorl %esi, %esi
movl $0x16a0, %edx           # imm = 0x16A0
callq 0x3120
movq -0x3e98(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x3e80(%rbp), %rsi
callq 0x8270
movq -0x3e98(%rbp), %rdi
movl %eax, -0x3e84(%rbp)
addq $0x28, %rdi
movq -0x2220(%rbp), %rsi
leaq -0x3e80(%rbp), %rdx
movl -0x3e84(%rbp), %ecx
leaq -0x38d0(%rbp), %r8
callq 0x12c30
movq -0x3e98(%rbp), %rdi
movq -0x2220(%rbp), %rcx
movl -0x2214(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x2214(%rbp)
cltq
movq %rcx, -0x2210(%rbp,%rax,8)
movb (%rdi), %al
andb $0x1, %al
movzbl %al, %esi
callq 0x3b10
movl %eax, %ecx
movq -0x3e98(%rbp), %rax
movl %ecx, -0x3e88(%rbp)
movq 0x8(%rax), %rdi
callq 0x6540
cmpl $-0x1, -0x3e88(%rbp)
jne 0x3f72
jmp 0x3ce3
testb $0x1, -0x29(%rbp)
je 0x3f89
movl $0x1, %eax
subl -0x3e88(%rbp), %eax
movl %eax, -0x3e88(%rbp)
movq -0x3e98(%rbp), %rdi
movl -0x3e88(%rbp), %esi
leaq -0x2210(%rbp), %rdx
movl -0x2214(%rbp), %ecx
movb -0x29(%rbp), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x4080
jmp 0x3ce3
movq -0x3e98(%rbp), %rdi
addq $0x28, %rdi
callq 0x4750
movq -0x3e98(%rbp), %rdi
movq %rax, -0x3e90(%rbp)
callq 0x4120
movq -0x3e90(%rbp), %rdi
callq 0x4740
cmpl $0x0, %eax
jne 0x3ff3
movl $0x0, -0x4(%rbp)
jmp 0x406f
movq -0x3e90(%rbp), %rdi
movsd 0x1001e(%rip), %xmm0    # 0x14020
callq 0x11fe0
movaps %xmm0, %xmm1
movsd 0x10006(%rip), %xmm0    # 0x14018
ucomisd %xmm1, %xmm0
jbe 0x4021
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x406f
testb $0x1, -0x11(%rbp)
je 0x4060
movq -0x3e90(%rbp), %rdi
movsd 0xffea(%rip), %xmm0     # 0x14020
callq 0x11fe0
movsd 0xffcd(%rip), %xmm1     # 0x14010
ucomisd %xmm1, %xmm0
jb 0x4060
movq -0x38(%rbp), %rdi
callq 0x4740
cmpl $0x0, %eax
jne 0x4060
movl $0x0, -0x4(%rbp)
jmp 0x406f
movq -0x3e90(%rbp), %rdi
callq 0x4740
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x3eb0, %rsp           # imm = 0x3EB0
popq %rbp
retq
nopl (%rax,%rax)