private SquareTracker(SquareTracker <TPuzzle> other) { // Puzzle is guaranteed to be of type TPuzzle. _puzzle = (TPuzzle)other._puzzle.DeepCopy(); // Copy matrix, focusing only on 'Unknown' possible square values and (therefore) unsatisfied constraints. _matrix = other._matrix.CopyUnknowns(); _setCoords = new Stack <Coordinate>(_puzzle.NumEmptySquares); }
public SolveStats GetStatsForAllSolutions(TPuzzle puzzle) { if (!_AreValuesUnique(puzzle.AllPossibleValues)) { throw new ArgumentException( $"{nameof(puzzle.AllPossibleValues)} must all be unique. Received values: {puzzle.AllPossibleValues.ToString()}."); } var puzzleCopy = (TPuzzle)puzzle.DeepCopy(); var matrix = new ExactCoverMatrix(puzzleCopy); foreach (IConstraint?constraint in _constraints) { constraint.Constrain(puzzleCopy, matrix); } return(_TryAllSolutions(new SquareTracker <TPuzzle>(puzzleCopy, matrix))); }
public static ConstraintHeader CreateConnectedHeader( ExactCoverMatrix matrix, ReadOnlySpan <PossibleValue> possibleSquares) { var header = new ConstraintHeader(matrix); matrix.Attach(header); foreach (PossibleValue?possibleSquare in possibleSquares) { _ = Link.CreateConnectedLink(possibleSquare, header); } if (header.Count == 0) { throw new ArgumentException( $"Must provide at least one {nameof(PossibleValue)} when creating a {nameof(ConstraintHeader)}."); } return(header); }
internal ConstraintHeader CopyToMatrix(ExactCoverMatrix matrix) { Debug.Assert(FirstLink != null, $"Can't copy a header with a null {nameof(FirstLink)}."); Debug.Assert(!IsSatisfied, $"Can't copy a header that's already satisfied."); var copy = new ConstraintHeader(matrix); foreach (Link?link in GetLinks()) { Square?square = matrix.GetSquare(link.PossibleSquare.Square.Coordinate); Debug.Assert(square != null, $"Tried to copy a square link for a null square at {link.PossibleSquare.Square.Coordinate}."); PossibleValue?possibleSquare = square.GetPossibleValue(link.PossibleSquare.ValueIndex); Debug.Assert(possibleSquare != null, "Tried to link header to null possible square value."); _ = Link.CreateConnectedLink(possibleSquare, copy); } return(copy); }
public void SolveRandomly(TPuzzle puzzle) { if (!_AreValuesUnique(puzzle.AllPossibleValues)) { throw new ArgumentException( $"{nameof(puzzle.AllPossibleValues)} must all be unique. Received values: {puzzle.AllPossibleValues.ToString()}."); } var matrix = new ExactCoverMatrix(puzzle); foreach (IConstraint?constraint in _constraints) { constraint.Constrain(puzzle, matrix); } if (!_TrySolveRandomly(new Random(), new SquareTracker <TPuzzle>(puzzle, matrix))) { throw new ArgumentException($"Failed to solve the given puzzle."); } }
internal ConstraintHeader(ExactCoverMatrix matrix) { Matrix = matrix; NextHeader = PreviousHeader = this; }
internal SquareTracker(TPuzzle puzzle, ExactCoverMatrix matrix) { _puzzle = puzzle; _matrix = matrix; _setCoords = new Stack <Coordinate>(puzzle.NumEmptySquares); }