// File: /workspace/github_cpp_makefile_star2_O2/jeffreyan11[P]go-engine/board.cpp
// Function: Board::countTerritory(int&, int&)
void Board::countTerritory(int &whiteTerritory, int &blackTerritory) {
    whiteTerritory = 0;
    blackTerritory = 0;
    Stone *visited = new Stone[arraySize*arraySize];
    Stone *territory = new Stone[arraySize*arraySize];
    Stone *region = new Stone[arraySize*arraySize]; 

    // Count territory for both sides
    for (Player p = BLACK; p <= WHITE; p++) {
        // Reset the visited array
        for (int i = 0; i < arraySize*arraySize; i++)
            visited[i] = 0;

        // Main loop
        for (int j = 1; j <= boardSize; j++) {
            for (int i = 1; i <= boardSize; i++) {
                // Don't recount territory
                if (visited[index(i, j)])
                    continue;
                // Only use empty squares as seeds
                if (pieces[index(i, j)])
                    continue;

                if (isEye(p, coordToMove(i, j))) {
                    visited[index(i, j)] = 1;
                    if (p == BLACK)
                        blackTerritory++;
                    else
                        whiteTerritory++;
                    continue;
                }
                
                for (int k = 0; k < arraySize*arraySize; k++)
                    territory[k] = 0;
                int territorySize = 0;
                int boundarySize = 0;

                getTerritory(p, i, j, visited, territory, territorySize, boundarySize);

                // Check if territory was actually sectioned off
                if (territorySize + boundarySize == boardSize*boardSize)
                    continue;

                // Detect life/death of internal stones
                // Initialize region to 0 if territory is 1, and vice versa
                // This acts as our "visited" array, so that we only explore areas
                // inside the territory
                // bool isContested = false;
                // for (int n = 1; n <= boardSize; n++) {
                //     for (int m = 1; m <= boardSize; m++) {
                //         if (!territory[index(m, n)])
                //             continue;
                //         if (pieces[index(m, n)] == otherPlayer(p)) {
                //             isContested = true;
                //             break;
                //         }
                //     }
                // }

                // if (!isContested) {
                //     if (p == BLACK)
                //         blackTerritory += territorySize;
                //     else
                //         whiteTerritory += territorySize;
                // }
                
                for (int k = 0; k < arraySize*arraySize; k++)
                    region[k] = territory[k] ^ 1;
                int internalRegions = 0;

                for (int n = 1; n <= boardSize; n++) {
                    for (int m = 1; m <= boardSize; m++) {
                        if (region[index(m, n)])
                            continue;
                        if (pieces[index(m, n)])
                            continue;

                        MoveList eye;
                        if (isSurrounded(EMPTY, p, m, n, region, eye))
                            internalRegions++;
                    }
                }

                int territoryCount = 0;
                if (internalRegions == 0) {
                    territoryCount += territorySize;
                    // Score dead stones
                    for (int k = 0; k < arraySize*arraySize; k++)
                        if (territory[k] && pieces[k] == otherPlayer(p))
                            territoryCount++;
                }

                if (p == BLACK)
                    blackTerritory += territoryCount;
                else
                    whiteTerritory += territoryCount;
            }
        }
    }

    delete[] visited;
    delete[] territory;
    delete[] region;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x478, %rsp            # imm = 0x478
movq %rsi, 0x40(%rsp)
andl $0x0, (%rsi)
movq %rdx, 0x38(%rsp)
andl $0x0, (%rdx)
movq %rdi, %r14
movl 0x71be(%rip), %ebx      # 0xb174
imull %ebx, %ebx
shlq $0x2, %rbx
movq %rbx, %rdi
callq 0x2030
movq %rax, %rbp
movq %rbx, %rdi
callq 0x2030
movq %rax, %r12
movq %rbx, %rdi
callq 0x2030
movq %r14, %r9
movq %rax, 0x28(%rsp)
pushq $0x1
popq %r13
movq %r14, 0x10(%rsp)
movq %rbp, 0x50(%rsp)
movq %r12, 0x48(%rsp)
cmpl $0x3, %r13d
je 0x4263
movl 0x716e(%rip), %eax      # 0xb174
imull %eax, %eax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x401a
andl $0x0, (%rbp,%rcx,4)
incq %rcx
jmp 0x400b
pushq $0x3
popq %rax
subl %r13d, %eax
movl %eax, 0x30(%rsp)
cmpl $0x1, %r13d
movl 0x7142(%rip), %ebx      # 0xb170
movq 0x40(%rsp), %rax
cmoveq 0x38(%rsp), %rax
movq %rax, 0x58(%rsp)
pushq $0x1
popq %rcx
movl %r13d, 0x1c(%rsp)
cmpl %ebx, %ecx
jg 0x425b
pushq $0x1
popq %rdx
movl %ecx, 0x8(%rsp)
cmpl %ebx, %edx
jg 0x4254
movslq 0x7110(%rip), %rax      # 0xb174
movq %rax, %r15
imull %ecx, %eax
addl %edx, %eax
movslq %eax, %r14
cmpl $0x0, (%rbp,%r14,4)
jne 0x4247
movq (%r9), %rax
cmpl $0x0, (%rax,%r14,4)
jne 0x4247
movl %edx, 0xc(%rsp)
movl %edx, %eax
shll $0x8, %eax
orl %ecx, %eax
movzwl %ax, %edx
movq %r9, %rdi
movl %r13d, %esi
callq 0x3bda
testb %al, %al
je 0x40c3
movl $0x1, (%rbp,%r14,4)
cmpl $0x1, %r13d
jne 0x4147
movq 0x38(%rsp), %rax
jmp 0x414c
movl %r15d, %r14d
imull %r14d, %r14d
xorl %eax, %eax
movl 0x8(%rsp), %ecx
movl 0xc(%rsp), %edx
movq %rbp, %r8
cmpq %rax, %r14
je 0x40e6
andl $0x0, (%r12,%rax,4)
incq %rax
jmp 0x40d7
andl $0x0, 0x24(%rsp)
andl $0x0, 0x20(%rsp)
movq 0x10(%rsp), %rdi
movl %r13d, %esi
movq %r12, %r9
leaq 0x20(%rsp), %rax
pushq %rax
leaq 0x2c(%rsp), %rax
pushq %rax
callq 0x4290
movq 0x20(%rsp), %r9
addq $0x10, %rsp
movl 0x24(%rsp), %esi
movl 0x20(%rsp), %eax
addl %esi, %eax
movl %ebx, %ecx
imull %ebx, %ecx
cmpl %ecx, %eax
je 0x423a
xorl %eax, %eax
cmpq %rax, %r14
je 0x4158
movl (%r12,%rax,4), %ecx
xorl $0x1, %ecx
movq 0x28(%rsp), %rdx
movl %ecx, (%rdx,%rax,4)
incq %rax
jmp 0x412e
movq 0x40(%rsp), %rax
incl (%rax)
movq 0x10(%rsp), %r9
jmp 0x423f
movl %esi, 0x34(%rsp)
movq %r14, 0x60(%rsp)
incl %ebx
movq 0x28(%rsp), %rax
leaq (%rax,%r15,4), %rbp
shlq $0x2, %r15
xorl %r12d, %r12d
movq %r15, 0x68(%rsp)
pushq $0x1
popq %r14
cmpq %rbx, %r14
je 0x41f0
pushq $0x1
popq %r13
cmpq %r13, %rbx
je 0x41e0
cmpl $0x0, (%rbp,%r13,4)
jne 0x41db
movq (%r9), %rax
addq %r15, %rax
cmpl $0x0, (%rax,%r13,4)
jne 0x41db
andl $0x0, 0x474(%rsp)
subq $0x8, %rsp
movq 0x18(%rsp), %rdi
xorl %esi, %esi
movl 0x24(%rsp), %edx
movl %r13d, %ecx
movl %r14d, %r8d
movq 0x30(%rsp), %r9
leaq 0x7c(%rsp), %rax
pushq %rax
callq 0x3dea
movq 0x20(%rsp), %r9
addq $0x10, %rsp
movzbl %al, %eax
addl %eax, %r12d
incq %r13
jmp 0x4185
incq %r14
movq 0x68(%rsp), %rax
addq %rax, %rbp
addq %rax, %r15
jmp 0x417c
xorl %eax, %eax
testl %r12d, %r12d
movq 0x50(%rsp), %rbp
movq 0x48(%rsp), %r12
jne 0x4233
movq (%r9), %rax
xorl %ecx, %ecx
movl 0x30(%rsp), %esi
movq 0x60(%rsp), %r8
movl 0x34(%rsp), %r10d
cmpq %rcx, %r8
je 0x4230
cmpl $0x0, (%r12,%rcx,4)
je 0x422b
xorl %edx, %edx
cmpl %esi, (%rax,%rcx,4)
sete %dl
addl %edx, %r10d
incq %rcx
jmp 0x4214
movl %r10d, %eax
movq 0x58(%rsp), %rcx
addl %eax, (%rcx)
movl 0x1c(%rsp), %r13d
movl 0x8(%rsp), %ecx
movl 0xc(%rsp), %edx
incl %edx
movl 0x6f21(%rip), %ebx      # 0xb170
jmp 0x4055
incl %ecx
jmp 0x4046
incl %r13d
jmp 0x3ff6
movq %rbp, %rdi
callq 0x21d0
movq %r12, %rdi
callq 0x21d0
movq 0x28(%rsp), %rdi
callq 0x21d0
addq $0x478, %rsp            # imm = 0x478
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop