/// <summary> /// Applies this strategy to the specified puzzle. /// </summary> /// <param name="puzzle">The puzzle to which to apply this strategy.</param> public override void ApplyStrategy(Puzzle puzzle) { this.Puzzle = puzzle; while (!Puzzle.IsSolved) { for (int rowIndex = 0; rowIndex < Puzzle.Height; rowIndex++) { for (int columnIndex = 0; columnIndex < Puzzle.Width; columnIndex++) { Cell cell = Puzzle[columnIndex, rowIndex]; if (cell.IsSolved) { RemoveCandidates(columnIndex, rowIndex, cell.Value); } } } } try { this.Puzzle.Validate(); } catch (Exception e) { Puzzle.ErrorMessage = e.Message; } }
public void Solve(Puzzle puzzle) { while (!puzzle.IsSolved) { foreach (Strategy strategy in this.Strategies) strategy.ApplyStrategy(puzzle); } }
private List<char[]> GetPuzzleCellValues(Puzzle Puzzle) { List<char[]> puzzleCellValues = new List<char[]>(); string[] puzzleRows = Puzzle.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.None); foreach(string row in puzzleRows) { puzzleCellValues.Add(row.ToCharArray()); } return puzzleCellValues; }
/// <summary> /// Populates the Cells collection for the Box based on the Position supplied. /// </summary> /// <param name="Position">The position of the Box in the Puzzle (numbered left-to-right then down).</param> /// <param name="puzzle">The associated Puzzle</param> private void PopulateCells(int Position, Puzzle puzzle) { int firstColumnIndex = Position % puzzle.BoxWidth * puzzle.BoxWidth; int firstRowIndex = Position / puzzle.BoxHeight * puzzle.BoxHeight % puzzle.Height; for (int rowIndex = firstRowIndex; rowIndex < firstRowIndex + puzzle.BoxHeight; rowIndex++) { for (int columnIndex = firstColumnIndex; columnIndex < firstColumnIndex + puzzle.BoxWidth; columnIndex++) { this.Cells.Add(puzzle[columnIndex, rowIndex]); } } }
/// <summary> /// Initializes a new instance of the Sudoku.Common.Box class /// with its specified position and associated puzzle. /// </summary> /// public Box(int position, Puzzle puzzle) : base(position) { // TODO: (DONE) Identify cells PopulateCells(position, puzzle); }
/// <summary> /// Initializes a new instance of the Sudoku.Common.Column class /// with its specified position and associated puzzle. /// </summary> public Column(int position, Puzzle puzzle) : base(position) { for(int i=0;i<puzzle.Height;i++) this.Cells.Add(puzzle[this.Position, i]); }
/// <summary> /// Applies this strategy to the specified puzzle. /// </summary> /// <param name="puzzle">The puzzle to which to apply this strategy.</param> public abstract void ApplyStrategy(Puzzle puzzle);
/// <summary> /// Initializes a new instance of the Sudoku.Common.Box class /// with its specified position and associated puzzle. /// </summary> public Box(int position, Puzzle puzzle) : base(position) { // TODO: Identify cells }
private void WritePuzzle(Puzzle Puzzle, List<char[]> OriginalCellValues, List<char[]> SolvedCellValues) { Table originalPuzzleTable = new Table(); Table solvedPuzzleTable = new Table(); originalPuzzleTable.Style.Add("border-spacing", "0px"); solvedPuzzleTable.Style.Add("border-spacing", "0px"); originalPuzzleTable.Style.Add("border", "solid black 3px"); solvedPuzzleTable.Style.Add("border", "solid black 3px"); for(int rowIndex = 0; rowIndex < OriginalCellValues.Count; rowIndex++) { char[] originalValues = new char[OriginalCellValues.Count]; char[] solvedValues = new char[SolvedCellValues.Count]; originalValues = OriginalCellValues[rowIndex]; solvedValues = SolvedCellValues[rowIndex]; TableRow originalTableRow = new TableRow(); TableRow solvedTableRow = new TableRow(); for (int columnIndex = 0; columnIndex < originalValues.Length; columnIndex++) { char originalValue = originalValues[columnIndex]; char solvedValue = solvedValues[columnIndex]; TableCell originalTableCell = new TableCell(); TableCell solvedTableCell = new TableCell(); originalTableCell.Width = 21; solvedTableCell.Width = 21; originalTableCell.Style.Add("text-align", "center"); solvedTableCell.Style.Add("text-align", "center"); originalTableCell.Style.Add("border", "solid black 1px"); solvedTableCell.Style.Add("border", "solid black 1px"); originalTableCell.Style.Add("padding", "0px"); solvedTableCell.Style.Add("padding", "0px"); if ((columnIndex + 1) % (Puzzle.BoxWidth) == 0 && columnIndex < (Puzzle.Width - 1)) { originalTableCell.Style.Add("border-right", "solid black 3px"); solvedTableCell.Style.Add("border-right", "solid black 3px"); } if ((rowIndex + 1) % (Puzzle.BoxHeight) == 0 && rowIndex < (Puzzle.Height - 1)) { originalTableCell.Style.Add("border-bottom", "solid black 3px;"); solvedTableCell.Style.Add("border-bottom", "solid black 3px"); } originalTableCell.Text = originalValue.ToString() == "0" ? " " : originalValue.ToString(); solvedTableCell.Text = solvedValue.ToString(); if (solvedValue != originalValue) { solvedTableCell.ForeColor = Color.Red; } originalTableRow.Cells.Add(originalTableCell); solvedTableRow.Cells.Add(solvedTableCell); originalTableRow.BorderColor = Color.Black; solvedTableRow.BorderColor = Color.Black; originalTableRow.BorderWidth = 3; solvedTableRow.BorderWidth = 3; } originalPuzzleTable.Rows.Add(originalTableRow); solvedPuzzleTable.Rows.Add(solvedTableRow); } this.original.Controls.Add(originalPuzzleTable); this.solved.Controls.Add(solvedPuzzleTable); }
/// <summary> /// (Overridable) Accepts an unassigned Puzzle and returns it created and populated with required values. /// </summary> /// <param name="Puzzle"></param> public virtual void InitializePuzzle(out Puzzle Puzzle) { List<string> puzzleRows = GetPuzzleContent(); int[] cellValues = new int[puzzleRows[0].Length * puzzleRows.Count]; Alphabet puzzleAlphabet = new Alphabet(); ExtractMetadata(puzzleRows); // Assumption: All values in the puzzle's alphabet can be found among the pre-filled cells it contains. for (int rowIndex = 0; rowIndex < puzzleRows.Count; rowIndex++) { for (int columnIndex = 0; columnIndex < puzzleRows[rowIndex].Length; columnIndex++) { string cellValue = puzzleRows[rowIndex].Substring(columnIndex, 1); if (cellValue != _EmptyCellDesignator && !puzzleAlphabet.Contains(int.Parse(cellValue))) { puzzleAlphabet.Add(int.Parse(cellValue)); } cellValues[rowIndex * puzzleRows.Count + columnIndex] = cellValue == _EmptyCellDesignator ? _EmptyCellValue : int.Parse(cellValue); } } Puzzle = new Puzzle(puzzleRows[0].Length, puzzleRows.Count, this.BoxWidth, this.BoxHeight, puzzleAlphabet); for (int cellIndex = 0; cellIndex < Puzzle.Cells.Count; cellIndex++) { Puzzle.Cells[cellIndex].Value = cellValues[cellIndex]; if (Puzzle.Cells[cellIndex].Value != _EmptyCellValue) { Puzzle.Cells[cellIndex].SetAsSolved(); } } if (Puzzle.SolveCount == 0) { Puzzle.ErrorMessage = "Error: The puzzle has no starting values in it."; } else { Puzzle.ErrorMessage = null; } }