// File: macfergus[P]baduk/cppsrc/baduk/scoring.cpp
// Function: baduk::removeDeadStones(std::shared_ptr<baduk::GameState const>)
Board removeDeadStones(std::shared_ptr<const GameState> game) {
    const unsigned int num_rounds = 1000;
    const auto orig_board = game->board();
    const auto num_rows = orig_board.numRows();
    const auto num_cols = orig_board.numCols();
    BoardCounter b_count(num_rows, num_cols);
    BoardCounter w_count(num_rows, num_cols);
    for (unsigned int num_done = 0; num_done < num_rounds; ++num_done) {
        // Randomly complete the game
        const auto final_state = completeGame(game);
        // Score the result
        const auto tmap = evaluateTerritory(final_state->board());
        // Count up the status
        for (unsigned int r = 0; r < num_rows; ++r) {
            for (unsigned int c = 0; c < num_cols; ++c) {
                const Point p(r, c);
                const auto status = tmap.at(p);
                if (status == PointStatus::black) {
                    b_count.increment(p);
                } else if (status == PointStatus::white) {
                    w_count.increment(p);
                }
            }
        }
    }

    // Remove dead stones.
    Board cleaned_board(num_rows, num_cols);
    for (unsigned int r = 0; r < num_rows; ++r) {
        for (unsigned int c = 0; c < num_cols; ++c) {
            const Point p(r, c);
            if (orig_board.isEmpty(p)) {
                continue;
            }
            const auto orig_stone = orig_board.at(p);
            if (orig_stone == Stone::black) {
                const double p_white = w_count.get(p) / float(num_rounds);
                if (p_white < DEAD_THRESHOLD) {
                    cleaned_board.place(p, orig_stone);
                }
            } else {
                const double p_black = b_count.get(p) / float(num_rounds);
                if (p_black < DEAD_THRESHOLD) {
                    cleaned_board.place(p, orig_stone);
                }
            }
        }
    }
    return cleaned_board;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x5ce0, %rsp           # imm = 0x5CE0
movq %rsi, -0x5cb0(%rbp)
movq %rdi, %rax
movq -0x5cb0(%rbp), %rdi
movq %rax, -0x5ca8(%rbp)
movq %rax, -0x5ca0(%rbp)
movq %rdi, -0x8(%rbp)
movl $0x3e8, -0xc(%rbp)      # imm = 0x3E8
callq 0xb8c0
movq %rax, %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
leaq -0x5b40(%rbp), %rdi
movq %rdi, -0x5c98(%rbp)
movl $0x5b30, %edx           # imm = 0x5B30
callq 0x31b0
movq -0x5c98(%rbp), %rdi
callq 0xb6a0
movq -0x5c98(%rbp), %rdi
movl %eax, -0x5b44(%rbp)
callq 0xb6c0
movl %eax, -0x5b48(%rbp)
movl -0x5b44(%rbp), %esi
movl -0x5b48(%rbp), %edx
leaq -0x5b78(%rbp), %rdi
callq 0x119d0
movl -0x5b44(%rbp), %esi
movl -0x5b48(%rbp), %edx
leaq -0x5ba8(%rbp), %rdi
callq 0x119d0
jmp 0xae87
movl $0x0, -0x5bb8(%rbp)
cmpl $0x3e8, -0x5bb8(%rbp)   # imm = 0x3E8
jae 0xb0db
movq -0x5cb0(%rbp), %rsi
leaq -0x5bd8(%rbp), %rdi
movq %rdi, -0x5cb8(%rbp)
callq 0xb890
movq -0x5cb8(%rbp), %rsi
leaq -0x5bc8(%rbp), %rdi
callq 0xaca0
jmp 0xaed0
leaq -0x5bd8(%rbp), %rdi
callq 0xb960
leaq -0x5bc8(%rbp), %rdi
callq 0xb8c0
movq %rax, %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x5cc0(%rbp)
jmp 0xaefd
movq -0x5cc0(%rbp), %rsi
leaq -0x5c08(%rbp), %rdi
callq 0xa9b0
jmp 0xaf12
movl $0x0, -0x5c0c(%rbp)
movl -0x5c0c(%rbp), %eax
cmpl -0x5b44(%rbp), %eax
jae 0xb09e
movl $0x0, -0x5c10(%rbp)
movl -0x5c10(%rbp), %eax
cmpl -0x5b48(%rbp), %eax
jae 0xb088
movl -0x5c0c(%rbp), %esi
movl -0x5c10(%rbp), %edx
leaq -0x5c18(%rbp), %rdi
callq 0x9dc0
jmp 0xaf64
movq -0x5c18(%rbp), %rax
movq %rax, -0x5c28(%rbp)
movq -0x5c28(%rbp), %rsi
leaq -0x5c08(%rbp), %rdi
callq 0xa410
movl %eax, -0x5cc4(%rbp)
jmp 0xaf8d
movl -0x5cc4(%rbp), %eax
movl %eax, -0x5c1c(%rbp)
cmpl $0x0, -0x5c1c(%rbp)
jne 0xb042
movq -0x5c18(%rbp), %rax
movq %rax, -0x5c30(%rbp)
movq -0x5c30(%rbp), %rsi
leaq -0x5b78(%rbp), %rdi
callq 0x11a00
jmp 0xafc9
jmp 0xb072
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x5bb0(%rbp)
movl %eax, -0x5bb4(%rbp)
jmp 0xb357
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x5bb0(%rbp)
movl %eax, -0x5bb4(%rbp)
leaq -0x5bd8(%rbp), %rdi
callq 0xb960
jmp 0xb34b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x5bb0(%rbp)
movl %eax, -0x5bb4(%rbp)
jmp 0xb0ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x5bb0(%rbp)
movl %eax, -0x5bb4(%rbp)
leaq -0x5c08(%rbp), %rdi
callq 0xb7f0
jmp 0xb0ca
cmpl $0x1, -0x5c1c(%rbp)
jne 0xb070
movq -0x5c18(%rbp), %rax
movq %rax, -0x5c38(%rbp)
movq -0x5c38(%rbp), %rsi
leaq -0x5ba8(%rbp), %rdi
callq 0x11a00
jmp 0xb06e
jmp 0xb070
jmp 0xb072
jmp 0xb074
movl -0x5c10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c10(%rbp)
jmp 0xaf38
jmp 0xb08a
movl -0x5c0c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c0c(%rbp)
jmp 0xaf1c
leaq -0x5c08(%rbp), %rdi
callq 0xb7f0
leaq -0x5bc8(%rbp), %rdi
callq 0xb960
movl -0x5bb8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5bb8(%rbp)
jmp 0xae91
leaq -0x5bc8(%rbp), %rdi
callq 0xb960
jmp 0xb34b
movq -0x5ca8(%rbp), %rdi
movl -0x5b44(%rbp), %esi
movl -0x5b48(%rbp), %edx
callq 0x3c5b0
jmp 0xb0f5
movl $0x0, -0x5c3c(%rbp)
movl -0x5c3c(%rbp), %eax
cmpl -0x5b44(%rbp), %eax
jae 0xb323
movl $0x0, -0x5c40(%rbp)
movl -0x5c40(%rbp), %eax
cmpl -0x5b48(%rbp), %eax
jae 0xb30d
movl -0x5c3c(%rbp), %esi
movl -0x5c40(%rbp), %edx
leaq -0x5c48(%rbp), %rdi
callq 0x9dc0
jmp 0xb147
movq -0x5c48(%rbp), %rax
movq %rax, -0x5c50(%rbp)
movq -0x5c50(%rbp), %rsi
leaq -0x5b40(%rbp), %rdi
callq 0x3c650
movb %al, -0x5cc5(%rbp)
jmp 0xb170
movb -0x5cc5(%rbp), %al
testb $0x1, %al
jne 0xb17c
jmp 0xb198
jmp 0xb2f9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x5bb0(%rbp)
movl %eax, -0x5bb4(%rbp)
jmp 0xb34b
movq -0x5c48(%rbp), %rax
movq %rax, -0x5c60(%rbp)
movq -0x5c60(%rbp), %rsi
leaq -0x5b40(%rbp), %rdi
callq 0x3d4c0
movl %eax, -0x5ccc(%rbp)
jmp 0xb1c1
movl -0x5ccc(%rbp), %eax
movl %eax, -0x5c54(%rbp)
cmpl $0x0, -0x5c54(%rbp)
jne 0xb26a
movq -0x5c48(%rbp), %rax
movq %rax, -0x5c70(%rbp)
movq -0x5c70(%rbp), %rsi
leaq -0x5ba8(%rbp), %rdi
callq 0x11a80
movl %eax, -0x5cd0(%rbp)
jmp 0xb203
movl -0x5cd0(%rbp), %eax
movl %eax, %eax
cvtsi2ss %rax, %xmm0
movss 0x381c8(%rip), %xmm1    # 0x433e0
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x5c68(%rbp)
movsd 0x381a8(%rip), %xmm0    # 0x433d8
ucomisd -0x5c68(%rbp), %xmm0
jbe 0xb265
movq -0x5ca8(%rbp), %rdi
movq -0x5c48(%rbp), %rax
movq %rax, -0x5c78(%rbp)
movl -0x5c54(%rbp), %edx
movq -0x5c78(%rbp), %rsi
callq 0x3c6f0
jmp 0xb263
jmp 0xb265
jmp 0xb2f7
movq -0x5c48(%rbp), %rax
movq %rax, -0x5c88(%rbp)
movq -0x5c88(%rbp), %rsi
leaq -0x5b78(%rbp), %rdi
callq 0x11a80
movl %eax, -0x5cd4(%rbp)
jmp 0xb293
movl -0x5cd4(%rbp), %eax
movl %eax, %eax
cvtsi2ss %rax, %xmm0
movss 0x38138(%rip), %xmm1    # 0x433e0
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x5c80(%rbp)
movsd 0x38118(%rip), %xmm0    # 0x433d8
ucomisd -0x5c80(%rbp), %xmm0
jbe 0xb2f5
movq -0x5ca8(%rbp), %rdi
movq -0x5c48(%rbp), %rax
movq %rax, -0x5c90(%rbp)
movl -0x5c54(%rbp), %edx
movq -0x5c90(%rbp), %rsi
callq 0x3c6f0
jmp 0xb2f3
jmp 0xb2f5
jmp 0xb2f7
jmp 0xb2f9
movl -0x5c40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c40(%rbp)
jmp 0xb11b
jmp 0xb30f
movl -0x5c3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c3c(%rbp)
jmp 0xb0ff
leaq -0x5ba8(%rbp), %rdi
callq 0xb980
leaq -0x5b78(%rbp), %rdi
callq 0xb980
movq -0x5ca0(%rbp), %rax
addq $0x5ce0, %rsp           # imm = 0x5CE0
popq %rbp
retq
leaq -0x5ba8(%rbp), %rdi
callq 0xb980
leaq -0x5b78(%rbp), %rdi
callq 0xb980
movq -0x5bb0(%rbp), %rdi
callq 0x3370
nop