// File: /workspace/github_cpp_makefile_star2_O2/hantaoyin[P]ffxiv-crafting-mcts/ffxiv-crafting-mcts.C
// Function: Driver::simulate()
void simulate() {
    uct.reset(root_state);
    State s(root_state);
    std::vector<State> states;
    double score = 0.;

    const size_t size = training_data.size();
    ++simulate_count;
    bool track_simulation = simulate_count % 16 == 0;
    while(true) {
      if (s.done()) {
        LOG(track_simulation) << "Sample play: done, score = " << std::scientific << std::setprecision(3) << s.score() << "\n";
        score = s.score();
        break;
      }
      training_data.emplace_back(s, std::array<double, TotalActionCount>({}), 0.);
      for (size_t i = 0; i < SimulateCount; ++i) {
        uct.simulateFromState(s, track_simulation && i == SimulateCount - 1);
        // uct.simulateFromState(s, false);
      }
      // Select a move.
      Action ac = uct.select(s, inv_temp);
      LOG(track_simulation) << "Sample play: " << s.DebugString() << " ==> " << Action2Name(ac);
      if (ac == Action::NumActions) {
        LOG(track_simulation) << "Sample play: resigned.\n";
        break;
      } else {
        s.ExecuteAction(ac);
      }
    }

    for (size_t i = 0; i + size < training_data.size(); ++i) {
      auto& example = training_data[size + i];
      State& s = std::get<0>(example);
      uct.set_target_probability(s, inv_temp, std::get<1>(example));
      std::get<2>(example) = score;
    }
    while (training_data.size() > 10000) {
      training_data.pop_front();
    }
    LOG(track_simulation) << "Training data: has " << training_data.size() << " examples.";

    size_t example_id = random_real() * training_data.size();
    const auto& example = training_data[example_id];
    LOG(track_simulation) << "Training data: " << std::get<0>(example).DebugString() << " ==>";
    for (size_t i = 0; i < TotalActionCount; ++i) {
      LOG(track_simulation) << "Training data: " << std::setw(20) << std::setfill(' ')
          << Action2Name(static_cast<Action>(i)) << ": "
          << std::setfill('0') << std::scientific << std::setprecision(3) << std::get<1>(example)[i];
    }
    LOG(track_simulation) << "Training data: " << std::setfill(' ') << std::setw(20) << "Final score:"
        << std::scientific << std::setprecision(3) << std::get<2>(example);
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %rdi, %rbx
leaq 0x40(%rdi), %r15
leaq 0x9f0f(%rip), %rsi      # 0xc510
movq %r15, %rdi
callq 0x432e
movl 0x9f11(%rip), %eax      # 0xc520
leaq 0x30(%rsp), %r13
movl %eax, 0x10(%r13)
movupd 0x9ef0(%rip), %xmm0     # 0xc510
movapd %xmm0, (%r13)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x50(%rsp)
andq $0x0, 0x60(%rsp)
leaq 0x1b0(%rbx), %rdi
movq %rdi, 0x28(%rsp)
callq 0x5170
movq %rax, %r12
movq (%rbx), %r14
incq %r14
movq %rbx, 0x20(%rsp)
movq %r14, (%rbx)
movzwl 0x32(%rsp), %eax
cmpw $0x160c, %ax            # imm = 0x160C
jg 0x27a3
cmpw $0x0, 0x36(%rsp)
jle 0x27a3
movl $0xe8, %edx
leaq 0x70(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x20a0
andq $0x0, 0x48(%rsp)
movq 0x28(%rsp), %rdi
movq %r13, %rsi
movq %rbx, %rdx
leaq 0x48(%rsp), %rcx
callq 0x519e
movl $0x2710, %eax           # imm = 0x2710
movl $0x2710, %ebx           # imm = 0x2710
subq $0x1, %rbx
jb 0x26d4
movl %r14d, %ecx
andl $0xf, %ecx
xorq $0x1, %rax
xorl %edx, %edx
orq %rcx, %rax
sete %dl
movq %r15, %rdi
movq %r13, %rsi
callq 0x5212
movq %rbx, %rax
jmp 0x26ac
movq %r15, %rdi
movq %r13, %rsi
movsd 0x4936(%rip), %xmm0     # 0x7018
callq 0x56a4
movl %eax, %ebp
movzbl %al, %ebx
testb $0xf, %r14b
je 0x270b
cmpb $0x1d, %bpl
je 0x27b3
movq %r13, %rdi
movl %ebx, %esi
callq 0x5b0c
jmp 0x2658
movq 0x88c6(%rip), %rdi      # 0xafd8
leaq 0x4d86(%rip), %rsi      # 0x749f
callq 0x2170
movq %rax, 0x10(%rsp)
leaq 0x70(%rsp), %rdi
movq %r13, %rsi
callq 0x579e
movq 0x10(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x2140
movq %rax, %rdi
leaq 0x4d64(%rip), %rsi      # 0x74ad
callq 0x2170
movl %ebx, %ecx
shll $0x4, %ecx
leaq 0x8396(%rip), %rdx      # 0xaaf0
movq (%rcx,%rdx), %rsi
movq %rax, %rdi
callq 0x2170
leaq 0x70(%rsp), %rdi
callq 0x2070
leaq 0xe(%rsp), %rdi
callq 0x5180
cmpb $0x1d, %bpl
jne 0x26fc
movq 0x884d(%rip), %rdi      # 0xafd8
leaq 0x4d21(%rip), %rsi      # 0x74b3
callq 0x2170
leaq 0xd(%rsp), %rdi
callq 0x5180
jmp 0x27b3
testb $0xf, %r14b
je 0x2aea
cmpw $0x160d, %ax            # imm = 0x160D
jge 0x27b9
xorpd %xmm0, %xmm0
jmp 0x27ca
movswl 0x34(%rsp), %eax
cvtsi2sd %eax, %xmm0
divsd 0x4856(%rip), %xmm0     # 0x7020
movsd %xmm0, 0x10(%rsp)
addq $0x1c0, 0x20(%rsp)      # imm = 0x1C0
movq 0x28(%rsp), %rdi
callq 0x5170
cmpq %rax, %r12
jae 0x2822
movq 0x20(%rsp), %rdi
movq %r12, %rsi
callq 0x64b0
movq %rax, %rbx
leaq 0xf0(%rax), %rsi
leaq 0x8(%rax), %rdx
movq %r15, %rdi
movsd 0x480a(%rip), %xmm0     # 0x7018
callq 0x5b74
movsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rbx)
incq %r12
jmp 0x27d9
movq 0x28(%rsp), %r15
movq %r15, %rdi
callq 0x5170
cmpq $0x2711, %rax           # imm = 0x2711
jb 0x2841
movq %r15, %rdi
callq 0x5c56
jmp 0x2827
testb $0xf, %r14b
je 0x29c7
leaq 0x9ca6(%rip), %rdi      # 0xc4f8
callq 0x2508
movapd %xmm0, 0x10(%rsp)
movq %r15, %rdi
callq 0x5170
movq %rax, %xmm0
punpckldq 0x488e(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x4896(%rip), %xmm0     # 0x7110
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd 0x10(%rsp), %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x4784(%rip), %xmm0     # 0x7028
cvttsd2si %xmm0, %rsi
andq %rcx, %rsi
orq %rax, %rsi
movq 0x20(%rsp), %rdi
callq 0x64b0
movq %rax, %rbp
testb $0xf, %r14b
je 0x2a0e
movq %rbp, %rbx
addq $0x8, %rbx
xorl %r12d, %r12d
movq 0x8701(%rip), %rdi      # 0xafd8
leaq 0x4c0c(%rip), %rsi      # 0x74ea
pushq $0x30
popq %r13
leaq 0xa(%rsp), %r15
cmpq $0x1d0, %r12            # imm = 0x1D0
je 0x29a1
testb $0xf, %r14b
je 0x2904
addq $0x10, %r12
addq $0x8, %rbx
jmp 0x28e7
callq 0x2170
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0x14, 0x10(%rax,%rcx)
movq %rax, %rdi
pushq $0x20
popq %rsi
callq 0x21f0
leaq 0x81c5(%rip), %rcx      # 0xaaf0
movq (%r12,%rcx), %rsi
movq %rax, %rdi
callq 0x2170
movq %rax, %rdi
leaq 0x4cf3(%rip), %rsi      # 0x7634
callq 0x2170
movq %rax, %rdi
movl %r13d, %esi
callq 0x21f0
movq (%rax), %rcx
movq -0x18(%rcx), %rdx
movl 0x18(%rax,%rdx), %esi
movl $0xfffffefb, %edi       # imm = 0xFFFFFEFB
andl %edi, %esi
orl $0x100, %esi            # imm = 0x100
movl %esi, 0x18(%rax,%rdx)
movq -0x18(%rcx), %rcx
movq $0x3, 0x8(%rax,%rcx)
movsd (%rbx), %xmm0
movq %rax, %rdi
callq 0x2210
movq %r15, %rdi
callq 0x5180
movq 0x8643(%rip), %rdi      # 0xafd8
leaq 0x4b4e(%rip), %rsi      # 0x74ea
jmp 0x28fa
testb $0xf, %r14b
je 0x2a6a
leaq 0x50(%rsp), %rdi
callq 0x6572
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x860a(%rip), %rdi      # 0xafd8
leaq 0x4af6(%rip), %rsi      # 0x74cb
callq 0x2170
movq %rax, %rbx
movq %r15, %rdi
callq 0x5170
movq %rbx, %rdi
movq %rax, %rsi
callq 0x20b0
leaq 0x4ae8(%rip), %rsi      # 0x74df
movq %rax, %rdi
callq 0x2170
leaq 0xc(%rsp), %rdi
callq 0x5180
jmp 0x284b
movq 0x85c3(%rip), %rdi      # 0xafd8
leaq 0x4ace(%rip), %rsi      # 0x74ea
callq 0x2170
movq %rax, %r15
leaq 0xf0(%rbp), %rsi
leaq 0x70(%rsp), %rdi
callq 0x579e
leaq 0x70(%rsp), %rsi
movq %r15, %rdi
callq 0x2140
leaq 0x4ab1(%rip), %rsi      # 0x74fa
movq %rax, %rdi
callq 0x2170
leaq 0x70(%rsp), %rdi
callq 0x2070
leaq 0xb(%rsp), %rdi
callq 0x5180
jmp 0x28c6
movq 0x8567(%rip), %rdi      # 0xafd8
leaq 0x4a72(%rip), %rsi      # 0x74ea
callq 0x2170
pushq $0x20
popq %rsi
movq %rax, %rdi
callq 0x21f0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0x14, 0x10(%rax,%rcx)
leaq 0x4a60(%rip), %rsi      # 0x74ff
movq %rax, %rdi
callq 0x2170
movq (%rax), %rcx
movq -0x18(%rcx), %rdx
movl $0xfffffefb, %esi       # imm = 0xFFFFFEFB
andl 0x18(%rax,%rdx), %esi
orl $0x100, %esi            # imm = 0x100
movl %esi, 0x18(%rax,%rdx)
movq -0x18(%rcx), %rcx
movq $0x3, 0x8(%rax,%rcx)
movsd (%rbp), %xmm0
movq %rax, %rdi
callq 0x2210
leaq 0x9(%rsp), %rdi
callq 0x5180
jmp 0x29ab
movq 0x84e7(%rip), %rdi      # 0xafd8
leaq 0x498b(%rip), %rsi      # 0x7483
callq 0x2170
movq (%rax), %rcx
movq -0x18(%rcx), %rdx
movl $0xfffffefb, %esi       # imm = 0xFFFFFEFB
andl 0x18(%rax,%rdx), %esi
orl $0x100, %esi            # imm = 0x100
movl %esi, 0x18(%rax,%rdx)
movq -0x18(%rcx), %rcx
movq $0x3, 0x8(%rax,%rcx)
cmpw $0x160d, 0x32(%rsp)     # imm = 0x160D
jge 0x2b33
xorpd %xmm0, %xmm0
jmp 0x2b44
movswl 0x34(%rsp), %ecx
cvtsi2sd %ecx, %xmm0
divsd 0x44dc(%rip), %xmm0     # 0x7020
movq %rax, %rdi
callq 0x2210
leaq 0x4976(%rip), %rsi      # 0x74c9
movq %rax, %rdi
callq 0x2170
leaq 0xf(%rsp), %rdi
callq 0x5180
movzwl 0x32(%rsp), %eax
jmp 0x27ad
movq %rax, %rbx
leaq 0xd(%rsp), %rdi
jmp 0x2bd5
jmp 0x2b7b
movq %rax, %rbx
jmp 0x2b97
movq %rax, %rbx
leaq 0xf(%rsp), %rdi
jmp 0x2bd5
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x2070
leaq 0xb(%rsp), %rdi
jmp 0x2bd5
movq %rax, %rbx
leaq 0xc(%rsp), %rdi
jmp 0x2bd5
movq %rax, %rbx
leaq 0x9(%rsp), %rdi
jmp 0x2bd5
jmp 0x2bb4
movq %rax, %rbx
jmp 0x2bc6
movq %rax, %rbx
leaq 0x70(%rsp), %rdi
callq 0x2070
leaq 0xe(%rsp), %rdi
jmp 0x2bd5
movq %rax, %rbx
leaq 0xa(%rsp), %rdi
callq 0x5180
jmp 0x2be7
jmp 0x2be4
jmp 0x2be4
jmp 0x2be4
jmp 0x2be4
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x6572
movq %rbx, %rdi
callq 0x2270
nop