// File: davidjosepha[P]slitherlink/src/generator/loopgen.cpp
// Function: LoopGen::validCell(Coordinates, Coordinates) const
bool LoopGen::validCell(Coordinates coords, Coordinates cur) const {
    bool valid = true;

    /* check to make sure the cell is within the grid */
    if (!inBounds(coords)) {
        return false;
    }

    valid = valid && loop_[coords.i][coords.j] != NOEXP;
    valid = valid && loop_[coords.i][coords.j] != OUT;
    valid = valid && loop_[coords.i][coords.j] != EXP;

    Coordinates shift = { coords.i - cur.i, coords.j - cur.j };

    if ((shift.i + shift.j != 1 && shift.i + shift.j != -1) || shift.i * shift.j != 0) {
        valid = false;
    }

    if (shift.i == 0) {
        valid = valid && cellOpen(coords.i, coords.j + shift.j);

        if (coords.i == 0) {
            valid = valid && cellOpen(1, coords.j + shift.j);
        } else if (coords.i == m_ - 1) {
            valid = valid && cellOpen(m_ - 2, coords.j + shift.j);
        }
        valid = valid && cellOpen(coords.i + 1, coords.j + shift.j);
        valid = valid && cellOpen(coords.i - 1, coords.j + shift.j);
    }

    if (shift.j == 0) {
        valid = valid && cellOpen(coords.i + shift.i, coords.j);

        if (coords.j == 0) {
            valid = valid && cellOpen(coords.i + shift.i, 1);
        } else if (coords.j == n_ - 1) {
            valid = valid && cellOpen(coords.i + shift.i, n_ - 2);
        }
        valid = valid && cellOpen(coords.i + shift.i, coords.j + 1);
        valid = valid && cellOpen(coords.i + shift.i, coords.j - 1);
    }

    if (!valid && loop_[coords.i][coords.j] == UNKNOWN) {
        loop_[coords.i][coords.j] = OUT;
    }

    return valid;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rsi, -0xc(%rbp)
movq %rdx, -0x14(%rbp)
movq %rdi, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movq %rdi, -0x40(%rbp)
movb $0x1, -0x21(%rbp)
movq -0xc(%rbp), %rax
movq %rax, -0x2c(%rbp)
movq -0x2c(%rbp), %rsi
callq 0x137c0
testb $0x1, %al
jne 0x13dae
movb $0x0, -0x1(%rbp)
jmp 0x140a7
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x41(%rbp)
je 0x13dd6
movq -0x40(%rbp), %rax
movq (%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x8(%rbp), %rcx
cmpl $0x2, (%rax,%rcx,4)
setne %al
movb %al, -0x41(%rbp)
movb -0x41(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x42(%rbp)
je 0x13e06
movq -0x40(%rbp), %rax
movq (%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x8(%rbp), %rcx
cmpl $0x3, (%rax,%rcx,4)
setne %al
movb %al, -0x42(%rbp)
movb -0x42(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x43(%rbp)
je 0x13e36
movq -0x40(%rbp), %rax
movq (%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x8(%rbp), %rcx
cmpl $0x1, (%rax,%rcx,4)
setne %al
movb %al, -0x43(%rbp)
movb -0x43(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
movl -0xc(%rbp), %eax
subl -0x14(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x8(%rbp), %eax
subl -0x10(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x34(%rbp), %eax
addl -0x30(%rbp), %eax
cmpl $0x1, %eax
je 0x13e66
movl -0x34(%rbp), %eax
addl -0x30(%rbp), %eax
cmpl $-0x1, %eax
jne 0x13e72
movl -0x34(%rbp), %eax
imull -0x30(%rbp), %eax
cmpl $0x0, %eax
je 0x13e76
movb $0x0, -0x21(%rbp)
cmpl $0x0, -0x34(%rbp)
jne 0x13f6e
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x44(%rbp)
je 0x13ea0
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0x8(%rbp), %edx
addl -0x30(%rbp), %edx
callq 0x140c0
movb %al, -0x44(%rbp)
movb -0x44(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
cmpl $0x0, -0xc(%rbp)
jne 0x13eda
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x45(%rbp)
je 0x13ed0
movq -0x40(%rbp), %rdi
movl -0x8(%rbp), %edx
addl -0x30(%rbp), %edx
movl $0x1, %esi
callq 0x140c0
movb %al, -0x45(%rbp)
movb -0x45(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
jmp 0x13f18
movq -0x40(%rbp), %rcx
movl -0xc(%rbp), %eax
movl 0x10(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x13f16
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x46(%rbp)
je 0x13f0e
movq -0x40(%rbp), %rdi
movl 0x10(%rdi), %esi
subl $0x2, %esi
movl -0x8(%rbp), %edx
addl -0x30(%rbp), %edx
callq 0x140c0
movb %al, -0x46(%rbp)
movb -0x46(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
jmp 0x13f18
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x47(%rbp)
je 0x13f3b
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
addl $0x1, %esi
movl -0x8(%rbp), %edx
addl -0x30(%rbp), %edx
callq 0x140c0
movb %al, -0x47(%rbp)
movb -0x47(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x48(%rbp)
je 0x13f66
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
subl $0x1, %esi
movl -0x8(%rbp), %edx
addl -0x30(%rbp), %edx
callq 0x140c0
movb %al, -0x48(%rbp)
movb -0x48(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x14066
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x49(%rbp)
je 0x13f98
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
addl -0x34(%rbp), %esi
movl -0x8(%rbp), %edx
callq 0x140c0
movb %al, -0x49(%rbp)
movb -0x49(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
cmpl $0x0, -0x8(%rbp)
jne 0x13fd2
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x4a(%rbp)
je 0x13fc8
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
addl -0x34(%rbp), %esi
movl $0x1, %edx
callq 0x140c0
movb %al, -0x4a(%rbp)
movb -0x4a(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
jmp 0x14010
movq -0x40(%rbp), %rcx
movl -0x8(%rbp), %eax
movl 0x14(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x1400e
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x4b(%rbp)
je 0x14006
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
addl -0x34(%rbp), %esi
movl 0x14(%rdi), %edx
subl $0x2, %edx
callq 0x140c0
movb %al, -0x4b(%rbp)
movb -0x4b(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
jmp 0x14010
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x4c(%rbp)
je 0x14033
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
addl -0x34(%rbp), %esi
movl -0x8(%rbp), %edx
addl $0x1, %edx
callq 0x140c0
movb %al, -0x4c(%rbp)
movb -0x4c(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
xorl %eax, %eax
testb $0x1, -0x21(%rbp)
movb %al, -0x4d(%rbp)
je 0x1405e
movq -0x40(%rbp), %rdi
movl -0xc(%rbp), %esi
addl -0x34(%rbp), %esi
movl -0x8(%rbp), %edx
subl $0x1, %edx
callq 0x140c0
movb %al, -0x4d(%rbp)
movb -0x4d(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
testb $0x1, -0x21(%rbp)
jne 0x1409f
movq -0x40(%rbp), %rax
movq (%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x8(%rbp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jne 0x1409f
movq -0x40(%rbp), %rax
movq (%rax), %rax
movslq -0xc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x8(%rbp), %rcx
movl $0x3, (%rax,%rcx,4)
movb -0x21(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)