// File: /workspace/github_cpp_makefile_star2_O1/pgrouchy[P]NoiseWorld/mathNet.cpp
// Function: Genome::setNearestNeighbor(std::__cxx11::list<gridEntry*, std::allocator<gridEntry*>>*, bool&, Population*)
void Genome::setNearestNeighbor(list<gridEntry*> *fullGrid, bool &isWithinReproductionDistance, Population *myPop) {
    list<Genome*>::iterator curGenome, curGenome2; 
    list<gridEntry*> innerEntriesToCheck;
    list<gridEntry*> outerEntriesToCheck;
    list<gridEntry*>::iterator curGridEntry;
    double minDist, myDist, closestIndDist = DBL_MAX;
    int i, j, xGridBlock, yGridBlock;
    int counter = 1;
    bool neighbourFound = false;

    // first check the grid location that is also occupied by the agent
    for (curGridEntry = fullGrid[this->mainGridLocation[1]*(int)(ISLAND_SIZE/NN_BLOCK_SIZE) + this->mainGridLocation[0]].begin(); curGridEntry != fullGrid[this->mainGridLocation[1]*(int)(ISLAND_SIZE/NN_BLOCK_SIZE) + this->mainGridLocation[0]].end(); ++curGridEntry) {
        if (((*curGridEntry)->myGenome != this)) {
            (*curGridEntry)->myDist = sqrt(pow((this->myPosition[0] - (*curGridEntry)->myGenome->myPosition[0]),2.0) + pow((this->myPosition[1] - (*curGridEntry)->myGenome->myPosition[1]),2.0));
            innerEntriesToCheck.push_back((*curGridEntry));
        }
    }

    do { // check next group of grid sqaures
        for (i = (-1*counter); i <= counter; i++) {
            for (j = (-1*counter); j <= counter; j++) {
                if ((i == (-1*counter)) || (j == (-1*counter)) || (i == counter) || (j == counter)) {
                    xGridBlock = this->mainGridLocation[0] + i;
                    if (xGridBlock >= (int)(ISLAND_SIZE/NN_BLOCK_SIZE)) {
                        continue;
                    } else if (xGridBlock < 0) {
                        continue;
                    }
                    yGridBlock = this->mainGridLocation[1] + j;
                    if (yGridBlock >= (int)(ISLAND_SIZE/NN_BLOCK_SIZE)) {
                        continue;
                    } else if (yGridBlock < 0) {
                        continue;
                    }
                    for (curGridEntry = fullGrid[yGridBlock*(int)(ISLAND_SIZE/NN_BLOCK_SIZE) + xGridBlock].begin(); curGridEntry != fullGrid[yGridBlock*(int)(ISLAND_SIZE/NN_BLOCK_SIZE) + xGridBlock].end(); ++curGridEntry) {
                        (*curGridEntry)->myDist = sqrt(pow((this->myPosition[0] - (*curGridEntry)->myGenome->myPosition[0]),2.0) + pow((this->myPosition[1] - (*curGridEntry)->myGenome->myPosition[1]),2.0));
                        outerEntriesToCheck.push_back((*curGridEntry));
                    }
                }
            }
        }

        // first check the inner grid locations for a neighbor
        for (curGridEntry = innerEntriesToCheck.begin(); curGridEntry != innerEntriesToCheck.end(); ++curGridEntry) {
            if ((*curGridEntry)->myDist < closestIndDist) {
                neighbourFound = true;
                closestIndDist = (*curGridEntry)->myDist;
                this->closestInd = (*curGridEntry)->myGenome;
            }
        }

        if (neighbourFound) { // if we find a neighbor, we still need to search the next layer of grid locations as a closer neighbor may be located there
            for (curGridEntry = outerEntriesToCheck.begin(); curGridEntry != outerEntriesToCheck.end(); ++curGridEntry) {
                if ((*curGridEntry)->myDist < closestIndDist) {
                    closestIndDist = (*curGridEntry)->myDist;
                    this->closestInd = (*curGridEntry)->myGenome;
                }
            }
        } else { // get ready to check the next layer
            innerEntriesToCheck.clear();
            innerEntriesToCheck.splice(innerEntriesToCheck.begin(), outerEntriesToCheck);
            outerEntriesToCheck.clear();
            counter++;
        }
    } while ((!neighbourFound) && (counter <= 2));

    if (!neighbourFound) { // if after 5 layers no neighbor is found, do a search of the entire population
        minDist = DBL_MAX;
        for (curGenome = myPop->genomes.begin(); curGenome != myPop->genomes.end(); ++curGenome) {
            if ((*curGenome) != this) {
                myDist = sqrt(pow((this->myPosition[0] - (*curGenome)->myPosition[0]), 2.0) + pow((this->myPosition[1] - (*curGenome)->myPosition[1]), 2.0));
                if (myDist < minDist) {
                    minDist = myDist;
                    this->closestInd = (*curGenome);
                    closestIndDist = minDist;
                }
            }
        }
    }

    isWithinReproductionDistance = false;
    if (closestIndDist < REPRODUCTION_DIST) {
        isWithinReproductionDistance = true;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rcx, 0x58(%rsp)
movq %rdx, %r14
movq %rdi, %rdx
leaq 0x40(%rsp), %rdi
movq %rdi, 0x8(%rdi)
movq %rdi, (%rdi)
xorl %eax, %eax
movq %rax, 0x10(%rdi)
leaq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rcx)
movq %rcx, (%rcx)
movq %rax, 0x10(%rcx)
movslq 0x4c(%rdx), %rax
leaq (%rax,%rax,4), %rax
shlq $0x5, %rax
movslq 0x48(%rdx), %rcx
addq %rax, %rcx
leaq (%rcx,%rcx,2), %rax
movq %rsi, 0x30(%rsp)
leaq (%rsi,%rax,8), %rax
movq (%rax), %rbx
cmpq %rax, %rbx
movq %rdx, 0x38(%rsp)
je 0xa4a6
leaq 0x40(%rsp), %r15
movq 0x10(%rbx), %rax
movq (%rax), %rax
cmpq %rdx, %rax
je 0xa47a
movupd 0x68(%rdx), %xmm1
movupd 0x68(%rax), %xmm0
subpd %xmm0, %xmm1
mulpd %xmm1, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
ucomisd 0xd6b(%rip), %xmm0      # 0xb1a8
jb 0xa445
sqrtsd %xmm0, %xmm0
jmp 0xa44a
callq 0x2140
movq 0x10(%rbx), %rax
movsd %xmm0, 0x8(%rax)
movl $0x18, %edi
callq 0x21e0
movq 0x10(%rbx), %rcx
movq %rcx, 0x10(%rax)
movq %rax, %rdi
movq %r15, %rsi
callq 0x2060
incq 0x50(%rsp)
movq 0x38(%rsp), %rdx
movq (%rbx), %rbx
movslq 0x4c(%rdx), %rax
leaq (%rax,%rax,4), %rax
shlq $0x5, %rax
movslq 0x48(%rdx), %rcx
addq %rax, %rcx
leaq (%rcx,%rcx,2), %rax
movq 0x30(%rsp), %rcx
leaq (%rcx,%rax,8), %rax
cmpq %rax, %rbx
jne 0xa40b
movq %r14, 0x60(%rsp)
movsd 0xc9d(%rip), %xmm1      # 0xb150
movl $0x1, %r15d
xorl %ebp, %ebp
movl %ebp, 0x14(%rsp)
movsd %xmm1, 0x8(%rsp)
testl %r15d, %r15d
js 0xa5c1
movl %r15d, %r12d
negl %r12d
movl %r12d, %ebp
movl %r12d, %ebx
cmpl %r15d, %ebx
je 0xa4f2
cmpl %r15d, %ebp
je 0xa4f2
cmpl %r12d, %ebp
je 0xa4f2
cmpl %r12d, %ebx
jne 0xa5a5
movl 0x48(%rdx), %eax
addl %ebp, %eax
cmpl $0x9f, %eax
ja 0xa5a5
movl 0x4c(%rdx), %ecx
addl %ebx, %ecx
cmpl $0x9f, %ecx
ja 0xa5a5
leal (%rcx,%rcx,4), %ecx
shll $0x5, %ecx
addl %eax, %ecx
leaq (%rcx,%rcx,2), %rax
movq 0x30(%rsp), %rcx
leaq (%rcx,%rax,8), %r14
movq (%r14), %r13
cmpq %r14, %r13
je 0xa5a5
movq 0x10(%r13), %rax
movq (%rax), %rax
movupd 0x68(%rdx), %xmm1
movupd 0x68(%rax), %xmm0
subpd %xmm0, %xmm1
mulpd %xmm1, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
ucomisd 0xc4b(%rip), %xmm0      # 0xb1a8
jb 0xa565
sqrtsd %xmm0, %xmm0
jmp 0xa56a
callq 0x2140
movq 0x10(%r13), %rax
movsd %xmm0, 0x8(%rax)
movl $0x18, %edi
callq 0x21e0
movq 0x10(%r13), %rcx
movq %rcx, 0x10(%rax)
movq %rax, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2060
incq 0x28(%rsp)
movq (%r13), %r13
cmpq %r14, %r13
movq 0x38(%rsp), %rdx
jne 0xa530
leal 0x1(%rbx), %eax
cmpl %r15d, %ebx
movl %eax, %ebx
jne 0xa4da
leal 0x1(%rbp), %eax
cmpl %r15d, %ebp
movl %eax, %ebp
jne 0xa4d7
movq 0x40(%rsp), %rdi
leaq 0x40(%rsp), %r14
cmpq %r14, %rdi
je 0xa609
movq %rdi, %rax
leaq 0x18(%rsp), %r12
movsd 0x8(%rsp), %xmm1
movl 0x14(%rsp), %ebp
movq 0x10(%rax), %rcx
movsd 0x8(%rcx), %xmm0
ucomisd %xmm0, %xmm1
jbe 0xa5ff
movq (%rcx), %rcx
movq %rcx, 0x50(%rdx)
movb $0x1, %bpl
movapd %xmm0, %xmm1
movq (%rax), %rax
cmpq %r14, %rax
jne 0xa5e2
jmp 0xa618
leaq 0x18(%rsp), %r12
movsd 0x8(%rsp), %xmm1
movl 0x14(%rsp), %ebp
testb $0x1, %bpl
je 0xa64b
movq 0x18(%rsp), %rax
cmpq %r12, %rax
je 0xa6e6
movq 0x10(%rax), %rcx
movsd 0x8(%rcx), %xmm0
ucomisd %xmm0, %xmm1
jbe 0xa646
movq (%rcx), %rcx
movq %rcx, 0x50(%rdx)
movapd %xmm0, %xmm1
movq (%rax), %rax
jmp 0xa623
movsd %xmm1, 0x8(%rsp)
cmpq %r14, %rdi
je 0xa66b
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r14, %rbx
jne 0xa656
movq %r14, 0x48(%rsp)
movq %r14, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
movq 0x18(%rsp), %rsi
cmpq %r12, %rsi
je 0xa6a6
movq %r14, %rdi
movq %r12, %rdx
callq 0x20b0
movq 0x28(%rsp), %rax
addq %rax, 0x50(%rsp)
movq $0x0, 0x28(%rsp)
movq 0x18(%rsp), %rdi
cmpq %r12, %rdi
je 0xa6c5
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r12, %rbx
jne 0xa6b0
movq %r12, 0x20(%rsp)
movq %r12, 0x18(%rsp)
movq $0x0, 0x28(%rsp)
incl %r15d
movq 0x38(%rsp), %rdx
movsd 0x8(%rsp), %xmm1
testb $0x1, %bpl
jne 0xa6f6
cmpl $0x3, %r15d
jl 0xa4bb
testb $0x1, %bpl
jne 0xa794
movq 0x58(%rsp), %r15
movq (%r15), %rbx
cmpq %r15, %rbx
je 0xa794
movsd 0xa37(%rip), %xmm3      # 0xb150
xorpd %xmm2, %xmm2
movq 0x10(%rbx), %rax
cmpq %rdx, %rax
je 0xa78c
movsd %xmm1, 0x8(%rsp)
movupd 0x68(%rdx), %xmm1
movupd 0x68(%rax), %xmm0
subpd %xmm0, %xmm1
mulpd %xmm1, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
ucomisd %xmm2, %xmm0
jb 0xa756
sqrtsd %xmm0, %xmm0
jmp 0xa770
movsd %xmm3, 0x30(%rsp)
callq 0x2140
movsd 0x30(%rsp), %xmm3
xorpd %xmm2, %xmm2
movq 0x38(%rsp), %rdx
movsd 0x8(%rsp), %xmm1
ucomisd %xmm0, %xmm3
jbe 0xa78c
movq 0x10(%rbx), %rax
movq %rax, 0x50(%rdx)
movapd %xmm0, %xmm1
movapd %xmm0, %xmm3
movq (%rbx), %rbx
cmpq %r15, %rbx
jne 0xa71d
movsd 0xbe4(%rip), %xmm0      # 0xb380
ucomisd %xmm1, %xmm0
movq 0x60(%rsp), %rax
seta (%rax)
movq 0x18(%rsp), %rdi
cmpq %r12, %rdi
je 0xa7c7
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r12, %rbx
jne 0xa7b2
movq 0x40(%rsp), %rdi
cmpq %r14, %rdi
je 0xa7e6
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r14, %rbx
jne 0xa7d1
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xa7f7
movq %rax, %r15
movq 0x18(%rsp), %rdi
leaq 0x18(%rsp), %r12
cmpq %r12, %rdi
leaq 0x40(%rsp), %r14
je 0xa823
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r12, %rbx
jne 0xa80e
movq 0x40(%rsp), %rdi
cmpq %r14, %rdi
je 0xa842
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r14, %rbx
jne 0xa82d
movq %r15, %rdi
callq 0x2300