Skip to content

Commit 0964f9c

Browse files
committed
Added handling of invalid files and invalid Sudoku puzzles.
1 parent 4e441d4 commit 0964f9c

File tree

3 files changed

+67
-16
lines changed

3 files changed

+67
-16
lines changed

SimpleSudokuSolver.Tests/Strategy/BacktrackingTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,26 @@ public void BacktrackingTest1()
2727
var sudokuPuzzle = solver.Solve(sudoku);
2828
Assert.That(sudokuPuzzle.IsSolved(), Is.True);
2929
}
30+
31+
[Test]
32+
public void BacktrackingTest2()
33+
{
34+
var sudoku = new[,]
35+
{
36+
// Unsolvable, taken from: https://www.sudokudragon.com/unsolvable.htm
37+
{ 5,1,6,8,4,9,7,3,2 },
38+
{ 3,0,7,6,0,5,0,0,0 },
39+
{ 8,0,9,7,0,0,0,6,5 },
40+
{ 1,3,5,0,6,0,9,0,7 },
41+
{ 4,7,2,5,9,1,0,0,6 },
42+
{ 9,6,8,3,7,0,0,5,0 },
43+
{ 2,5,3,1,8,6,0,7,4 },
44+
{ 6,8,4,2,0,7,5,0,0 },
45+
{ 7,9,1,0,5,0,6,0,8 }
46+
};
47+
48+
var sudokuPuzzle = solver.Solve(sudoku);
49+
Assert.That(sudokuPuzzle.IsSolved(), Is.False);
50+
}
3051
}
3152
}

SimpleSudokuSolver.UI/MainWindow.xaml.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using SimpleSudokuSolver.PuzzleProviders;
44
using SimpleSudokuSolver.UI.PuzzleProviders;
55
using SimpleSudokuSolver.UI.ViewModel;
6+
using System;
67
using System.IO;
78
using System.Windows;
89

@@ -24,6 +25,7 @@ public MainWindow()
2425
viewModel.LoadGame += OnLoadGame;
2526
viewModel.SaveGame += OnSaveGame;
2627
viewModel.ExitGame += OnExitGame;
28+
viewModel.InvalidSudokuLoaded += OnInvalidSudokuLoaded;
2729

2830
DataContext = viewModel;
2931
}
@@ -35,14 +37,28 @@ private SudokuPuzzle OnLoadGame()
3537
CheckFileExists = true,
3638
Filter = DialogFilter
3739
};
38-
if(openFileDialog.ShowDialog() == true)
40+
if (openFileDialog.ShowDialog() == true)
3941
{
40-
var sudoku = new SudokuFilePuzzleProvider(openFileDialog.FileName).GetPuzzle();
41-
return new SudokuPuzzle(sudoku);
42+
try
43+
{
44+
var sudoku = new SudokuFilePuzzleProvider(openFileDialog.FileName).GetPuzzle();
45+
return new SudokuPuzzle(sudoku);
46+
}
47+
catch (Exception)
48+
{
49+
MessageBox.Show(this, $"Failed to load sudoku puzzle from file:\r\n{openFileDialog.FileName}", "Error loading Sudoku",
50+
MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.None);
51+
}
4252
}
4353
return null;
4454
}
4555

56+
private void OnInvalidSudokuLoaded()
57+
{
58+
MessageBox.Show(this, $"Loaded file does not contain a valid sudoku puzzle\r\n(it is unsolvable).", "Error loading Sudoku",
59+
MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK, MessageBoxOptions.None);
60+
}
61+
4662
private void OnSaveGame(SudokuPuzzle sudokuPuzzle)
4763
{
4864
var saveFileDialog = new SaveFileDialog

SimpleSudokuSolver.UI/ViewModel/MainViewModel.cs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ public class MainViewModel : INotifyPropertyChanged
2020
public event Func<SudokuPuzzle> LoadGame;
2121
public event Action<SudokuPuzzle> SaveGame;
2222
public event Action ExitGame;
23+
public event Action InvalidSudokuLoaded;
2324

24-
public Tuple<int,int> LastUpdatedCellIndex { get; private set; }
25+
public Tuple<int, int> LastUpdatedCellIndex { get; private set; }
2526

2627
private bool _showCandidates;
2728
public bool ShowCandidates
@@ -114,18 +115,31 @@ private void ExecuteNewGameCommand()
114115
private void ExecuteLoadGameCommand()
115116
{
116117
var loadGame = LoadGame;
117-
if (loadGame != null)
118+
if (loadGame == null)
118119
{
119-
var sudokuPuzzle = loadGame();
120-
if (sudokuPuzzle != null)
121-
{
122-
SudokuPuzzle = sudokuPuzzle;
123-
SolvedSudokuPuzzle = _solver.Solve(sudokuPuzzle.ToIntArray());
124-
LastUpdatedCellIndex = null;
125-
Message = string.Empty;
126-
UpdateStatusMessage();
127-
}
120+
return;
121+
}
122+
123+
var sudokuPuzzle = loadGame();
124+
if (sudokuPuzzle == null)
125+
{
126+
return;
127+
}
128+
129+
try
130+
{
131+
SolvedSudokuPuzzle = _solver.Solve(sudokuPuzzle.ToIntArray());
128132
}
133+
catch (Exception)
134+
{
135+
InvalidSudokuLoaded?.Invoke();
136+
return;
137+
}
138+
139+
SudokuPuzzle = sudokuPuzzle;
140+
LastUpdatedCellIndex = null;
141+
Message = string.Empty;
142+
UpdateStatusMessage();
129143
}
130144

131145
private void ExecuteSaveGameCommand()
@@ -225,11 +239,11 @@ public void UpdateStatusMessage()
225239
}
226240

227241
var sb = new StringBuilder("Values left: ");
228-
for(int i = 1; i <= SudokuPuzzle.NumberOfRowsOrColumnsInPuzzle; i++)
242+
for (int i = 1; i <= SudokuPuzzle.NumberOfRowsOrColumnsInPuzzle; i++)
229243
{
230244
var numberOfValuesLeft = SudokuPuzzle.NumberOfRowsOrColumnsInPuzzle - SudokuPuzzle.Cells.OfType<Cell>().Count(x => x.Value == i);
231245
var separator = (i == SudokuPuzzle.NumberOfRowsOrColumnsInPuzzle) ? string.Empty : ",";
232-
if(numberOfValuesLeft > 0)
246+
if (numberOfValuesLeft > 0)
233247
sb.Append($"{i} x{numberOfValuesLeft}{separator} ");
234248
}
235249

0 commit comments

Comments
 (0)