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

    if (grid_->getHLine(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.setHLine(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.setHLine(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_->setHLine(i, j, NLINE);
            return;
        } else {
            Grid nLineGuess;
            grid_->copy(nLineGuess);

            /* make an NLINE guess */
            nLineGuess.setHLine(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_->setHLine(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 0xdefd
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
addl $0x1, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x379(%rbp)
jge 0xdefd
xorl %eax, %eax
xorl %ecx, %ecx
cmpl -0x10(%rbp), %ecx
movb %al, -0x379(%rbp)
jg 0xdefd
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
cmpl %ecx, %eax
setl %al
movb %al, -0x379(%rbp)
movb -0x379(%rbp), %al
testb $0x1, %al
jne 0xdf09
jmp 0xdf0b
jmp 0xdf2a
leaq 0x7552(%rip), %rdi      # 0x15464
leaq 0x7591(%rip), %rsi      # 0x154aa
movl $0xc8, %edx
leaq 0x759b(%rip), %rcx      # 0x154c0
callq 0x2120
cmpl $0x0, -0x14(%rbp)
jl 0xdf32
jmp 0xdf51
leaq 0x75b2(%rip), %rdi      # 0x154eb
leaq 0x756a(%rip), %rsi      # 0x154aa
movl $0xc9, %edx
leaq 0x7574(%rip), %rcx      # 0x154c0
callq 0x2120
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
callq 0x5bf0
cmpl $0x0, %eax
jne 0xe7b7
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 0xdfae
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
leaq -0x70(%rbp), %rdi
movl $0x1, %ecx
callq 0x3860
jmp 0xdfc4
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 0xe010
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 0xe054
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 0xe084
movb -0x3b9(%rbp), %al
testb $0x1, %al
jne 0xe093
jmp 0xe2df
leaq -0x168(%rbp), %rdi
callq 0xfc90
jmp 0xe0a1
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x168(%rbp), %rsi
callq 0x2ea0
jmp 0xe0ba
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
leaq -0x168(%rbp), %rdi
movl $0x2, %ecx
callq 0x3860
jmp 0xe0d3
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 0xe116
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 0xe15b
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 0xe18e
movb -0x3d9(%rbp), %al
testb $0x1, %al
jne 0xe19d
jmp 0xe242
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x70(%rbp), %rdi
callq 0x2ea0
jmp 0xe1b3
jmp 0xe2a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe7ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x110(%rbp), %rdi
callq 0xfbc0
jmp 0xe7ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe7a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe2ce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0xfbc0
jmp 0xe2ce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0xfcf0
jmp 0xe2ce
leaq -0x168(%rbp), %rdi
callq 0x4830
movb %al, -0x3da(%rbp)
jmp 0xe256
movb -0x3da(%rbp), %al
testb $0x1, %al
jne 0xe282
jmp 0xe262
leaq -0x1d0(%rbp), %rdi
callq 0xfcd0
movb %al, -0x3db(%rbp)
jmp 0xe276
movb -0x3db(%rbp), %al
testb $0x1, %al
jne 0xe282
jmp 0xe28f
movq -0x388(%rbp), %rax
movb $0x1, 0x64(%rax)
jmp 0xe2a5
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %esi, %esi
callq 0xfc50
jmp 0xe2a3
jmp 0xe2a5
jmp 0xe2a7
movl $0x1, -0x1fc(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0xfcf0
leaq -0x168(%rbp), %rdi
callq 0x2b10
jmp 0xe77b
leaq -0x168(%rbp), %rdi
callq 0x2b10
jmp 0xe7a0
leaq -0xe8(%rbp), %rdi
callq 0xd170
movb %al, -0x3dc(%rbp)
jmp 0xe2f3
movb -0x3dc(%rbp), %al
testb $0x1, %al
jne 0xe2ff
jmp 0xe32e
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movq (%rdi), %rax
movq (%rax), %rax
movl $0x2, %ecx
callq *%rax
jmp 0xe31f
movl $0x1, -0x1fc(%rbp)
jmp 0xe77b
leaq -0x258(%rbp), %rdi
callq 0xfc90
jmp 0xe33c
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
leaq -0x258(%rbp), %rsi
callq 0x2ea0
jmp 0xe355
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
leaq -0x258(%rbp), %rdi
movl $0x2, %ecx
callq 0x3860
jmp 0xe36e
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 0xe3ba
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 0xe401
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 0xe434
movb -0x401(%rbp), %al
testb $0x1, %al
jne 0xe460
jmp 0xe440
leaq -0xe8(%rbp), %rdi
callq 0xfcd0
movb %al, -0x402(%rbp)
jmp 0xe454
movb -0x402(%rbp), %al
testb $0x1, %al
jne 0xe460
jmp 0xe4b9
movq -0x388(%rbp), %rax
movb $0x1, 0x64(%rax)
movl $0x1, -0x1fc(%rbp)
jmp 0xe72f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe761
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0xfbc0
jmp 0xe761
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0xe755
leaq -0x258(%rbp), %rdi
callq 0x4830
movb %al, -0x403(%rbp)
jmp 0xe4cd
movb -0x403(%rbp), %al
testb $0x1, %al
jne 0xe4dc
jmp 0xe676
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 0xe51f
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 0xe561
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 0xe5c1
movb -0x421(%rbp), %al
testb $0x1, %al
jne 0xe5cd
jmp 0xe605
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x258(%rbp), %rdi
callq 0x2ea0
jmp 0xe5e6
jmp 0xe667
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x378(%rbp), %rdi
callq 0xfbc0
jmp 0xe755
leaq -0x70(%rbp), %rdi
callq 0x4830
movb %al, -0x439(%rbp)
jmp 0xe616
movb -0x439(%rbp), %al
testb $0x1, %al
jne 0xe642
jmp 0xe622
leaq -0xe8(%rbp), %rdi
callq 0xfcd0
movb %al, -0x43a(%rbp)
jmp 0xe636
movb -0x43a(%rbp), %al
testb $0x1, %al
jne 0xe642
jmp 0xe64f
movq -0x388(%rbp), %rax
movb $0x1, 0x64(%rax)
jmp 0xe665
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %esi, %esi
callq 0xfc50
jmp 0xe663
jmp 0xe665
jmp 0xe667
movl $0x1, -0x1fc(%rbp)
jmp 0xe72f
leaq -0x2c0(%rbp), %rdi
callq 0xd170
movb %al, -0x43b(%rbp)
jmp 0xe68a
movb -0x43b(%rbp), %al
testb $0x1, %al
jne 0xe696
jmp 0xe6c2
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movq (%rdi), %rax
movq (%rax), %rax
movl $0x1, %ecx
callq *%rax
jmp 0xe6b6
movl $0x1, -0x1fc(%rbp)
jmp 0xe72f
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
xorl %esi, %esi
callq 0xfc50
jmp 0xe6d6
movq -0x388(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0x258(%rbp), %rdx
callq 0xf140
jmp 0xe6ef
movq -0x388(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xfc70
movb %al, -0x43c(%rbp)
jmp 0xe707
movb -0x43c(%rbp), %al
testb $0x1, %al
jne 0xe713
jmp 0xe71f
movl $0x1, -0x1fc(%rbp)
jmp 0xe72f
jmp 0xe721
jmp 0xe723
jmp 0xe725
movl $0x0, -0x1fc(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0xfcf0
leaq -0x258(%rbp), %rdi
callq 0x2b10
movl -0x1fc(%rbp), %eax
testl %eax, %eax
jne 0xe77b
jmp 0xe753
jmp 0xe76f
leaq -0x2c0(%rbp), %rdi
callq 0xfcf0
leaq -0x258(%rbp), %rdi
callq 0x2b10
jmp 0xe7a0
jmp 0xe771
movl $0x0, -0x1fc(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xfcf0
leaq -0x70(%rbp), %rdi
callq 0x2b10
movl -0x1fc(%rbp), %eax
testl %eax, %eax
je 0xe79e
jmp 0xe79c
jmp 0xe7b7
jmp 0xe7b7
leaq -0xe8(%rbp), %rdi
callq 0xfcf0
leaq -0x70(%rbp), %rdi
callq 0x2b10
jmp 0xe7c0
addq $0x450, %rsp            # imm = 0x450
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x22c0
nopl (%rax)