// File: macfergus[P]baduk/cppsrc/baduk/scoring.cpp
// Function: baduk::collectBoundary(baduk::Board, baduk::Point)
Boundary collectBoundary(Board board, Point origin) {
    Boundary b;
    std::queue<Point> q;
    std::set<Point> visited;

    const auto check_and_enqueue = [&q, &visited](Point new_point) {
        if (visited.find(new_point) == visited.end()) {
            q.push(new_point);
        }
    };

    q.push(origin);
    while (!q.empty()) {
        const auto p = q.front();
        q.pop();
        if (visited.find(p) != visited.end()) {
            continue;
        }
        if (board.isEmpty(p)) {
            // Enqueue its neighbors.
            if (p.row() > 0) {
                check_and_enqueue(Point(p.row() - 1, p.col()));
            }
            if (p.row() < board.numRows() - 1) {
                check_and_enqueue(Point(p.row() + 1, p.col()));
            }
            if (p.col() > 0) {
                check_and_enqueue(Point(p.row(), p.col() - 1));
            }
            if (p.col() < board.numCols() - 1) {
                check_and_enqueue(Point(p.row(), p.col() + 1));
            }
        } else {
            const auto stone = board.at(p);
            if (stone == Stone::black) {
                b.includes_black = true;
            } else {
                // Not empty, not black, must be white
                b.includes_white = true;
            }
        }
        visited.insert(p);
    }

    return b;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
leaq 0x10(%rbp), %rax
movq %rax, -0x128(%rbp)
movq %rdi, -0xc(%rbp)
leaq -0x2(%rbp), %rdi
callq 0xb500
leaq -0x60(%rbp), %rdi
movq %rdi, -0x118(%rbp)
callq 0xb520
leaq -0x90(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0xb550
movq -0x120(%rbp), %rax
movq -0x118(%rbp), %rdi
movq %rdi, -0xa0(%rbp)
movq %rax, -0x98(%rbp)
leaq -0xc(%rbp), %rsi
callq 0xb570
jmp 0xa52d
jmp 0xa52f
leaq -0x60(%rbp), %rdi
callq 0xb5a0
movb %al, -0x129(%rbp)
jmp 0xa540
movb -0x129(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xa551
jmp 0xa903
leaq -0x60(%rbp), %rdi
callq 0xb5c0
movq %rax, -0x138(%rbp)
jmp 0xa563
movq -0x138(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xb8(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xb5e0
jmp 0xa57f
leaq -0x90(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0xb630
movq %rax, -0x140(%rbp)
jmp 0xa59b
movq -0x140(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0x90(%rbp), %rdi
callq 0xb670
movq %rax, -0xc8(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0xb600
testb $0x1, %al
jne 0xa5d5
jmp 0xa606
jmp 0xa52f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x90(%rbp), %rdi
callq 0xb730
leaq -0x60(%rbp), %rdi
callq 0xb750
jmp 0xa925
movq -0x128(%rbp), %rdi
movq -0xb8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rsi
callq 0x3c650
movb %al, -0x141(%rbp)
jmp 0xa62f
movb -0x141(%rbp), %al
testb $0x1, %al
jne 0xa63e
jmp 0xa878
leaq -0xb8(%rbp), %rdi
callq 0x9db0
movl %eax, -0x148(%rbp)
jmp 0xa652
movl -0x148(%rbp), %eax
cmpl $0x0, %eax
jbe 0xa6c4
leaq -0xb8(%rbp), %rdi
callq 0x9db0
movl %eax, -0x14c(%rbp)
jmp 0xa671
movl -0x14c(%rbp), %eax
decl %eax
movl %eax, -0x154(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x9d90
movl %eax, -0x150(%rbp)
jmp 0xa693
movl -0x150(%rbp), %edx
movl -0x154(%rbp), %esi
leaq -0xd8(%rbp), %rdi
callq 0x9dc0
jmp 0xa6ad
movq -0xd8(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0xa940
jmp 0xa6c2
jmp 0xa6c4
leaq -0xb8(%rbp), %rdi
callq 0x9db0
movl %eax, -0x158(%rbp)
jmp 0xa6d8
movq -0x128(%rbp), %rdi
callq 0xb6a0
movl %eax, -0x15c(%rbp)
jmp 0xa6ec
movl -0x158(%rbp), %eax
movl -0x15c(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0xa766
leaq -0xb8(%rbp), %rdi
callq 0x9db0
movl %eax, -0x160(%rbp)
jmp 0xa713
movl -0x160(%rbp), %eax
incl %eax
movl %eax, -0x168(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x9d90
movl %eax, -0x164(%rbp)
jmp 0xa735
movl -0x164(%rbp), %edx
movl -0x168(%rbp), %esi
leaq -0xe0(%rbp), %rdi
callq 0x9dc0
jmp 0xa74f
movq -0xe0(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0xa940
jmp 0xa764
jmp 0xa766
leaq -0xb8(%rbp), %rdi
callq 0x9d90
movl %eax, -0x16c(%rbp)
jmp 0xa77a
movl -0x16c(%rbp), %eax
cmpl $0x0, %eax
jbe 0xa7e0
leaq -0xb8(%rbp), %rdi
callq 0x9db0
movl %eax, -0x170(%rbp)
jmp 0xa799
leaq -0xb8(%rbp), %rdi
callq 0x9d90
movl %eax, -0x174(%rbp)
jmp 0xa7ad
movl -0x170(%rbp), %esi
movl -0x174(%rbp), %edx
decl %edx
leaq -0xe8(%rbp), %rdi
callq 0x9dc0
jmp 0xa7c9
movq -0xe8(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0xa940
jmp 0xa7de
jmp 0xa7e0
leaq -0xb8(%rbp), %rdi
callq 0x9d90
movl %eax, -0x178(%rbp)
jmp 0xa7f4
movq -0x128(%rbp), %rdi
callq 0xb6c0
movl %eax, -0x17c(%rbp)
jmp 0xa808
movl -0x178(%rbp), %eax
movl -0x17c(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0xa876
leaq -0xb8(%rbp), %rdi
callq 0x9db0
movl %eax, -0x180(%rbp)
jmp 0xa82f
leaq -0xb8(%rbp), %rdi
callq 0x9d90
movl %eax, -0x184(%rbp)
jmp 0xa843
movl -0x180(%rbp), %esi
movl -0x184(%rbp), %edx
incl %edx
leaq -0xf0(%rbp), %rdi
callq 0x9dc0
jmp 0xa85f
movq -0xf0(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0xa940
jmp 0xa874
jmp 0xa876
jmp 0xa8c2
movq -0x128(%rbp), %rdi
movq -0xb8(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x100(%rbp), %rsi
callq 0x3d4c0
movl %eax, -0x188(%rbp)
jmp 0xa8a1
movl -0x188(%rbp), %eax
movl %eax, -0xf4(%rbp)
cmpl $0x0, -0xf4(%rbp)
jne 0xa8bc
movb $0x1, -0x2(%rbp)
jmp 0xa8c0
movb $0x1, -0x1(%rbp)
jmp 0xa8c2
leaq -0x90(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0xb6e0
movb %dl, -0x191(%rbp)
movq %rax, -0x190(%rbp)
jmp 0xa8e4
movb -0x191(%rbp), %al
movq -0x190(%rbp), %rcx
movq %rcx, -0x110(%rbp)
movb %al, -0x108(%rbp)
jmp 0xa52f
leaq -0x90(%rbp), %rdi
callq 0xb730
leaq -0x60(%rbp), %rdi
callq 0xb750
movw -0x2(%rbp), %ax
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
movq -0xa8(%rbp), %rdi
callq 0x3370
nopw %cs:(%rax,%rax)