// File: davidjosepha[P]slitherlink/src/solver/solver.cpp
// Function: Solver::applyRule(int, int, Rule&, Orientation)
void Solver::applyRule(int i, int j, Rule & rule, Orientation orient) {
    int m = rule.getHeight();
    int n = rule.getWidth();

    std::vector<EdgePosition> const * hLineDiff = rule.getHLineDiff();
    for (int k = 0; k < hLineDiff->size(); k++) {
        EdgePosition pattern = (*hLineDiff)[k];
        Coordinates adjusted = rotateHLine(pattern.coords.i, pattern.coords.j, m, n, orient);

        switch (orient) {
            case UPFLIP:
            case UP:
            case DOWNFLIP:
            case DOWN:
                if (grid_->getHLine(adjusted.i + i, adjusted.j + j) == EMPTY) {
                    grid_->setValid(grid_->setHLine(adjusted.i + i, adjusted.j + j, pattern.edge));
                    grid_->setUpdated(true);
                }
                break;
            case LEFTFLIP:
            case LEFT:
            case RIGHTFLIP:
            case RIGHT:
                if (grid_->getVLine(adjusted.i + i, adjusted.j + j) == EMPTY) {
                    grid_->setValid(grid_->setVLine(adjusted.i + i, adjusted.j + j, pattern.edge));
                    grid_->setUpdated(true);
                }
                break;
        }
    }

    std::vector<EdgePosition> const * vLineDiff = rule.getVLineDiff();
    for (int k = 0; k < vLineDiff->size(); k++) {
        EdgePosition pattern = (*vLineDiff)[k];
        Coordinates adjusted = rotateVLine(pattern.coords.i, pattern.coords.j, m, n, orient);

        switch (orient) {
            case UPFLIP:
            case UP:
            case DOWNFLIP:
            case DOWN:
                if (grid_->getVLine(adjusted.i + i, adjusted.j + j) == EMPTY) {
                    grid_->setValid(grid_->setVLine(adjusted.i + i, adjusted.j + j, pattern.edge));
                    grid_->setUpdated(true);
                }
                break;
            case LEFTFLIP:
            case LEFT:
            case RIGHTFLIP:
            case RIGHT:
                if (grid_->getHLine(adjusted.i + i, adjusted.j + j) == EMPTY) {
                    grid_->setValid(grid_->setHLine(adjusted.i + i, adjusted.j + j, pattern.edge));
                    grid_->setUpdated(true);
                }
                break;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x18(%rbp), %rdi
callq 0xfda0
movl %eax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0xfdb0
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rdi
callq 0xfdd0
movq %rax, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movslq -0x34(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x30(%rbp), %rdi
callq 0x79f0
movq %rax, %rcx
movq -0x78(%rbp), %rax
cmpq %rcx, %rax
jae 0xf9f7
movq -0x30(%rbp), %rdi
movslq -0x34(%rbp), %rsi
callq 0xfdf0
movl 0x8(%rax), %ecx
movl %ecx, -0x38(%rbp)
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movl -0x40(%rbp), %edi
movl -0x3c(%rbp), %esi
movl -0x20(%rbp), %edx
movl -0x24(%rbp), %ecx
movl -0x1c(%rbp), %r8d
callq 0xaa60
movq %rax, -0x48(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x7c(%rbp)
subl $0x2, %eax
jb 0xf910
jmp 0xf8e2
movl -0x7c(%rbp), %eax
addl $-0x2, %eax
subl $0x2, %eax
jb 0xf97b
jmp 0xf8f3
movl -0x7c(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0xf910
jmp 0xf900
movl -0x7c(%rbp), %eax
addl $-0x6, %eax
subl $0x2, %eax
jb 0xf97b
jmp 0xf9e7
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x48(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x44(%rbp), %edx
addl -0x10(%rbp), %edx
callq 0x5bf0
cmpl $0x0, %eax
jne 0xf979
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rcx
movq %rcx, -0x88(%rbp)
movq 0x8(%rax), %rdi
movl -0x48(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x44(%rbp), %edx
addl -0x10(%rbp), %edx
movl -0x38(%rbp), %ecx
movq (%rdi), %rax
callq *(%rax)
movq -0x88(%rbp), %rdi
movzbl %al, %esi
andl $0x1, %esi
callq 0xfe10
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x1, %esi
callq 0xfc50
jmp 0xf9e7
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x48(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x44(%rbp), %edx
addl -0x10(%rbp), %edx
callq 0x5c90
cmpl $0x0, %eax
jne 0xf9e5
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rcx
movq %rcx, -0x90(%rbp)
movq 0x8(%rax), %rdi
movl -0x48(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x44(%rbp), %edx
addl -0x10(%rbp), %edx
movl -0x38(%rbp), %ecx
movq (%rdi), %rax
callq *0x8(%rax)
movq -0x90(%rbp), %rdi
movzbl %al, %esi
andl $0x1, %esi
callq 0xfe10
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x1, %esi
callq 0xfc50
jmp 0xf9e7
jmp 0xf9e9
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0xf881
movq -0x18(%rbp), %rdi
callq 0xfe50
movq %rax, -0x50(%rbp)
movl $0x0, -0x54(%rbp)
movslq -0x54(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x50(%rbp), %rdi
callq 0x79f0
movq %rax, %rcx
movq -0x98(%rbp), %rax
cmpq %rcx, %rax
jae 0xfb93
movq -0x50(%rbp), %rdi
movslq -0x54(%rbp), %rsi
callq 0xfdf0
movl 0x8(%rax), %ecx
movl %ecx, -0x58(%rbp)
movq (%rax), %rax
movq %rax, -0x60(%rbp)
movl -0x60(%rbp), %edi
movl -0x5c(%rbp), %esi
movl -0x20(%rbp), %edx
movl -0x24(%rbp), %ecx
movl -0x1c(%rbp), %r8d
callq 0xaaa0
movq %rax, -0x68(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x9c(%rbp)
subl $0x2, %eax
jb 0xfaac
jmp 0xfa75
movl -0x9c(%rbp), %eax
addl $-0x2, %eax
subl $0x2, %eax
jb 0xfb18
jmp 0xfa89
movl -0x9c(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0xfaac
jmp 0xfa99
movl -0x9c(%rbp), %eax
addl $-0x6, %eax
subl $0x2, %eax
jb 0xfb18
jmp 0xfb83
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x68(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x64(%rbp), %edx
addl -0x10(%rbp), %edx
callq 0x5c90
cmpl $0x0, %eax
jne 0xfb16
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rcx
movq %rcx, -0xa8(%rbp)
movq 0x8(%rax), %rdi
movl -0x68(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x64(%rbp), %edx
addl -0x10(%rbp), %edx
movl -0x58(%rbp), %ecx
movq (%rdi), %rax
callq *0x8(%rax)
movq -0xa8(%rbp), %rdi
movzbl %al, %esi
andl $0x1, %esi
callq 0xfe10
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x1, %esi
callq 0xfc50
jmp 0xfb83
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x68(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x64(%rbp), %edx
addl -0x10(%rbp), %edx
callq 0x5bf0
cmpl $0x0, %eax
jne 0xfb81
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rcx
movq %rcx, -0xb0(%rbp)
movq 0x8(%rax), %rdi
movl -0x68(%rbp), %esi
addl -0xc(%rbp), %esi
movl -0x64(%rbp), %edx
addl -0x10(%rbp), %edx
movl -0x58(%rbp), %ecx
movq (%rdi), %rax
callq *(%rax)
movq -0xb0(%rbp), %rdi
movzbl %al, %esi
andl $0x1, %esi
callq 0xfe10
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x1, %esi
callq 0xfc50
jmp 0xfb83
jmp 0xfb85
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0xfa0b
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax)