// File: hantaoyin[P]ffxiv-crafting-mcts/ffxiv-crafting-mcts.C
// Function: UCT::simulateFromState(State const&, bool)
double simulateFromState(const State& s, bool track_simulation) {
    if (s.done()) {
      LOG(track_simulation) << s.DebugString() << ": (UCT)==> done " << s.score()
          << (s.successful() ? " <Finished>." : " <Failed>.");
      return s.score();
    }
    if (all_states.find(s) == all_states.end()) {
      double score = initState(s);
      LOG(track_simulation) << s.DebugString() << "\n(UCT)==> NN estimation = "
                            << std::scientific << std::setprecision(3) << score << ".";
      return score;
    }
    StateStatistics& stat = all_states.at(s);
    LOG(track_simulation) << s.DebugString() << "\n" << stat.DebugString();

    double ucb1_max = -std::numeric_limits<double>::infinity();
    Action ac_max = Action::NumActions;
    double nsq = std::sqrt((double)stat.total_count);
    for (size_t ac_id = 0; ac_id < TotalActionCount; ++ac_id) {
      Action ac = static_cast<Action>(ac_id);
      if(!stat.valid(ac)) continue;
      double u = stat.count(ac) == 0 ? 0. : stat.value(ac) / stat.count(ac);
      u += stat.prior(ac) * nsq / (1 + stat.count(ac));
      if (u > ucb1_max) {
        ucb1_max = u;
        ac_max = ac;
      }
    }
    if (ac_max == Action::NumActions) {
      LOG(track_simulation) << "(UCT)==> <Failed>.";
      ++stat.total_count;
      return 0.;
    } else {
      LOG(track_simulation) << "(UCT)==> picked " << Action2Name(ac_max) << ".";
    }

    State next(s);
    next.ExecuteAction(ac_max);
    double score = simulateFromState(next, track_simulation);
    stat.value(ac_max) += score;
    ++stat.count(ac_max);
    ++stat.total_count;
    return score;
  }

// Assembly:
subq $0x1e8, %rsp            # imm = 0x1E8
movb %dl, %al
movq %rdi, 0x1d8(%rsp)
movq %rsi, 0x1d0(%rsp)
andb $0x1, %al
movb %al, 0x1cf(%rsp)
movq 0x1d8(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x1d0(%rsp), %rdi
callq 0xd0f0
testb $0x1, %al
jne 0xe428
jmp 0xe5c0
movb 0x1cf(%rsp), %al
xorb $-0x1, %al
movb $0x0, 0x1cd(%rsp)
movb $0x0, 0x19b(%rsp)
testb $0x1, %al
jne 0xe447
jmp 0xe44c
jmp 0xe510
movb $0x1, 0x1cd(%rsp)
movq 0x1d0(%rsp), %rsi
leaq 0x1a8(%rsp), %rdi
callq 0xf010
jmp 0xe46b
movb $0x1, 0x19b(%rsp)
movq 0xdb5e(%rip), %rdi      # 0x1bfd8
leaq 0x1a8(%rsp), %rsi
callq 0x2140
movq %rax, 0x90(%rsp)
jmp 0xe491
movq 0x90(%rsp), %rdi
leaq 0x5090(%rip), %rsi      # 0x13530
callq 0x2180
movq %rax, 0x88(%rsp)
jmp 0xe4af
movq 0x1d0(%rsp), %rdi
callq 0xe2d0
movq 0x88(%rsp), %rdi
callq 0x22f0
movq %rax, 0x80(%rsp)
jmp 0xe4d3
movq 0x1d0(%rsp), %rdi
callq 0x10980
movb %al, 0x7f(%rsp)
jmp 0xe4e6
movq 0x80(%rsp), %rdi
movb 0x7f(%rsp), %cl
leaq 0x5048(%rip), %rax      # 0x13541
leaq 0x5071(%rip), %rsi      # 0x13571
testb $0x1, %cl
cmovneq %rax, %rsi
callq 0x2180
jmp 0xe50e
jmp 0xe510
testb $0x1, 0x19b(%rsp)
jne 0xe51c
jmp 0xe529
leaq 0x1a8(%rsp), %rdi
callq 0x20b0
testb $0x1, 0x1cd(%rsp)
jne 0xe535
jmp 0xe542
leaq 0x1ce(%rsp), %rdi
callq 0xe320
movq 0x1d0(%rsp), %rdi
callq 0xe2d0
movsd %xmm0, 0x1e0(%rsp)
jmp 0xee21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0xe5a2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
testb $0x1, 0x19b(%rsp)
jne 0xe593
jmp 0xe5a0
leaq 0x1a8(%rsp), %rdi
callq 0x20b0
jmp 0xe5a2
testb $0x1, 0x1cd(%rsp)
jne 0xe5ae
jmp 0xe5bb
leaq 0x1ce(%rsp), %rdi
callq 0xe320
jmp 0xee32
movq 0x98(%rsp), %rdi
addq $0x138, %rdi            # imm = 0x138
movq 0x1d0(%rsp), %rsi
callq 0x109c0
movq 0x98(%rsp), %rdi
movq %rax, 0x190(%rsp)
addq $0x138, %rdi            # imm = 0x138
callq 0x109f0
movq %rax, 0x188(%rsp)
leaq 0x190(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x109a0
testb $0x1, %al
jne 0xe61e
jmp 0xe7d6
movq 0x98(%rsp), %rdi
movq 0x1d0(%rsp), %rsi
callq 0xa750
movsd %xmm0, 0x180(%rsp)
movb 0x1cf(%rsp), %al
xorb $-0x1, %al
movb $0x0, 0x17e(%rsp)
movb $0x0, 0x157(%rsp)
testb $0x1, %al
jne 0xe65b
jmp 0xe660
jmp 0xe72a
movb $0x1, 0x17e(%rsp)
movq 0x1d0(%rsp), %rsi
leaq 0x158(%rsp), %rdi
callq 0xf010
jmp 0xe67f
movb $0x1, 0x157(%rsp)
movq 0xd94a(%rip), %rdi      # 0x1bfd8
leaq 0x158(%rsp), %rsi
callq 0x2140
movq %rax, 0x70(%rsp)
jmp 0xe6a2
movq 0x70(%rsp), %rdi
leaq 0x4ea0(%rip), %rsi      # 0x1354e
callq 0x2180
movq %rax, 0x68(%rsp)
jmp 0xe6ba
movq 0x68(%rsp), %rdi
leaq -0x436(%rip), %rsi      # 0xe290
callq 0x2050
movq %rax, 0x60(%rsp)
jmp 0xe6d2
movl $0x3, %edi
callq 0xe2b0
movq 0x60(%rsp), %rdi
movl %eax, 0x150(%rsp)
movl 0x150(%rsp), %esi
callq 0x2250
movq %rax, 0x58(%rsp)
jmp 0xe6fb
movq 0x58(%rsp), %rdi
movsd 0x180(%rsp), %xmm0
callq 0x22f0
movq %rax, 0x50(%rsp)
jmp 0xe715
movq 0x50(%rsp), %rdi
leaq 0x4e2b(%rip), %rsi      # 0x1354c
callq 0x2180
jmp 0xe728
jmp 0xe72a
testb $0x1, 0x157(%rsp)
jne 0xe736
jmp 0xe743
leaq 0x158(%rsp), %rdi
callq 0x20b0
testb $0x1, 0x17e(%rsp)
jne 0xe74f
jmp 0xe75c
leaq 0x17f(%rsp), %rdi
callq 0xe320
movsd 0x180(%rsp), %xmm0
movsd %xmm0, 0x1e0(%rsp)
jmp 0xee21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0xe7b8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
testb $0x1, 0x157(%rsp)
jne 0xe7a9
jmp 0xe7b6
leaq 0x158(%rsp), %rdi
callq 0x20b0
jmp 0xe7b8
testb $0x1, 0x17e(%rsp)
jne 0xe7c4
jmp 0xe7d1
leaq 0x17f(%rsp), %rdi
callq 0xe320
jmp 0xee32
movq 0x98(%rsp), %rdi
addq $0x138, %rdi            # imm = 0x138
movq 0x1d0(%rsp), %rsi
callq 0x10a20
movq %rax, 0x148(%rsp)
movb 0x1cf(%rsp), %al
xorb $-0x1, %al
movb $0x0, 0x146(%rsp)
movb $0x0, 0x11f(%rsp)
movb $0x0, 0xf7(%rsp)
testb $0x1, %al
jne 0xe821
jmp 0xe826
jmp 0xe8b5
movb $0x1, 0x146(%rsp)
movq 0x1d0(%rsp), %rsi
leaq 0x120(%rsp), %rdi
callq 0xf010
jmp 0xe845
movb $0x1, 0x11f(%rsp)
movq 0xd784(%rip), %rdi      # 0x1bfd8
leaq 0x120(%rsp), %rsi
callq 0x2140
movq %rax, 0x48(%rsp)
jmp 0xe868
movq 0x48(%rsp), %rdi
leaq 0x4c49(%rip), %rsi      # 0x134bd
callq 0x2180
movq %rax, 0x40(%rsp)
jmp 0xe880
movq 0x148(%rsp), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x10a50
jmp 0xe897
movq 0x40(%rsp), %rdi
movb $0x1, 0xf7(%rsp)
leaq 0xf8(%rsp), %rsi
callq 0x2140
jmp 0xe8b3
jmp 0xe8b5
testb $0x1, 0xf7(%rsp)
jne 0xe8c1
jmp 0xe8ce
leaq 0xf8(%rsp), %rdi
callq 0x20b0
testb $0x1, 0x11f(%rsp)
jne 0xe8da
jmp 0xe8e7
leaq 0x120(%rsp), %rdi
callq 0x20b0
testb $0x1, 0x146(%rsp)
jne 0xe8f3
jmp 0xe900
leaq 0x147(%rsp), %rdi
callq 0xe320
callq 0x10f10
movaps 0x4844(%rip), %xmm1     # 0x13150
pxor %xmm1, %xmm0
movlpd %xmm0, 0xe8(%rsp)
movb $0x1d, 0xe7(%rsp)
movq 0x148(%rsp), %rax
movq 0x2b8(%rax), %xmm0
movaps 0x47f8(%rip), %xmm1     # 0x13130
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x47fc(%rip), %xmm1     # 0x13140
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
callq 0x2100
movsd %xmm0, 0xd8(%rsp)
movq $0x0, 0xd0(%rsp)
cmpq $0x1d, 0xd0(%rsp)
jae 0xebb9
movq 0xd0(%rsp), %rax
movb %al, 0xcf(%rsp)
movq 0x148(%rsp), %rdi
movzbl 0xcf(%rsp), %esi
callq 0x10f20
testb $0x1, %al
jne 0xea41
jmp 0xeba0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0xea23
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
jmp 0xea08
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
testb $0x1, 0xf7(%rsp)
jne 0xe9f9
jmp 0xea06
leaq 0xf8(%rsp), %rdi
callq 0x20b0
jmp 0xea08
testb $0x1, 0x11f(%rsp)
jne 0xea14
jmp 0xea21
leaq 0x120(%rsp), %rdi
callq 0x20b0
jmp 0xea23
testb $0x1, 0x146(%rsp)
jne 0xea2f
jmp 0xea3c
leaq 0x147(%rsp), %rdi
callq 0xe320
jmp 0xee32
movq 0x148(%rsp), %rdi
movzbl 0xcf(%rsp), %esi
callq 0xaea0
cmpq $0x0, (%rax)
jne 0xea67
xorps %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
jmp 0xead1
movq 0x148(%rsp), %rdi
movzbl 0xcf(%rsp), %esi
callq 0xaef0
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x148(%rsp), %rdi
movzbl 0xcf(%rsp), %esi
callq 0xaea0
movsd 0x30(%rsp), %xmm0
movq (%rax), %xmm1
movaps 0x4684(%rip), %xmm2     # 0x13130
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x4688(%rip), %xmm2     # 0x13140
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x38(%rsp), %xmm0
movsd %xmm0, 0xc0(%rsp)
movq 0x148(%rsp), %rdi
movzbl 0xcf(%rsp), %esi
callq 0xae50
movsd (%rax), %xmm0
movsd 0xd8(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x148(%rsp), %rdi
movzbl 0xcf(%rsp), %esi
callq 0xaea0
movsd 0x28(%rsp), %xmm0
movq (%rax), %rax
incq %rax
movq %rax, %xmm1
movaps 0x45f7(%rip), %xmm2     # 0x13130
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x45fb(%rip), %xmm2     # 0x13140
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
addsd 0xc0(%rsp), %xmm0
movsd %xmm0, 0xc0(%rsp)
movsd 0xc0(%rsp), %xmm0
ucomisd 0xe8(%rsp), %xmm0
jbe 0xeb9e
movsd 0xc0(%rsp), %xmm0
movsd %xmm0, 0xe8(%rsp)
movb 0xcf(%rsp), %al
movb %al, 0xe7(%rsp)
jmp 0xeba0
movq 0xd0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xd0(%rsp)
jmp 0xe96d
cmpb $0x1d, 0xe7(%rsp)
jne 0xec75
movb 0x1cf(%rsp), %al
xorb $-0x1, %al
movb $0x0, 0xbe(%rsp)
testb $0x1, %al
jne 0xebde
jmp 0xebe0
jmp 0xebff
movb $0x1, 0xbe(%rsp)
movq 0xd3e9(%rip), %rdi      # 0x1bfd8
leaq 0x4973(%rip), %rsi      # 0x13569
callq 0x2180
jmp 0xebfd
jmp 0xebff
testb $0x1, 0xbe(%rsp)
jne 0xec0b
jmp 0xec18
leaq 0xbf(%rsp), %rdi
callq 0xe320
movq 0x148(%rsp), %rax
movq 0x2b8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x2b8(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1e0(%rsp)
jmp 0xee21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
testb $0x1, 0xbe(%rsp)
jne 0xec63
jmp 0xec70
leaq 0xbf(%rsp), %rdi
callq 0xe320
jmp 0xee32
movb 0x1cf(%rsp), %al
xorb $-0x1, %al
movb $0x0, 0xbc(%rsp)
testb $0x1, %al
jne 0xec8c
jmp 0xec8e
jmp 0xecef
movb $0x1, 0xbc(%rsp)
movq 0xd33b(%rip), %rdi      # 0x1bfd8
leaq 0x48d8(%rip), %rsi      # 0x1357c
callq 0x2180
movq %rax, 0x20(%rsp)
jmp 0xecb0
movzbl 0xe7(%rsp), %edi
callq 0x2530
movq %rax, 0x18(%rsp)
jmp 0xecc4
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdi
callq 0x2180
movq %rax, 0x10(%rsp)
jmp 0xecda
movq 0x10(%rsp), %rdi
leaq 0x4866(%rip), %rsi      # 0x1354c
callq 0x2180
jmp 0xeced
jmp 0xecef
testb $0x1, 0xbc(%rsp)
jne 0xecfb
jmp 0xed08
leaq 0xbd(%rsp), %rdi
callq 0xe320
jmp 0xed3c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a0(%rsp)
movl %eax, 0x19c(%rsp)
testb $0x1, 0xbc(%rsp)
jne 0xed2a
jmp 0xed37
leaq 0xbd(%rsp), %rdi
callq 0xe320
jmp 0xee32
movq 0x1d0(%rsp), %rax
movq (%rax), %rcx
movq %rcx, 0xa8(%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0xb0(%rsp)
movl 0x10(%rax), %eax
movl %eax, 0xb8(%rsp)
leaq 0xa8(%rsp), %rdi
movzbl 0xe7(%rsp), %esi
callq 0xfa50
movq 0x98(%rsp), %rdi
movb 0x1cf(%rsp), %al
leaq 0xa8(%rsp), %rsi
andb $0x1, %al
movzbl %al, %edx
callq 0xe3e0
movsd %xmm0, 0xa0(%rsp)
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x148(%rsp), %rdi
movzbl 0xe7(%rsp), %esi
callq 0xaef0
movsd 0x8(%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, (%rax)
movq 0x148(%rsp), %rdi
movzbl 0xe7(%rsp), %esi
callq 0xaea0
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
movq 0x148(%rsp), %rax
movq 0x2b8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x2b8(%rax)
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x1e0(%rsp)
movsd 0x1e0(%rsp), %xmm0
addq $0x1e8, %rsp            # imm = 0x1E8
retq
movq 0x1a0(%rsp), %rdi
callq 0x22c0
nop