// File: /workspace/github_c_makefile_star2_O2/icarroll[P]clunk/mcts.c
// Function: mcts_step
double mcts_step(struct mctreenode * node) {
    curdepth += 1; if (curdepth > deepest) deepest = curdepth;

    node->visits += 1;
    visited += 1;   // count all nodes visited

    if (node->boardstate.captless > 10) {
        // terminal node, game over
        return (double) score_game(& node->boardstate);
    }

    double guess;
    if (node->unexplored_moves) {
        // some children remain unvisited, visit an unvisited child
        int ix = node->allmoves.used - node->unexplored_moves;
        node->unexplored_moves -= 1;

        struct mctreenode * child = & node->children[ix];

        struct thudboard board = node->boardstate;
        struct move move = node->allmoves.moves[ix];
        domove(& board, & move);

        initmctree(child, & board);

        guess = mcts_simulate(child);
        child->scoreguess = guess;
    }
    else {
        // all children visited at least once, pick most promising via UCB1
        int choice = 0;
        double value = ucb1(node->visits, & node->children[choice]);
        for (int ix=0 ; ix<node->allmoves.used ; ix+=1) {
            double tryvalue = ucb1(node->visits, & node->children[ix]);
            if (tryvalue > value) {
                choice = ix;
                value = tryvalue;
            }
        }

        guess = mcts_step(& node->children[choice]);
    }

    node->scoreguess = guess / node->visits
                       + node->scoreguess * (node->visits-1) / node->visits;

    curdepth -= 1;

    return guess;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rdi, %rbx
movl 0x4677(%rip), %ecx      # 0x8288
leal 0x1(%rcx), %eax
movl %eax, 0x466e(%rip)      # 0x8288
cmpl 0x466c(%rip), %ecx      # 0x828c
jl 0x3c28
movl %eax, 0x4664(%rip)      # 0x828c
movsd 0xa8(%rbx), %xmm0
addsd 0x1608(%rip), %xmm0     # 0x5240
movsd %xmm0, 0xa8(%rbx)
incl 0x464a(%rip)            # 0x8290
cmpl $0xb, 0x78(%rbx)
jl 0x3c5d
movq %rbx, %rdi
callq 0x3241
cvtsi2sd %eax, %xmm0
jmp 0x3d8b
movslq 0x90(%rbx), %rax
testq %rax, %rax
je 0x3ce0
movslq 0x80(%rbx), %rdx
subq %rax, %rdx
decl %eax
movl %eax, 0x90(%rbx)
movq 0x98(%rbx), %r12
imulq $0xb0, %rdx, %r13
leaq (%r12,%r13), %r14
pushq $0x10
popq %rcx
leaq 0x68(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
rep  movsq (%rsi), %es:(%rdi)
imulq $0x58, %rdx, %rsi
addq 0x88(%rbx), %rsi
pushq $0x16
popq %rcx
leaq 0x10(%rsp), %rax
movq %rax, %rdi
rep  movsl (%rsi), %es:(%rdi)
movq %r15, %rdi
movq %rax, %rsi
callq 0x1fa4
movq %r14, %rdi
movq %r15, %rsi
callq 0x3e34
movq %r14, %rdi
callq 0x3d9d
movsd %xmm0, 0xa0(%r12,%r13)
jmp 0x3d51
movq 0x98(%rbx), %rdi
callq 0x3da9
xorl %r14d, %r14d
xorl %r15d, %r15d
xorl %ebp, %ebp
movslq 0x80(%rbx), %rax
cmpq %rax, %r15
jge 0x3d3b
movsd %xmm0, 0x8(%rsp)
movsd 0xa8(%rbx), %xmm0
movq 0x98(%rbx), %rdi
addq %r14, %rdi
callq 0x3da9
movsd 0x8(%rsp), %xmm1
ucomisd %xmm1, %xmm0
cmoval %r15d, %ebp
maxsd %xmm1, %xmm0
incq %r15
addq $0xb0, %r14
jmp 0x3cf4
movslq %ebp, %rax
imulq $0xb0, %rax, %rdi
addq 0x98(%rbx), %rdi
callq 0x3bf7
movsd 0xa8(%rbx), %xmm1
movapd %xmm0, %xmm2
divsd %xmm1, %xmm2
movsd 0x14df(%rip), %xmm3     # 0x5248
addsd %xmm1, %xmm3
mulsd 0xa0(%rbx), %xmm3
divsd %xmm1, %xmm3
addsd %xmm2, %xmm3
movsd %xmm3, 0xa0(%rbx)
decl 0x44fd(%rip)            # 0x8288
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq