// File: davidjosepha[P]slitherlink/src/solver/solver.cpp
// Function: Solver::makeVLineGuess(int, int, int)
void Solver::makeVLineGuess(int i, int j, int depth) {
    assert(0 <= i && i < grid_->getHeight() && 0 <= j && j < grid_->getWidth()+1);
    assert(depth >= 0);

    if (grid_->getVLine(i, j) == EMPTY) {
        /* there is only one case where the grid
         * will not be updated, which is handled
         * at the end of this iteration. */
        grid_->setUpdated(true);

        Grid lineGuess;
        grid_->copy(lineGuess);

        /* make a LINE guess */
        lineGuess.setVLine(i, j, LINE);
        Solver lineSolver = Solver(lineGuess, rules_, contradictions_, selectedRules_, selectLength_, depth, epq_);
        ruleCounts_ = ruleCounts_ + lineSolver.ruleCounts_;

        /* If this guess happens to solve the puzzle we need to make sure that
         * the opposite guess leads to a contradiction, otherwise we know that
         * there might be multiple solutions */
        if (lineGuess.isSolved()) {
            Grid nLineGuess;
            grid_->copy(nLineGuess);
            nLineGuess.setVLine(i, j, NLINE);
            Solver nLineSolver = Solver(nLineGuess, rules_, contradictions_, selectedRules_, selectLength_, MAX_DEPTH, epq_);
            ruleCounts_ = ruleCounts_ + nLineSolver.ruleCounts_;
            if (nLineSolver.testContradictions()) {
                /* The opposite guess leads to a contradiction
                 * so the previous found solution is the only one */
                lineGuess.copy(*grid_);
            } else if (nLineGuess.isSolved() || nLineSolver.hasMultipleSolutions()) {
                /* The opposite guess also led to a solution
                 * so there are multiple solutions */
                multipleSolutions_ = true;
            } else {
                /* The opposite guess led to neither a solution or
                 * a contradiction, which can only happen if the subPuzzle
                 * is unsolvable for our maximum depth. We can learn nothing
                 * from this result. */
                grid_->setUpdated(false);
            }
            return;
        }
        /* test for contradictions; if we encounter one we set the opposite line */
        else if (lineSolver.testContradictions()) {
            grid_->setVLine(i, j, NLINE);
            return;
        } else {
            Grid nLineGuess;
            grid_->copy(nLineGuess);

            /* make an NLINE guess */
            nLineGuess.setVLine(i, j, NLINE);
            Solver nLineSolver = Solver(nLineGuess, rules_, contradictions_, selectedRules_, selectLength_, depth, epq_);
            ruleCounts_ = ruleCounts_ + nLineSolver.ruleCounts_;

            /* if both guesses led to multiple solutions, we know this puzzle
             * must also lead to another solution */
            if (nLineSolver.hasMultipleSolutions() || lineSolver.hasMultipleSolutions()) {
                multipleSolutions_ = true;
                return;
            }
            /* again check if solved. In this case we already know that we can't
             * get to a solution or contradiction with the opposite guess, so
             * we know we can't conclude whether this is the single solution */
            else if (nLineGuess.isSolved()) {
                lineSolver = Solver(lineGuess, rules_, contradictions_, selectedRules_, selectLength_, MAX_DEPTH, epq_);
                ruleCounts_ = ruleCounts_ + lineSolver.ruleCounts_;
                if (lineSolver.testContradictions()) {
                    /* The opposite guess leads to a contradiction
                     * so the previous found solution is the only one */
                    nLineGuess.copy(*grid_);
                } else if (lineGuess.isSolved() || lineSolver.hasMultipleSolutions()) {
                    /* The opposite guess also led to a solution
                     * so there are multiple solutions */
                    multipleSolutions_ = true;
                } else {
                    /* The opposite guess led to neither a solution or
                     * a contradiction, which can only happen if the subPuzzle
                     * is unsolvable for our maximum depth. We can learn nothing
                     * from this result. */
                    grid_->setUpdated(false);
                }
                return;
            }
            /* again check for contradictions */
            else if (nLineSolver.testContradictions()) {
                grid_->setVLine(i, j, LINE);
                return;
            } else {
                grid_->setUpdated(false);

                /* check for things that happen when we make both
                 * guesses; if we find any, we know they must happen */
                intersectGrids(lineGuess, nLineGuess);

                if (grid_->getUpdated()) {
                    return;
                }
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x450, %rsp            # imm = 0x450
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x388(%rbp)
xorl %eax, %eax
xorl %ecx, %ecx
cmpl -0xc(%rbp), %ecx
movb %al, -0x379(%rbp)
jg 0xe86d
movq -0x388(%rbp), %rax
movl -0xc(%rbp), %ecx
movl %ecx, -0x38c(%rbp)
movq 0x8(%rax), %rdi
callq 0x2ad0
movl -0x38c(%rbp), %ecx
movl %eax, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x379(%rbp)
jge 0xe86d
xorl %eax, %eax
xorl %ecx, %ecx
cmpl -0x10(%rbp), %ecx
movb %al, -0x379(%rbp)
jg 0xe86d
movq -0x388(%rbp), %rax
movl -0x10(%rbp), %ecx
movl %ecx, -0x390(%rbp)
movq 0x8(%rax), %rdi
callq 0x2af0
movl %eax, %ecx
movl -0x390(%rbp), %eax
addl $0x1, %ecx
cmpl %ecx, %eax
setl %al
movb %al, -0x379(%rbp)
movb -0x379(%rbp), %al
testb $0x1, %al
jne 0xe879
jmp 0xe87b
jmp 0xe89a
leaq 0x6c74(%rip), %rdi      # 0x154f6
leaq 0x6c21(%rip), %rsi      # 0x154aa
movl $0x132, %edx            # imm = 0x132
leaq 0x6ca7(%rip), %rcx      # 0x1553c
callq 0x2120
cmpl $0x0, -0x14(%rbp)
jl 0xe8a2
jmp 0xe8c1
leaq 0x6c42(%rip), %rdi      # 0x154eb
leaq 0x6bfa(%rip), %rsi      # 0x154aa
movl $0x133, %edx            # imm = 0x133
leaq 0x6c80(%rip), %rcx      # 0x1553c
callq 0x2120
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
callq 0x5c90
cmpl $0x0, %eax
jne 0xf129
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x1, %esi
callq 0xfc50
leaq -0x70(%rbp), %rdi
movq %rdi, -0x398(%rbp)
callq 0xfc90
movq -0x388(%rbp), %rax
movq -0x398(%rbp), %rsi
movq 0x8(%rax), %rdi
callq 0x2ea0
jmp 0xe91e
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
leaq -0x70(%rbp), %rdi
movl $0x1, %ecx
callq 0x4280
jmp 0xe934
movq -0x388(%rbp), %rsi
movq 0x18(%rsi), %rax
movq %rax, -0x3b8(%rbp)
movq 0x20(%rsi), %rax
movq %rax, -0x3b0(%rbp)
movq 0x30(%rsi), %rax
movq %rax, -0x3a8(%rbp)
movl 0x28(%rsi), %eax
movl %eax, -0x3a0(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x39c(%rbp)
addq $0x38, %rsi
leaq -0x110(%rbp), %rdi
callq 0xfbe0
jmp 0xe980
movl -0x3a0(%rbp), %r9d
movq -0x3b0(%rbp), %r8
movq -0x3a8(%rbp), %rcx
movq -0x3b8(%rbp), %rdx
movl -0x39c(%rbp), %esi
movq %rsp, %rax
leaq -0x110(%rbp), %rdi
movq %rdi, 0x8(%rax)
movl %esi, (%rax)
leaq -0xe8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xd040
jmp 0xe9c4
leaq -0x110(%rbp), %rdi
callq 0xfbc0
movq -0x388(%rbp), %rax
movl (%rax), %ecx
movl -0xe8(%rbp), %edx
addl %edx, %ecx
movl %ecx, (%rax)
leaq -0x70(%rbp), %rdi
callq 0x4830
movb %al, -0x3b9(%rbp)
jmp 0xe9f4
movb -0x3b9(%rbp), %al
testb $0x1, %al
jne 0xea03
jmp 0xec4f
leaq -0x168(%rbp), %rdi
callq 0xfc90
jmp 0xea11
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x168(%rbp), %rsi
callq 0x2ea0
jmp 0xea2a
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
leaq -0x168(%rbp), %rdi
movl $0x2, %ecx
callq 0x4280
jmp 0xea43
movq -0x388(%rbp), %rsi
movq 0x18(%rsi), %rax
movq %rax, -0x3d8(%rbp)
movq 0x20(%rsi), %rax
movq %rax, -0x3d0(%rbp)
movq 0x30(%rsi), %rax
movq %rax, -0x3c8(%rbp)
movl 0x28(%rsi), %eax
movl %eax, -0x3c0(%rbp)
addq $0x38, %rsi
leaq -0x1f8(%rbp), %rdi
callq 0xfbe0
jmp 0xea86
movl -0x3c0(%rbp), %r9d
movq -0x3d0(%rbp), %r8
movq -0x3c8(%rbp), %rcx
movq -0x3d8(%rbp), %rdx
movq %rsp, %rax
leaq -0x1f8(%rbp), %rsi
movq %rsi, 0x8(%rax)
movl $0x64, (%rax)
leaq -0x1d0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0xd040
jmp 0xeacb
leaq -0x1f8(%rbp), %rdi
callq 0xfbc0
movq -0x388(%rbp), %rax
movl (%rax), %ecx
movl -0x1d0(%rbp), %edx
addl %edx, %ecx
movl %ecx, (%rax)
leaq -0x1d0(%rbp), %rdi
callq 0xd170
movb %al, -0x3d9(%rbp)
jmp 0xeafe
movb -0x3d9(%rbp), %al
testb $0x1, %al
jne 0xeb0d
jmp 0xebb2
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x70(%rbp), %rdi
callq 0x2ea0
jmp 0xeb23
jmp 0xec17
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xf11e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x110(%rbp), %rdi
callq 0xfbc0
jmp 0xf11e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xf112
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xec3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0xfbc0
jmp 0xec3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0xfcf0
jmp 0xec3e
leaq -0x168(%rbp), %rdi
callq 0x4830
movb %al, -0x3da(%rbp)
jmp 0xebc6
movb -0x3da(%rbp), %al
testb $0x1, %al
jne 0xebf2
jmp 0xebd2
leaq -0x1d0(%rbp), %rdi
callq 0xfcd0
movb %al, -0x3db(%rbp)
jmp 0xebe6
movb -0x3db(%rbp), %al
testb $0x1, %al
jne 0xebf2
jmp 0xebff
movq -0x388(%rbp), %rax
movb $0x1, 0x64(%rax)
jmp 0xec15
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %esi, %esi
callq 0xfc50
jmp 0xec13
jmp 0xec15
jmp 0xec17
movl $0x1, -0x1fc(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0xfcf0
leaq -0x168(%rbp), %rdi
callq 0x2b10
jmp 0xf0ed
leaq -0x168(%rbp), %rdi
callq 0x2b10
jmp 0xf112
leaq -0xe8(%rbp), %rdi
callq 0xd170
movb %al, -0x3dc(%rbp)
jmp 0xec63
movb -0x3dc(%rbp), %al
testb $0x1, %al
jne 0xec6f
jmp 0xec9f
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movq (%rdi), %rax
movq 0x8(%rax), %rax
movl $0x2, %ecx
callq *%rax
jmp 0xec90
movl $0x1, -0x1fc(%rbp)
jmp 0xf0ed
leaq -0x258(%rbp), %rdi
callq 0xfc90
jmp 0xecad
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x258(%rbp), %rsi
callq 0x2ea0
jmp 0xecc6
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
leaq -0x258(%rbp), %rdi
movl $0x2, %ecx
callq 0x4280
jmp 0xecdf
movq -0x388(%rbp), %rsi
movq 0x18(%rsi), %rax
movq %rax, -0x400(%rbp)
movq 0x20(%rsi), %rax
movq %rax, -0x3f8(%rbp)
movq 0x30(%rsi), %rax
movq %rax, -0x3f0(%rbp)
movl 0x28(%rsi), %eax
movl %eax, -0x3e4(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x3e0(%rbp)
addq $0x38, %rsi
leaq -0x2e8(%rbp), %rdi
callq 0xfbe0
jmp 0xed2b
movl -0x3e4(%rbp), %r9d
movq -0x3f8(%rbp), %r8
movq -0x3f0(%rbp), %rcx
movq -0x400(%rbp), %rdx
movl -0x3e0(%rbp), %esi
movq %rsp, %rax
leaq -0x2e8(%rbp), %rdi
movq %rdi, 0x8(%rax)
movl %esi, (%rax)
leaq -0x2c0(%rbp), %rdi
leaq -0x258(%rbp), %rsi
callq 0xd040
jmp 0xed72
leaq -0x2e8(%rbp), %rdi
callq 0xfbc0
movq -0x388(%rbp), %rax
movl (%rax), %ecx
movl -0x2c0(%rbp), %edx
addl %edx, %ecx
movl %ecx, (%rax)
leaq -0x2c0(%rbp), %rdi
callq 0xfcd0
movb %al, -0x401(%rbp)
jmp 0xeda5
movb -0x401(%rbp), %al
testb $0x1, %al
jne 0xedd1
jmp 0xedb1
leaq -0xe8(%rbp), %rdi
callq 0xfcd0
movb %al, -0x402(%rbp)
jmp 0xedc5
movb -0x402(%rbp), %al
testb $0x1, %al
jne 0xedd1
jmp 0xee2a
movq -0x388(%rbp), %rax
movb $0x1, 0x64(%rax)
movl $0x1, -0x1fc(%rbp)
jmp 0xf0a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xf0d3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0xfbc0
jmp 0xf0d3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xf0c7
leaq -0x258(%rbp), %rdi
callq 0x4830
movb %al, -0x403(%rbp)
jmp 0xee3e
movb -0x403(%rbp), %al
testb $0x1, %al
jne 0xee4d
jmp 0xefe7
movq -0x388(%rbp), %rsi
movq 0x18(%rsi), %rax
movq %rax, -0x420(%rbp)
movq 0x20(%rsi), %rax
movq %rax, -0x418(%rbp)
movq 0x30(%rsi), %rax
movq %rax, -0x410(%rbp)
movl 0x28(%rsi), %eax
movl %eax, -0x408(%rbp)
addq $0x38, %rsi
leaq -0x378(%rbp), %rdi
callq 0xfbe0
jmp 0xee90
movl -0x408(%rbp), %r9d
movq -0x418(%rbp), %r8
movq -0x410(%rbp), %rcx
movq -0x420(%rbp), %rdx
movq %rsp, %rax
leaq -0x378(%rbp), %rsi
movq %rsi, 0x8(%rax)
movl $0x64, (%rax)
leaq -0x350(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xd040
jmp 0xeed2
leaq -0xe8(%rbp), %rdi
movq %rdi, -0x430(%rbp)
leaq -0x350(%rbp), %rsi
movq %rsi, -0x438(%rbp)
callq 0xfd10
movq -0x438(%rbp), %rdi
callq 0xfcf0
leaq -0x378(%rbp), %rdi
callq 0xfbc0
movq -0x388(%rbp), %rax
movq -0x430(%rbp), %rdi
movl (%rax), %ecx
movl -0xe8(%rbp), %edx
addl %edx, %ecx
movl %ecx, (%rax)
callq 0xd170
movb %al, -0x421(%rbp)
jmp 0xef32
movb -0x421(%rbp), %al
testb $0x1, %al
jne 0xef3e
jmp 0xef76
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x258(%rbp), %rdi
callq 0x2ea0
jmp 0xef57
jmp 0xefd8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x378(%rbp), %rdi
callq 0xfbc0
jmp 0xf0c7
leaq -0x70(%rbp), %rdi
callq 0x4830
movb %al, -0x439(%rbp)
jmp 0xef87
movb -0x439(%rbp), %al
testb $0x1, %al
jne 0xefb3
jmp 0xef93
leaq -0xe8(%rbp), %rdi
callq 0xfcd0
movb %al, -0x43a(%rbp)
jmp 0xefa7
movb -0x43a(%rbp), %al
testb $0x1, %al
jne 0xefb3
jmp 0xefc0
movq -0x388(%rbp), %rax
movb $0x1, 0x64(%rax)
jmp 0xefd6
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %esi, %esi
callq 0xfc50
jmp 0xefd4
jmp 0xefd6
jmp 0xefd8
movl $0x1, -0x1fc(%rbp)
jmp 0xf0a1
leaq -0x2c0(%rbp), %rdi
callq 0xd170
movb %al, -0x43b(%rbp)
jmp 0xeffb
movb -0x43b(%rbp), %al
testb $0x1, %al
jne 0xf007
jmp 0xf034
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movq (%rdi), %rax
movq 0x8(%rax), %rax
movl $0x1, %ecx
callq *%rax
jmp 0xf028
movl $0x1, -0x1fc(%rbp)
jmp 0xf0a1
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %esi, %esi
callq 0xfc50
jmp 0xf048
movq -0x388(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0x258(%rbp), %rdx
callq 0xf140
jmp 0xf061
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xfc70
movb %al, -0x43c(%rbp)
jmp 0xf079
movb -0x43c(%rbp), %al
testb $0x1, %al
jne 0xf085
jmp 0xf091
movl $0x1, -0x1fc(%rbp)
jmp 0xf0a1
jmp 0xf093
jmp 0xf095
jmp 0xf097
movl $0x0, -0x1fc(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0xfcf0
leaq -0x258(%rbp), %rdi
callq 0x2b10
movl -0x1fc(%rbp), %eax
testl %eax, %eax
jne 0xf0ed
jmp 0xf0c5
jmp 0xf0e1
leaq -0x2c0(%rbp), %rdi
callq 0xfcf0
leaq -0x258(%rbp), %rdi
callq 0x2b10
jmp 0xf112
jmp 0xf0e3
movl $0x0, -0x1fc(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xfcf0
leaq -0x70(%rbp), %rdi
callq 0x2b10
movl -0x1fc(%rbp), %eax
testl %eax, %eax
je 0xf110
jmp 0xf10e
jmp 0xf129
jmp 0xf129
leaq -0xe8(%rbp), %rdi
callq 0xfcf0
leaq -0x70(%rbp), %rdi
callq 0x2b10
jmp 0xf132
addq $0x450, %rsp            # imm = 0x450
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x22c0
nopl (%rax,%rax)