public void TryInitFor_UpdatesPossibles()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                new int?[] { 3, 2, 4, 1 }
            });
            var rules = new IRule[]
            {
                new RowUniquenessRule(),
                new ColumnUniquenessRule(),
                new BoxUniquenessRule()
            };
            var ruleKeeper = new DynamicRuleKeeper(rules);

            Assert.True(ruleKeeper.TryInit(puzzle));

            Assert.NotNull(ruleKeeper);
            Assert.Equal(new BitVector(0b11000), puzzle.GetPossibleValues(new Coordinate(0, 1)));
            Assert.Equal(new BitVector(0b01000), puzzle.GetPossibleValues(new Coordinate(0, 2)));
            Assert.Equal(new BitVector(0b10100), puzzle.GetPossibleValues(new Coordinate(1, 0)));
            Assert.Equal(new BitVector(0b11000), puzzle.GetPossibleValues(new Coordinate(1, 1)));
            Assert.Equal(new BitVector(0b11000), puzzle.GetPossibleValues(new Coordinate(1, 3)));
            Assert.Equal(new BitVector(0b10000), puzzle.GetPossibleValues(new Coordinate(2, 0)));
            Assert.Equal(new BitVector(0b10010), puzzle.GetPossibleValues(new Coordinate(2, 1)));
            Assert.Equal(new BitVector(0b01100), puzzle.GetPossibleValues(new Coordinate(2, 2)));
            Assert.Equal(new BitVector(0b01000), puzzle.GetPossibleValues(new Coordinate(2, 3)));
        }
示例#2
0
        public void TrySolve_MegaPuzzle_Solves()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { null, null, null, null, 10, 1, null, 8, null, 15, 3, 11, null, 2, 16, null },
                new int?[] { 14, null, 2, null, null, 4, 3, null, null, 13, 8, null, null, 12, null, null },
                new int?[] { null, null, null, 12, null, null, null, 15, null, null, null, 7, null, null, 9, 10 },
                new int?[] { 1, 10, 15, null, 6, null, null, null, null, 14, null, null, null, null, null, 11 },
                new int?[] { null, 11, 14, 6, null, null, null, 9, 13, 8, null, null, null, null, 2, 3 },
                new int?[] { 12, null, null, null, 4, null, 7, 3, 11, 6, null, null, 16, null, 5, null },
                new int?[] { 13, 16, null, 2, null, null, null, 1, null, null, 5, null, 10, 9, null, null },
                new int?[] { null, 4, null, null, 13, null, 2, null, null, null, 16, 3, 11, null, null, null },
                new int?[] { null, null, null, 10, 3, 6, null, null, null, 9, null, 12, null, null, 4, null },
                new int?[] { null, null, 12, 15, null, 9, null, null, 7, null, null, null, 1, null, 3, 14 },
                new int?[] { null, 1, null, 4, null, null, 5, 12, 3, 10, null, 8, null, null, null, 2 },
                new int?[] { 3, 6, null, null, null, null, 15, 10, 4, null, null, null, 12, 5, 7, null },
                new int?[] { 2, null, null, null, null, null, 4, null, null, null, null, 15, null, 16, 11, 9 },
                new int?[] { 4, 14, null, null, 16, null, null, null, 2, null, null, null, 6, null, null, null },
                new int?[] { null, null, 16, null, null, 7, 8, null, null, 4, 10, null, null, 14, null, 5 },
                new int?[] { null, 3, 6, null, 9, 12, 14, null, 8, null, 13, 16, null, null, null, null }
            });
            var rowRule      = new RowUniquenessRule();
            var columnRule   = new ColumnUniquenessRule();
            var boxRule      = new BoxUniquenessRule();
            var diagonalRule = new DiagonalUniquenessRule();
            var ruleKeeper   = new DynamicRuleKeeper(
                new IRule[] { rowRule, columnRule, boxRule, diagonalRule });
            var heuristic = new StandardHeuristic(
                rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver <PuzzleWithPossibleValues>(ruleKeeper, heuristic);

            Assert.True(solver.TrySolve(puzzle));
            _AssertMegaPuzzleSolved(puzzle);
        }
        public void TrySet_WithValueThatCausesNoPossiblesForOtherSquare_FailsAndLeavesUnchanged()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                new int?[] { 3, 2, 4, 1 }
            });
            var rules = new IRule[]
            {
                new RowUniquenessRule(),
                new ColumnUniquenessRule(),
                new BoxUniquenessRule()
            };
            var ruleKeeper = new DynamicRuleKeeper(rules);

            Assert.True(ruleKeeper.TryInit(puzzle));
            IDictionary <Coordinate, BitVector> initialPossibleValues = _RetrieveAllUnsetPossibleValues(puzzle);
            var coord = new Coordinate(1, 0);
            int val   = 4;

            Assert.False(ruleKeeper.TrySet(coord, val));

            foreach (Coordinate c in puzzle.GetUnsetCoords())
            {
                Assert.Equal(initialPossibleValues[c], puzzle.GetPossibleValues(in c));
            }
        }
        public void Constructor_UpdatesPossibles()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { 1, null /* 4 */, null /* 3 */, 2 },
                { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                { 3, 2, 4, 1 }
            });
            var possibleValues = new PossibleValues(puzzle);
            var rules          = new List <ISudokuRule>
            {
                new RowUniquenessRule(puzzle, possibleValues.AllPossible),
                new ColumnUniquenessRule(puzzle, possibleValues.AllPossible),
                new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true)
            };
            var ruleKeeper = new DynamicRuleKeeper(puzzle, possibleValues, rules);

            Assert.NotNull(ruleKeeper);
            Assert.Equal(new BitVector(0b11000), possibleValues[new Coordinate(0, 1)]);
            Assert.Equal(new BitVector(0b01000), possibleValues[new Coordinate(0, 2)]);
            Assert.Equal(new BitVector(0b10100), possibleValues[new Coordinate(1, 0)]);
            Assert.Equal(new BitVector(0b11000), possibleValues[new Coordinate(1, 1)]);
            Assert.Equal(new BitVector(0b11000), possibleValues[new Coordinate(1, 3)]);
            Assert.Equal(new BitVector(0b10000), possibleValues[new Coordinate(2, 0)]);
            Assert.Equal(new BitVector(0b10010), possibleValues[new Coordinate(2, 1)]);
            Assert.Equal(new BitVector(0b01100), possibleValues[new Coordinate(2, 2)]);
            Assert.Equal(new BitVector(0b01000), possibleValues[new Coordinate(2, 3)]);
        }
        public void Revert_RevertsSpecifiedCoordinate()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                new int?[] { 3, 2, 4, 1 }
            });
            var rules = new IRule[]
            {
                new RowUniquenessRule(),
                new ColumnUniquenessRule(),
                new BoxUniquenessRule()
            };
            var ruleKeeper = new DynamicRuleKeeper(rules);

            Assert.True(ruleKeeper.TryInit(puzzle));
            IDictionary <Coordinate, BitVector> initialPossibleValues = _RetrieveAllUnsetPossibleValues(puzzle);
            var coord = new Coordinate(1, 1);
            int val   = 3;

            Assert.True(ruleKeeper.TrySet(in coord, val));

            ruleKeeper.Unset(in coord, val);

            foreach (Coordinate c in puzzle.GetUnsetCoords())
            {
                Assert.Equal(initialPossibleValues[c], puzzle.GetPossibleValues(in c));
            }
        }
        public void TrySet_WithValidValue_Succeeds()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { 1, null /* 4 */, null /* 3 */, 2 },
                { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                { 3, 2, 4, 1 }
            });
            var possibleValues = new PossibleValues(puzzle);
            var rules          = new List <ISudokuRule>
            {
                new RowUniquenessRule(puzzle, possibleValues.AllPossible),
                new ColumnUniquenessRule(puzzle, possibleValues.AllPossible),
                new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true)
            };
            var ruleKeeper = new DynamicRuleKeeper(puzzle, possibleValues, rules);
            var coord      = new Coordinate(1, 1);
            int val        = 3;

            Assert.True(ruleKeeper.TrySet(coord, val));
            puzzle[coord] = val;
            Assert.Equal(new BitVector(0b10000), possibleValues[new Coordinate(0, 1)]);
            Assert.Equal(new BitVector(0b10100), possibleValues[new Coordinate(1, 0)]);
            Assert.Equal(new BitVector(0b10000), possibleValues[new Coordinate(1, 3)]);
            Assert.Equal(new BitVector(0b10010), possibleValues[new Coordinate(2, 1)]);
        }
        public void CopyWithNewReferences_WithoutIMissingBoxValuesTracker_Throws()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { null /* 1 */, null /* 4 */, 3, 2 },
                { null /* 2 */, null /* 3 */, null /* 1 */, 4 },
                { null /* 4 */, null /* 1 */, 2, 3 },
                { 3, null /* 2 */, 4, 1 }
            });
            var possibleValues = new PossibleValues(puzzle);
            var boxRule        = new BoxUniquenessRule(puzzle, possibleValues.AllPossible, false);
            var ruleKeeper     = new DynamicRuleKeeper(puzzle, possibleValues, new List <ISudokuRule> {
                boxRule
            });
            var heuristic = new UniqueInBoxHeuristic(
                puzzle, possibleValues, boxRule);

            var puzzleCopy                  = new Puzzle(puzzle);
            var possibleValuesCopy          = new PossibleValues(possibleValues);
            var ruleKeeperWithoutBoxTracker = new DynamicRuleKeeper(puzzleCopy, possibleValuesCopy,
                                                                    new List <ISudokuRule> {
                new ColumnUniquenessRule(puzzleCopy, possibleValues.AllPossible),
            });

            Assert.Throws <ArgumentException>(() => heuristic.CopyWithNewReferences(
                                                  puzzleCopy, possibleValuesCopy, ruleKeeperWithoutBoxTracker.GetRules()));
        }
        public void TrySet_WithValidValue_Succeeds()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                new int?[] { 3, 2, 4, 1 }
            });
            var rules = new IRule[]
            {
                new RowUniquenessRule(),
                new ColumnUniquenessRule(),
                new BoxUniquenessRule()
            };
            var ruleKeeper = new DynamicRuleKeeper(rules);

            Assert.True(ruleKeeper.TryInit(puzzle));
            var coord = new Coordinate(1, 1);
            int val   = 3;

            Assert.True(ruleKeeper.TrySet(coord, val));

            puzzle[coord] = val;
            Assert.Equal(new BitVector(0b10000), puzzle.GetPossibleValues(new Coordinate(0, 1)));
            Assert.Equal(new BitVector(0b10100), puzzle.GetPossibleValues(new Coordinate(1, 0)));
            Assert.Equal(new BitVector(0b10000), puzzle.GetPossibleValues(new Coordinate(1, 3)));
            Assert.Equal(new BitVector(0b10010), puzzle.GetPossibleValues(new Coordinate(2, 1)));
        }
示例#9
0
        public bool SudokuSpiceDynamicSingle(PuzzleSample puzzle)
        {
            var p             = new PuzzleWithPossibleValues(puzzle.NullableJaggedMatrix);
            var standardRules = new StandardRules();
            var ruleKeeper    = new DynamicRuleKeeper(
                new IRule[] { standardRules });
            var heuristic = new StandardHeuristic(
                standardRules, standardRules, standardRules);
            var solver = new RuleBased.PuzzleSolver <PuzzleWithPossibleValues>(ruleKeeper, heuristic);
            var result = solver.Solve(p, randomizeGuesses: true);

            return(result.NumEmptySquares == 0);
        }
示例#10
0
        public bool SudokuSpiceDynamicMultiple(PuzzleSample puzzle)
        {
            var p          = new PuzzleWithPossibleValues(puzzle.NullableJaggedMatrix);
            var rowRule    = new RowUniquenessRule();
            var columnRule = new ColumnUniquenessRule();
            var boxRule    = new BoxUniquenessRule();
            var ruleKeeper = new DynamicRuleKeeper(
                new IRule[] { rowRule, columnRule, boxRule });
            var heuristic = new StandardHeuristic(
                rowRule, columnRule, boxRule);
            var solver = new RuleBased.PuzzleSolver <PuzzleWithPossibleValues>(ruleKeeper, heuristic);
            var result = solver.Solve(p, randomizeGuesses: true);

            return(result.NumEmptySquares == 0);
        }
示例#11
0
        public bool SudokuSpiceDynamicSingle(PuzzleSample puzzle)
        {
            var p = new Puzzle(puzzle.NullableMatrix);
            var possibleValues = new PossibleValues(p);
            var standardRules  = new StandardRules(p, possibleValues.AllPossible);
            var ruleKeeper     = new DynamicRuleKeeper(
                p, possibleValues,
                new List <ISudokuRule> {
                standardRules
            });
            var heuristic = new StandardHeuristic(
                p, possibleValues, standardRules, standardRules, standardRules);
            var solver = new PuzzleSolver(p, possibleValues, ruleKeeper, heuristic);

            solver.SolveRandomly();
            return(p.NumEmptySquares == 0);
        }
示例#12
0
        public void Solve_ValidPuzzle_SolvesPuzzle(Puzzle puzzle)
        {
            var possibleValues = new PossibleValues(puzzle);
            var rowRule        = new RowUniquenessRule(puzzle, possibleValues.AllPossible);
            var columnRule     = new ColumnUniquenessRule(puzzle, possibleValues.AllPossible);
            var boxRule        = new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true);
            var ruleKeeper     = new DynamicRuleKeeper(
                puzzle, possibleValues,
                new List <ISudokuRule> {
                rowRule, columnRule, boxRule
            });
            var heuristic = new StandardHeuristic(
                puzzle, possibleValues, rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver(puzzle, possibleValues, ruleKeeper, heuristic);

            solver.Solve();
            _AssertPuzzleSolved(puzzle);
        }
示例#13
0
        public bool SudokuSpiceDynamicMultiple(PuzzleSample puzzle)
        {
            var p = new Puzzle(puzzle.NullableMatrix);
            var possibleValues = new PossibleValues(p);
            var rowRule        = new RowUniquenessRule(p, possibleValues.AllPossible);
            var columnRule     = new ColumnUniquenessRule(p, possibleValues.AllPossible);
            var boxRule        = new BoxUniquenessRule(p, possibleValues.AllPossible, true);
            var ruleKeeper     = new DynamicRuleKeeper(
                p, possibleValues,
                new List <ISudokuRule> {
                rowRule, columnRule, boxRule
            });
            var heuristic = new StandardHeuristic(
                p, possibleValues, rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver(p, possibleValues, ruleKeeper, heuristic);

            solver.SolveRandomly();
            return(p.NumEmptySquares == 0);
        }
        public void TryInitFor_WhenSquareHasNoPossibleValues_Fails()
        {
            var puzzle = new PuzzleWithPossibleValues(
                new int?[][] {
                new int?[] { 1, 3 /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                new int?[] { 3, 2, 4, 1 }
            });
            var rules = new IRule[]
            {
                new RowUniquenessRule(),
                new ColumnUniquenessRule(),
                new BoxUniquenessRule()
            };
            var ruleKeeper = new DynamicRuleKeeper(rules);

            Assert.False(ruleKeeper.TryInit(puzzle));
        }
        public void CopyWithNewReferences_CreatesDeepCopy()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                new int?[] { 3, 2, 4, 1 }
            });
            var rules = new IRule[]
            {
                new RowUniquenessRule(),
                new ColumnUniquenessRule(),
                new BoxUniquenessRule()
            };
            var ruleKeeper = new DynamicRuleKeeper(rules);

            Assert.True(ruleKeeper.TryInit(puzzle));

            var         puzzleCopy     = new PuzzleWithPossibleValues(puzzle);
            IRuleKeeper ruleKeeperCopy = ruleKeeper.CopyWithNewReferences(puzzleCopy);

            var rulesCopy = ruleKeeperCopy.GetRules();

            Assert.Equal(rules.Length, rulesCopy.Length);
            for (int i = 0; i < rules.Length; i++)
            {
                Assert.NotSame(rules[i], rulesCopy[i]);
                Type originalType = rules[i].GetType();
                Type copiedType   = rulesCopy[i].GetType();
                Assert.Equal(originalType, copiedType);
            }
            var coord = new Coordinate(0, 1);
            int val   = 4;

            Assert.True(ruleKeeperCopy.TrySet(coord, val));
            Assert.Equal(new BitVector(0b11000), puzzle.GetPossibleValues(new Coordinate(1, 1)));
            Assert.Equal(new BitVector(0b01000), puzzleCopy.GetPossibleValues(new Coordinate(1, 1)));
        }
        public void CopyWithNewReferences_CreatesDeepCopy()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { 1, null /* 4 */, null /* 3 */, 2 },
                { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                { 3, 2, 4, 1 }
            });
            var possibleValues = new PossibleValues(puzzle);
            var rules          = new List <ISudokuRule>
            {
                new RowUniquenessRule(puzzle, possibleValues.AllPossible),
                new ColumnUniquenessRule(puzzle, possibleValues.AllPossible),
                new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true)
            };
            var ruleKeeper = new DynamicRuleKeeper(puzzle, possibleValues, rules);

            var puzzleCopy                   = new Puzzle(puzzle);
            var possibleValuesCopy           = new PossibleValues(possibleValues);
            ISudokuRuleKeeper ruleKeeperCopy = ruleKeeper.CopyWithNewReferences(puzzleCopy, possibleValuesCopy);

            IReadOnlyList <ISudokuRule> rulesCopy = ruleKeeperCopy.GetRules();

            Assert.Equal(rules.Count, rulesCopy.Count);
            for (int i = 0; i < rules.Count; i++)
            {
                Assert.NotSame(rules[i], rulesCopy[i]);
                Type originalType = rules[i].GetType();
                Type copiedType   = rulesCopy[i].GetType();
                Assert.Equal(originalType, copiedType);
            }
            var coord = new Coordinate(0, 1);
            int val   = 4;

            Assert.True(ruleKeeperCopy.TrySet(coord, val));
            Assert.Equal(new BitVector(0b11000), possibleValues[new Coordinate(1, 1)]);
            Assert.Equal(new BitVector(0b01000), possibleValuesCopy[new Coordinate(1, 1)]);
        }
        public void Constructor_WhenSquareHasNoPossibleValues_Throws()
        {
            var puzzle = new Puzzle(
                new int?[, ] {
                { 1, 3 /* 4 */, null /* 3 */, 2 },
                { null /* 2 */, null /* 3 */, 1, null /* 4 */ },
                { null /* 4 */, null /* 1 */, null /* 2 */, null /* 3 */ },
                { 3, 2, 4, 1 }
            });
            var possibleValues = new PossibleValues(puzzle);
            var rules          = new List <ISudokuRule>
            {
                new RowUniquenessRule(puzzle, possibleValues.AllPossible),
                new ColumnUniquenessRule(puzzle, possibleValues.AllPossible),
                new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true)
            };
            ArgumentException ex = Assert.Throws <ArgumentException>(() =>
            {
                var ruleKeeper = new DynamicRuleKeeper(puzzle, possibleValues, rules);
            });

            Assert.Contains("Puzzle could not be solved with the given values", ex.Message);
        }
示例#18
0
        public void Solve_MegaPuzzle_Solves()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { null, null, null, null, 10, 1, null, 8, null, 15, 3, 11, null, 2, 16, null },
                { 14, null, 2, null, null, 4, 3, null, null, 13, 8, null, null, 12, null, null },
                { null, null, null, 12, null, null, null, 15, null, null, null, 7, null, null, 9, 10 },
                { 1, 10, 15, null, 6, null, null, null, null, 14, null, null, null, null, null, 11 },
                { null, 11, 14, 6, null, null, null, 9, 13, 8, null, null, null, null, 2, 3 },
                { 12, null, null, null, 4, null, 7, 3, 11, 6, null, null, 16, null, 5, null },
                { 13, 16, null, 2, null, null, null, 1, null, null, 5, null, 10, 9, null, null },
                { null, 4, null, null, 13, null, 2, null, null, null, 16, 3, 11, null, null, null },
                { null, null, null, 10, 3, 6, null, null, null, 9, null, 12, null, null, 4, null },
                { null, null, 12, 15, null, 9, null, null, 7, null, null, null, 1, null, 3, 14 },
                { null, 1, null, 4, null, null, 5, 12, 3, 10, null, 8, null, null, null, 2 },
                { 3, 6, null, null, null, null, 15, 10, 4, null, null, null, 12, 5, 7, null },
                { 2, null, null, null, null, null, 4, null, null, null, null, 15, null, 16, 11, 9 },
                { 4, 14, null, null, 16, null, null, null, 2, null, null, null, 6, null, null, null },
                { null, null, 16, null, null, 7, 8, null, null, 4, 10, null, null, 14, null, 5 },
                { null, 3, 6, null, 9, 12, 14, null, 8, null, 13, 16, null, null, null, null }
            });
            var possibleValues = new PossibleValues(puzzle);
            var rowRule        = new RowUniquenessRule(puzzle, possibleValues.AllPossible);
            var columnRule     = new ColumnUniquenessRule(puzzle, possibleValues.AllPossible);
            var boxRule        = new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true);
            var diagonalRule   = new DiagonalUniquenessRule(puzzle, possibleValues.AllPossible);
            var ruleKeeper     = new DynamicRuleKeeper(
                puzzle, possibleValues,
                new List <ISudokuRule> {
                rowRule, columnRule, boxRule, diagonalRule
            });
            var heuristic = new StandardHeuristic(
                puzzle, possibleValues, rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver(puzzle, possibleValues, ruleKeeper, heuristic);

            solver.Solve();
            _AssertMegaPuzzleSolved(puzzle);
        }
        public void CopyWithNewReferences_WithoutIMissingBoxValuesTracker_Throws()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { null /* 1 */, null /* 4 */, 3, 2 },
                new int?[] { null /* 2 */, null /* 3 */, null /* 1 */, 4 },
                new int?[] { null /* 4 */, null /* 1 */, 2, 3 },
                new int?[] { 3, null /* 2 */, 4, 1 }
            });
            var ruleKeeper = new StandardRuleKeeper();

            Assert.True(ruleKeeper.TryInit(puzzle));
            var heuristic = new UniqueInBoxHeuristic(
                (IMissingBoxValuesTracker)ruleKeeper.GetRules()[0]);

            Assert.True(heuristic.TryInitFor(puzzle));

            var puzzleCopy = new PuzzleWithPossibleValues(puzzle);
            var ruleKeeperWithoutBoxTracker = new DynamicRuleKeeper(new IRule[] {
                new ColumnUniquenessRule(),
            });

            Assert.Throws <ArgumentException>(() => heuristic.CopyWithNewReferences(
                                                  puzzleCopy, ruleKeeperWithoutBoxTracker.GetRules()));
        }