/// <summary> /// Constructs a solver for the given square tracker. /// </summary> /// <param name="tracker">A square tracker referencing the puzzle to solve.</param> public PuzzleSolver( IPuzzle puzzle, PossibleValues possibleValues, ISudokuRuleKeeper ruleKeeper, ISudokuHeuristic?heuristic = null) { _tracker = new SquareTracker(puzzle, possibleValues, ruleKeeper, heuristic); }
/// <summary> /// Creates a deep copy of this ISquareTracker in its current state. /// </summary> public SquareTracker(SquareTracker existing) { _puzzle = existing._puzzle.DeepCopy(); _possibleValues = new PossibleValues(existing._possibleValues); _ruleKeeper = existing._ruleKeeper.CopyWithNewReferences(_puzzle, _possibleValues); _heuristic = existing._heuristic?.CopyWithNewReferences( _puzzle, _possibleValues, _ruleKeeper.GetRules()); _setCoords = new Stack <Coordinate>(existing._setCoords); _coordsThatUsedHeuristics = new Stack <Coordinate>(existing._coordsThatUsedHeuristics); }
/// <summary> /// Constructs a square tracker with a <see cref="StandardRuleKeeper"/> and a /// <see cref="StandardHeuristic"/>. Provided as a shortcut for standard Sudoku puzzles. /// </summary> /// <param name="puzzle">The puzzle to track.</param> public SquareTracker(Puzzle puzzle) { _puzzle = puzzle; _possibleValues = new PossibleValues(puzzle); _ruleKeeper = new StandardRuleKeeper(puzzle, _possibleValues); _heuristic = new StandardHeuristic( puzzle, _possibleValues, (IMissingRowValuesTracker)_ruleKeeper, (IMissingColumnValuesTracker)_ruleKeeper, (IMissingBoxValuesTracker)_ruleKeeper); _setCoords = new Stack <Coordinate>(puzzle.NumEmptySquares); _coordsThatUsedHeuristics = new Stack <Coordinate>(puzzle.NumEmptySquares); }
/// <summary> /// Constructs a square tracker to track the given puzzle using the given possible values, /// rule keeper, and heuristic. /// </summary> /// <param name="puzzle">The puzzle to track.</param> /// <param name="possibleValues">A possible values tracker for the given puzzle.</param> /// <param name="ruleKeeper">The rule keeper to satisfy when modifying this puzzle.</param> /// <param name="heuristic"> /// A heuristic to use to solve this puzzle efficiently. Can be set to null to skip using /// heuristics. /// <para> /// Note that only one heuristic can be provided. To use multiple heuristics, create a /// wrapper heuristic like <see cref="StandardHeuristic"/>. /// </para> /// </param> public SquareTracker( IPuzzle puzzle, PossibleValues possibleValues, ISudokuRuleKeeper ruleKeeper, ISudokuHeuristic?heuristic = null) { _puzzle = puzzle; _possibleValues = possibleValues; _ruleKeeper = ruleKeeper; _heuristic = heuristic; _setCoords = new Stack <Coordinate>(puzzle.NumEmptySquares); _coordsThatUsedHeuristics = new Stack <Coordinate>(puzzle.NumEmptySquares); }
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)]); }