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))); }
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))); }
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); }
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); }
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); }
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); }
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); }
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())); }