From d6bcf95595ca88b0e251c1f8a37feff368bed738 Mon Sep 17 00:00:00 2001 From: NightBits Date: Wed, 19 Dec 2018 20:11:50 +0100 Subject: [PATCH] Initial commit --- Complete/App.xaml | 8 + Complete/App.xaml.cs | 13 + Complete/Libraries/Sudoku.dll | Bin 0 -> 77824 bytes Complete/Libraries/register.bat | 2 + Complete/Libraries/unregister.bat | 2 + Complete/Models/BoardModel.cs | 551 ++++++++++++++++++ Complete/Models/Constants.cs | 18 + .../Converters/BackgroundValueConverter.cs | 41 ++ .../Models/Converters/BorderValueConverter.cs | 41 ++ .../Converters/Number2BrushValueConverter.cs | 35 ++ .../Converters/OptionsValueConverter.cs | 40 ++ .../Converters/VisibilityValueConverter.cs | 41 ++ Complete/Models/IntegerPoint.cs | 40 ++ Complete/Models/LargeCell.xaml | 6 + Complete/Models/LargeCell.xaml.cs | 70 +++ Complete/Models/LittleCell.xaml | 11 + Complete/Models/LittleCell.xaml.cs | 259 ++++++++ Complete/Models/NumberBrushes.cs | 41 ++ Complete/Properties/AssemblyInfo.cs | 55 ++ Complete/Properties/Resources.Designer.cs | 63 ++ Complete/Properties/Resources.resx | 121 ++++ Complete/Properties/Settings.Designer.cs | 26 + Complete/Properties/Settings.settings | 7 + Complete/Sudoku.csproj | 238 ++++++++ Complete/Sudoku.sln | 26 + Complete/ViewModels/MainViewModel.cs | 73 +++ Complete/Views/MainWindow.xaml | 30 + Complete/Views/MainWindow.xaml.cs | 95 +++ Complete/app.config | 3 + Sudoku_-_DLL/Libraries/Sudoku.dll | Bin 0 -> 77824 bytes Sudoku_-_DLL/Libraries/SudokuDLL.dll | Bin 0 -> 26624 bytes Sudoku_-_DLL/Libraries/register.bat | 2 + Sudoku_-_DLL/Libraries/unregister.bat | 2 + Sudoku_-_DLL/Models/BoardModel.cs | 551 ++++++++++++++++++ Sudoku_-_DLL/Models/Constants.cs | 18 + .../Converters/BackgroundValueConverter.cs | 41 ++ .../Models/Converters/BorderValueConverter.cs | 41 ++ .../Converters/Number2BrushValueConverter.cs | 35 ++ .../Converters/OptionsValueConverter.cs | 40 ++ .../Converters/VisibilityValueConverter.cs | 41 ++ Sudoku_-_DLL/Models/IntegerPoint.cs | 40 ++ Sudoku_-_DLL/Models/LargeCell.xaml | 6 + Sudoku_-_DLL/Models/LargeCell.xaml.cs | 70 +++ Sudoku_-_DLL/Models/LittleCell.xaml | 11 + Sudoku_-_DLL/Models/LittleCell.xaml.cs | 259 ++++++++ Sudoku_-_DLL/Models/NumberBrushes.cs | 41 ++ Sudoku_-_DLL/Properties/AssemblyInfo.cs | 55 ++ Sudoku_-_DLL/Properties/Resources.Designer.cs | 63 ++ Sudoku_-_DLL/Properties/Resources.resx | 121 ++++ Sudoku_-_DLL/Properties/Settings.Designer.cs | 26 + Sudoku_-_DLL/Properties/Settings.settings | 7 + Sudoku_-_DLL/Sudoku.csproj | 217 +++++++ Sudoku_-_DLL/Sudoku.sln | 26 + Sudoku_-_DLL/ViewModels/MainViewModel.cs | 73 +++ Sudoku_-_View/App.xaml | 8 + Sudoku_-_View/App.xaml.cs | 13 + Sudoku_-_View/Libraries/SudokuDLL.dll | Bin 0 -> 26624 bytes Sudoku_-_View/Libraries/register.bat | 2 + Sudoku_-_View/Libraries/unregister.bat | 2 + Sudoku_-_View/Properties/AssemblyInfo.cs | 55 ++ .../Properties/Resources.Designer.cs | 63 ++ Sudoku_-_View/Properties/Resources.resx | 121 ++++ Sudoku_-_View/Properties/Settings.Designer.cs | 26 + Sudoku_-_View/Properties/Settings.settings | 7 + Sudoku_-_View/Sudoku.csproj | 202 +++++++ Sudoku_-_View/Sudoku.sln | 26 + Sudoku_-_View/Views/MainWindow.xaml | 30 + Sudoku_-_View/Views/MainWindow.xaml.cs | 95 +++ Sudoku_-_View/app.config | 3 + 69 files changed, 4395 insertions(+) create mode 100644 Complete/App.xaml create mode 100644 Complete/App.xaml.cs create mode 100644 Complete/Libraries/Sudoku.dll create mode 100644 Complete/Libraries/register.bat create mode 100644 Complete/Libraries/unregister.bat create mode 100644 Complete/Models/BoardModel.cs create mode 100644 Complete/Models/Constants.cs create mode 100644 Complete/Models/Converters/BackgroundValueConverter.cs create mode 100644 Complete/Models/Converters/BorderValueConverter.cs create mode 100644 Complete/Models/Converters/Number2BrushValueConverter.cs create mode 100644 Complete/Models/Converters/OptionsValueConverter.cs create mode 100644 Complete/Models/Converters/VisibilityValueConverter.cs create mode 100644 Complete/Models/IntegerPoint.cs create mode 100644 Complete/Models/LargeCell.xaml create mode 100644 Complete/Models/LargeCell.xaml.cs create mode 100644 Complete/Models/LittleCell.xaml create mode 100644 Complete/Models/LittleCell.xaml.cs create mode 100644 Complete/Models/NumberBrushes.cs create mode 100644 Complete/Properties/AssemblyInfo.cs create mode 100644 Complete/Properties/Resources.Designer.cs create mode 100644 Complete/Properties/Resources.resx create mode 100644 Complete/Properties/Settings.Designer.cs create mode 100644 Complete/Properties/Settings.settings create mode 100644 Complete/Sudoku.csproj create mode 100644 Complete/Sudoku.sln create mode 100644 Complete/ViewModels/MainViewModel.cs create mode 100644 Complete/Views/MainWindow.xaml create mode 100644 Complete/Views/MainWindow.xaml.cs create mode 100644 Complete/app.config create mode 100644 Sudoku_-_DLL/Libraries/Sudoku.dll create mode 100644 Sudoku_-_DLL/Libraries/SudokuDLL.dll create mode 100644 Sudoku_-_DLL/Libraries/register.bat create mode 100644 Sudoku_-_DLL/Libraries/unregister.bat create mode 100644 Sudoku_-_DLL/Models/BoardModel.cs create mode 100644 Sudoku_-_DLL/Models/Constants.cs create mode 100644 Sudoku_-_DLL/Models/Converters/BackgroundValueConverter.cs create mode 100644 Sudoku_-_DLL/Models/Converters/BorderValueConverter.cs create mode 100644 Sudoku_-_DLL/Models/Converters/Number2BrushValueConverter.cs create mode 100644 Sudoku_-_DLL/Models/Converters/OptionsValueConverter.cs create mode 100644 Sudoku_-_DLL/Models/Converters/VisibilityValueConverter.cs create mode 100644 Sudoku_-_DLL/Models/IntegerPoint.cs create mode 100644 Sudoku_-_DLL/Models/LargeCell.xaml create mode 100644 Sudoku_-_DLL/Models/LargeCell.xaml.cs create mode 100644 Sudoku_-_DLL/Models/LittleCell.xaml create mode 100644 Sudoku_-_DLL/Models/LittleCell.xaml.cs create mode 100644 Sudoku_-_DLL/Models/NumberBrushes.cs create mode 100644 Sudoku_-_DLL/Properties/AssemblyInfo.cs create mode 100644 Sudoku_-_DLL/Properties/Resources.Designer.cs create mode 100644 Sudoku_-_DLL/Properties/Resources.resx create mode 100644 Sudoku_-_DLL/Properties/Settings.Designer.cs create mode 100644 Sudoku_-_DLL/Properties/Settings.settings create mode 100644 Sudoku_-_DLL/Sudoku.csproj create mode 100644 Sudoku_-_DLL/Sudoku.sln create mode 100644 Sudoku_-_DLL/ViewModels/MainViewModel.cs create mode 100644 Sudoku_-_View/App.xaml create mode 100644 Sudoku_-_View/App.xaml.cs create mode 100644 Sudoku_-_View/Libraries/SudokuDLL.dll create mode 100644 Sudoku_-_View/Libraries/register.bat create mode 100644 Sudoku_-_View/Libraries/unregister.bat create mode 100644 Sudoku_-_View/Properties/AssemblyInfo.cs create mode 100644 Sudoku_-_View/Properties/Resources.Designer.cs create mode 100644 Sudoku_-_View/Properties/Resources.resx create mode 100644 Sudoku_-_View/Properties/Settings.Designer.cs create mode 100644 Sudoku_-_View/Properties/Settings.settings create mode 100644 Sudoku_-_View/Sudoku.csproj create mode 100644 Sudoku_-_View/Sudoku.sln create mode 100644 Sudoku_-_View/Views/MainWindow.xaml create mode 100644 Sudoku_-_View/Views/MainWindow.xaml.cs create mode 100644 Sudoku_-_View/app.config diff --git a/Complete/App.xaml b/Complete/App.xaml new file mode 100644 index 0000000..1093c01 --- /dev/null +++ b/Complete/App.xaml @@ -0,0 +1,8 @@ + + + + + diff --git a/Complete/App.xaml.cs b/Complete/App.xaml.cs new file mode 100644 index 0000000..77619ef --- /dev/null +++ b/Complete/App.xaml.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Windows; + +namespace SudokuWeek4 +{ + public partial class App : Application + { + } +} diff --git a/Complete/Libraries/Sudoku.dll b/Complete/Libraries/Sudoku.dll new file mode 100644 index 0000000000000000000000000000000000000000..925b8723035b405a055787b10e1d5e841aeb520b GIT binary patch literal 77824 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 literal 0 HcmV?d00001 diff --git a/Complete/Libraries/register.bat b/Complete/Libraries/register.bat new file mode 100644 index 0000000..f54409a --- /dev/null +++ b/Complete/Libraries/register.bat @@ -0,0 +1,2 @@ + +C:\Windows\System32\regsvr32 E:\Programmering\C#\Sudoku\Complete\Libraries\Sudoku.dll diff --git a/Complete/Libraries/unregister.bat b/Complete/Libraries/unregister.bat new file mode 100644 index 0000000..74dc2c7 --- /dev/null +++ b/Complete/Libraries/unregister.bat @@ -0,0 +1,2 @@ + +C:\Windows\System32\regsvr32 /u E:\Programmering\C#\Sudoku\Complete\Libraries\Sudoku.dll diff --git a/Complete/Models/BoardModel.cs b/Complete/Models/BoardModel.cs new file mode 100644 index 0000000..3c38b6b --- /dev/null +++ b/Complete/Models/BoardModel.cs @@ -0,0 +1,551 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using System.Windows.Controls.Primitives; + +namespace SudokuWeek4.Models +{ + public partial class BoardModel + { + // Define an array to hold the bigCells + private LargeCell[,] bigCells; + + // Define an array to hold the smallCells + private LittleCell[,] smallCells; + + // Define the current X position + private int currentX = 0; + + // Define the current Y position + private int currentY = 0; + + // This property will get or set the cheatmode + public static Boolean CheatMode { get; set; } + + // Define the gameFieldSize + public static int GameFieldSize; + + // Define the gameFieldCount + public static int GameFieldCount; + + // Define the GameField + private UniformGrid _gameField = new UniformGrid(); + + // Define the sodukuGame (if the DLL is enabled) + private Sudoku.IGame _sudokuGame; + + // Create a dictionary that holds the cheatDicisions + private readonly Dictionary _cheatDictionary = new Dictionary(); + + // Define if the sudokuDLL is used + private Boolean _sudokuDLL = true; + + // Define a gameFinished boolean + private Boolean _gameFinished = false; + + private int _inputCount; + + public BoardModel() + { + // Just keep smiling ^_^ + } + + // This property will get the gameField + public UniformGrid GameField + { + get { return _gameField; } + } + + // This method will set the cheatmode + public void Cheat(Boolean cheatMode = false) + { + CheatMode = cheatMode; + RefreshAllCells(); + } + + // Refresh all the cells on the gameField + public void RefreshAllCells() + { + for (int x = 0; x < GameFieldSize; x++) + { + for (int y = 0; y < GameFieldSize; y++) + { + smallCells[x, y].Refresh(); + } + } + } + + public void Reset(int gameFieldSize = 3) + { + // Clear the gameField + GameField.Children.Clear(); + + // Reset the inputCount + _inputCount = 0; + + // Reset the game Finished Boolean + _gameFinished = false; + + // Set the boardCount + GameFieldCount = gameFieldSize; + + // Set the boardSize + GameFieldSize = GameFieldCount * GameFieldCount; + + // Create all the gameField columns (depending on GameFieldSize) + GameField.Columns = GameField.Rows = GameFieldCount; + + // Create all the big cells (2D array of gamefield size) + bigCells = new LargeCell[GameFieldCount, GameFieldCount]; + + // Create the gameField + for (int i = 0; i < GameFieldSize; i++) + { + // Create a new border + Border border = new Border(); + + // Set the border thickness + border.BorderThickness = new Thickness(1); + + // Set the borderBrush color + border.BorderBrush = Brushes.Blue; + + // Add the border to the gameField + GameField.Children.Add(border); + + // Create a bigCell + LargeCell bigCell = new LargeCell(); + + // Add the bigCell as a child to the created border + border.Child = bigCell; + + // Set the bigcells relative to the gameField size + bigCells[i % GameFieldCount, i / GameFieldCount] = bigCell; + } + + // Load all the small cells + LoadAllSmallCells(); + + // Clear all the filled in values + _cheatDictionary.Clear(); + } + + // Load all the smallCells + private void LoadAllSmallCells() + { + // Check if the selected gameMode is for 3 x 3 (if not we need to disable the sudoku DLL) + if (GameFieldCount != 3) + { + _sudokuDLL = false; + MessageBox.Show("This gamemode cannot be played with the sudoku DLL. SudokuDLL unloaded"); + } + // If the sudoDLL is used we need to create a game + if (SudokuDLL) + { + try + { + _sudokuGame = new Sudoku.Game(); + _sudokuGame.create(); + Console.WriteLine("Sudoku DLL loaded successfully"); + } + catch (Exception ex) + { + Console.WriteLine("Error while loading sudoku DLL: \n\n" + ex.Message + "\n\n"); + SudokuDLL = false; + } + } + + // Create the new smallCells + smallCells = new LittleCell[GameFieldSize, GameFieldSize]; + + // Reset the current X and Y position (Selected cell) + currentX = 0; + currentY = 0; + + for (int x = 0; x < GameFieldSize; x++) + { + for (int y = 0; y < GameFieldSize; y++) + { + smallCells[x, y] = bigCells[x / GameFieldCount, y / GameFieldCount][x % GameFieldCount, y % GameFieldCount]; + smallCells[x, y].X = x; + smallCells[x, y].Y = y; + } + } + + // If the sudoku DLL is loaded we need to fill in the gameField + if (SudokuDLL) + { + FillSudokuFields(); + } + + + /* // Check array contents + Console.WriteLine("Soduku DLL contents: \n\n -------------------------------\n\n"); + for (int x = 1; x <= GameFieldSize; x++) + { + for (int y = 1; y <= GameFieldSize; y++) + { + int sudokuValue; + _sudokuGame.get(x, y, out sudokuValue); + Console.Write(sudokuValue); + if (sudokuValue == -1) + { + Console.WriteLine(); + } + } + } */ + + + smallCells[0, 0].Selected = true; + } + + // This method will fill in all the sudokuFields + private void FillSudokuFields() + { + for (int x = 0; x < GameFieldSize; x++) + { + for (int y = 0; y < GameFieldSize; y++) + { + try + { + int sudokuValue; + _sudokuGame.get(x + 1, y + 1, out sudokuValue); + + // Check if the sudoku value is not an empty (0) value + if (sudokuValue > 0) + { + // Set the specified value + SetNumber(x, y, sudokuValue, false, true); + _cheatDictionary[new IntegerPoint(x, y)] = sudokuValue; + } + } + catch (Exception ex) + { + Console.WriteLine("Error while generating the sudoku field when using the Sudoku DLL: \n\n" + ex.Message + "\n\n"); + break; + } + } + } + } + + // This method will solve the sudoku puzzle (partially) + public void solvePuzzle(int cellsOver = 0) + { + for (int i = _inputCount; i < smallCells.Length - cellsOver; i++) + { + ShowHint(); + System.Console.WriteLine(i); + } + } + + // This method will get the current clicked cell + public void MouseClicked(object sender, MouseEventArgs click) + { + /* if (sender != null) + { + UniformGrid _grid = sender as UniformGrid; + int _row = (int)_grid.GetValue(Grid.RowProperty); + int _column = (int)_grid.GetValue(Grid.ColumnProperty); + MessageBox.Show(string.Format("Grid clicked at column {0}, row {1}", _column, _row)); + } */ + } + + // This method will check what to do if a key is pressed + public void KeyPressed(KeyEventArgs e) + { + // Check if the keys left, right, up or down are pressed + if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down) + { + // Disable the current selected cell + smallCells[currentX, currentY].Selected = false; + + // Check which key is pressed and do the appropriate action + switch (e.Key) + { + case Key.Left: + currentX = (currentX + GameFieldSize - 1) % GameFieldSize; + break; + case Key.Right: + currentX = (currentX + 1) % GameFieldSize; + break; + case Key.Up: + currentY = (currentY + GameFieldSize - 1) % GameFieldSize; + break; + case Key.Down: + currentY = (currentY + 1) % GameFieldSize; + break; + } + + // Set the current (new) cell to be selected + smallCells[currentX, currentY].Selected = true; + } + + // Check if the numberkeys where pressed + if ((e.Key >= Key.D1 && e.Key <= Key.D9) || (e.Key >= Key.NumPad1 && e.Key <= Key.NumPad9)) + { + int number = 0; + if (e.Key >= Key.D1 && e.Key <= Key.D9) + { + number = e.Key - Key.D0; + } + else + { + number = e.Key - Key.NumPad0; + } + + IntegerPoint cellPoint = new IntegerPoint(currentX, currentY); + + // Check if the cheatmode contains the key to be pressed + if (_cheatDictionary.ContainsKey(cellPoint)) + { + // Remove the userinput at the specified location + _cheatDictionary.Remove(cellPoint); + } + + // Check if the cheatMode does not contains the pressed numberKey and if the current has a candidate that can be selected + if (!_cheatDictionary.ContainsKey(cellPoint) && smallCells[currentX, currentY].CanSet(number)) + { + if (SetNumber(currentX, currentY, number)) + { + _cheatDictionary[cellPoint] = number; + } + } + } + + if (e.Key == Key.Delete && !smallCells[currentX, currentY].ReadOnly) + { + // Add the option at the specified column + foreach (IntegerPoint cellPoint in GetPointsInColumn(currentX)) + { + smallCells[cellPoint.X, cellPoint.Y].AddOption(smallCells[currentX, currentY].Determined); + } + + // Add the option at the specified row + foreach (IntegerPoint cellPoint in GetPointsInRow(currentY)) + { + smallCells[cellPoint.X, cellPoint.Y].AddOption(smallCells[currentX, currentY].Determined); + } + + // Add the option at the specified BigCell + foreach (IntegerPoint cellPoint in GetPointsInParentBigCell(currentX, currentY)) + { + smallCells[cellPoint.X, cellPoint.Y].AddOption(smallCells[currentX, currentY].Determined); + } + + smallCells[currentX, currentY].RemoveNumber(smallCells[currentX, currentY].Determined); + } + } + + // Set the specified number + private Boolean SetNumber(int x, int y, int number, Boolean hint = false, Boolean readOnly = false) + { + if (!_gameFinished) + { + if (number < 1 || number > GameFieldSize || smallCells[x, y].ReadOnly) + { + Console.WriteLine("Cannot set the value: The value is less or greater than the GameField size. (Or the cell is readOnly)\nActual Value: " + number + "\n"); + return false; + } + + // Remove the option at the specified column + foreach (IntegerPoint cellPoint in GetPointsInColumn(x)) + { + smallCells[cellPoint.X, cellPoint.Y].RemoveOption(number); + } + + // Remove the option at the specified row + foreach (IntegerPoint cellPoint in GetPointsInRow(y)) + { + smallCells[cellPoint.X, cellPoint.Y].RemoveOption(number); + } + + // Remove the option at the specified BigCell + foreach (IntegerPoint cellPoint in GetPointsInParentBigCell(x, y)) + { + smallCells[cellPoint.X, cellPoint.Y].RemoveOption(number); + } + + // Set the userInput on the specified cell + smallCells[x, y].MakeDecision(number, hint, readOnly); + + _inputCount++; + + if (_sudokuDLL) + { + int canAdapt; + _sudokuGame.set(x + 1, y + 1, number, out canAdapt); + } + + if (CheatMode) + { + // Check which numbers are still posible to set + FindCheatNumbers(GetPointsInColumn(x)); + FindCheatNumbers(GetPointsInRow(y)); + FindCheatNumbers(GetPointsInParentBigCell(x, y)); + } + + // Check if we got a winner + if (_inputCount == smallCells.Length) + { + if (CheckWinner()) + { + _gameFinished = true; + MessageBox.Show("Game finished!"); + return false; + } + } + return true; + } + return false; + } + + // Show a hint + public void ShowHint() + { + if (_sudokuDLL) + { + int hintPossible, value, x, y; + _sudokuGame.hint(out hintPossible, out x, out y, out value); + + if (hintPossible == 1) + { + // Todo: We need to decrease the inputCount if the hint overrides a value that was already set + SetNumber(--x, --y , value, true); + } + } + } + + // Save the game + public void Save() + { + if (_sudokuDLL) + { + int write; + _sudokuGame.write(out write); + + if (write == 1) + { + MessageBox.Show("File has been saved succesfully"); + RefreshAllCells(); + } + } + } + + // Load the game + public void Load() + { + if (_sudokuDLL) + { + int read; + _sudokuGame.read(out read); + + if (read == 1) + { + MessageBox.Show("File has been loaded succesfully"); + RefreshAllCells(); + } + } + } + + public Boolean CheckWinner() + { + int endGame; + _sudokuGame.isValid(out endGame); + return endGame == 1; + } + + // Find the numbers that can be set (Cheat mode) + private void FindCheatNumbers(List optionPoints) + { + try + { + Dictionary dictionaryCount = new Dictionary(); + for (int i = 1; i <= GameFieldSize; i++) + { + dictionaryCount[i] = 0; + } + + foreach (IntegerPoint optionPoint in optionPoints) + { + foreach (int option in smallCells[optionPoint.X, optionPoint.Y].Options) + { + dictionaryCount[option]++; + } + } + + foreach (int cell in (from keys in dictionaryCount.Keys where dictionaryCount[keys] == 1 select keys).ToArray()) + { + foreach (IntegerPoint cellPoint in optionPoints) + { + if (smallCells[cellPoint.X, cellPoint.Y].CanSet(cell)) + smallCells[cellPoint.X, cellPoint.Y].SetPossible(cell); + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + + // Get the current points that where set in the bigCell + private static List GetPointsInParentBigCell(int x, int y) + { + int x0 = x - x % GameFieldCount; + int y0 = y - y % GameFieldCount; + + List cellPoints = new List(); + for (int i = 0; i < GameFieldSize; i++) + { + cellPoints.Add(new IntegerPoint(x0 + i % GameFieldCount, y0 + i / GameFieldCount)); + } + return cellPoints; + } + + // Get the current points that where set in the current row + private static List GetPointsInRow(int y) + { + List cellPoints = new List(); + for (int i = 0; i < GameFieldSize; i++) + { + cellPoints.Add(new IntegerPoint(i, y)); + } + return cellPoints; + } + + // Create a property to check if the sudokuDLL is used + public Boolean SudokuDLL + { + get { return _sudokuDLL; } + set + { + _sudokuDLL = value; + Reset(GameFieldCount); + } + } + + + // Get the current points that where set in the current column + private static List GetPointsInColumn(int x) + { + List cellPoints = new List(); + for (int i = 0; i < GameFieldSize; i++) + { + cellPoints.Add(new IntegerPoint(x, i)); + } + return cellPoints; + } + } +} \ No newline at end of file diff --git a/Complete/Models/Constants.cs b/Complete/Models/Constants.cs new file mode 100644 index 0000000..f6172ee --- /dev/null +++ b/Complete/Models/Constants.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; + +namespace SudokuWeek4.Models +{ + public static class Constants + { + public static Color DefaultSmallCellFontColor = Colors.Green; + public static Color DefaultSmallCellReadOnlyFontColor = Colors.Red; + public static Color DefaultSmallCellHintFontColor = Colors.Orange; + + public static Color CheatActivedFontColor = Colors.Blue; + + } +} diff --git a/Complete/Models/Converters/BackgroundValueConverter.cs b/Complete/Models/Converters/BackgroundValueConverter.cs new file mode 100644 index 0000000..c00bd47 --- /dev/null +++ b/Complete/Models/Converters/BackgroundValueConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class BackgroundValueConverter : IValueConverter + { + private static readonly BackgroundValueConverter _instance = new BackgroundValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Boolean && targetType == typeof(Brush)) + { + Boolean color = (Boolean)value; + if (color) + return Brushes.Red; + else + return Brushes.Transparent; + } + + // The type is not a brush + return null; + } + + // Create a property to get the instance of the BackgroundValue + public static BackgroundValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Complete/Models/Converters/BorderValueConverter.cs b/Complete/Models/Converters/BorderValueConverter.cs new file mode 100644 index 0000000..b03a8e4 --- /dev/null +++ b/Complete/Models/Converters/BorderValueConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class BorderValueConverter : IValueConverter + { + private static readonly BorderValueConverter _instance = new BorderValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Boolean && targetType == typeof(Brush)) + { + Boolean color = (Boolean)value; + if (color) + return Brushes.Orange; + else + return Brushes.Transparent; + } + + // The type is not a brush + return null; + } + + // Create a property to get the instance of the BorderValue + public static BorderValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Complete/Models/Converters/Number2BrushValueConverter.cs b/Complete/Models/Converters/Number2BrushValueConverter.cs new file mode 100644 index 0000000..6b99cba --- /dev/null +++ b/Complete/Models/Converters/Number2BrushValueConverter.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class Number2BrushValueConverter : IValueConverter + { + private static readonly Number2BrushValueConverter _instance = new Number2BrushValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is int) || targetType != typeof(Brush)) + throw new InvalidCastException(); + + int number = (int)value; + return NumberBrushes.GetBrush(number, (Color)parameter); + } + + // Create a property to get the instance of the Number2BrushValue + public static Number2BrushValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Complete/Models/Converters/OptionsValueConverter.cs b/Complete/Models/Converters/OptionsValueConverter.cs new file mode 100644 index 0000000..cfcc3df --- /dev/null +++ b/Complete/Models/Converters/OptionsValueConverter.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class OptionsValueConverter : IValueConverter + { + private static readonly OptionsValueConverter _instance = new OptionsValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is HashSet) || targetType != typeof(Brush) || !(parameter is int)) + throw new InvalidCastException(); + + HashSet set = (HashSet)value; + int number = (int)parameter; + + if (set.Contains(number) && BoardModel.CheatMode) + return NumberBrushes.GetBrush(number, Constants.CheatActivedFontColor); + else + return Brushes.Transparent; + } + + // Create a property to get the instance of the OptionsValue + public static OptionsValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Complete/Models/Converters/VisibilityValueConverter.cs b/Complete/Models/Converters/VisibilityValueConverter.cs new file mode 100644 index 0000000..ba9d832 --- /dev/null +++ b/Complete/Models/Converters/VisibilityValueConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows; + +namespace SudokuWeek4.Models.Converters +{ + internal class VisibilityValueConverter : IValueConverter + { + private static readonly VisibilityValueConverter _instance = new VisibilityValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is bool) || targetType != typeof(Visibility)) + throw new InvalidCastException(); + + bool visible = (bool)value; + if (parameter != null) + visible =! visible; + + if (visible) + return Visibility.Visible; + else + return Visibility.Hidden; + } + + // Create a property to get the instance of the OptionsValue + public static VisibilityValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Complete/Models/IntegerPoint.cs b/Complete/Models/IntegerPoint.cs new file mode 100644 index 0000000..19f1086 --- /dev/null +++ b/Complete/Models/IntegerPoint.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SudokuWeek4.Models +{ + internal struct IntegerPoint + { + public int X; + public int Y; + + public IntegerPoint(int x, int y) + { + X = x; + Y = y; + } + + // Check if the given objectPoint is an IntegerPoint + public override bool Equals(object objectPoint) + { + if( objectPoint == null || objectPoint.GetType() != typeof(IntegerPoint) ) + return false; + + return Equals((IntegerPoint)objectPoint); + } + + // Check if the X and Y are equal to eachother + public bool Equals(IntegerPoint objectPoint) + { + return objectPoint.X == X && objectPoint.Y == Y; + } + + // We do not need this (just to have all the overrides) + public override int GetHashCode() + { + return 0; + } + } +} \ No newline at end of file diff --git a/Complete/Models/LargeCell.xaml b/Complete/Models/LargeCell.xaml new file mode 100644 index 0000000..170c11e --- /dev/null +++ b/Complete/Models/LargeCell.xaml @@ -0,0 +1,6 @@ + + + diff --git a/Complete/Models/LargeCell.xaml.cs b/Complete/Models/LargeCell.xaml.cs new file mode 100644 index 0000000..7948e3a --- /dev/null +++ b/Complete/Models/LargeCell.xaml.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using SudokuWeek4.Models; + +namespace SudokuWeek4.Models +{ + public partial class LargeCell : UserControl + { + // This array will hold the smallCells + private LittleCell[,] _littleCells; + + // Create the contructor + public LargeCell() + { + try + { + InitializeComponent(); + Initialize(); + } + catch (Exception) { + System.Console.WriteLine("Cannot create the largeCell Sudoku Error."); + } + } + + // Intialize the game + private void Initialize() + { + // Clear all the contents of the bigCellGrid + bigCellGrid.Children.Clear(); + + // Set the rows and columns to the size of the gameField + bigCellGrid.Columns = bigCellGrid.Rows = BoardModel.GameFieldCount; + + // Create a new array with all the smallCells to the size of the gameField + _littleCells = new LittleCell[BoardModel.GameFieldCount, BoardModel.GameFieldCount]; + + // Create all the smallCells that will come inside the bigCells + for (int i = 0; i < BoardModel.GameFieldSize; i++) + { + Border border = new Border(); + border.BorderThickness = new Thickness (1); + border.BorderBrush = Brushes.Green; + border.Margin = new Thickness (-1, -1, 0, 0); + bigCellGrid.Children.Add (border); + + LittleCell smallCell = new LittleCell (); + border.Child = smallCell; + + _littleCells[i % BoardModel.GameFieldCount, i / BoardModel.GameFieldCount] = smallCell; + } + } + + // This property returns the specified SmallCell + public LittleCell this[int x, int y] + { + get { return _littleCells[x, y]; } + } + } +} \ No newline at end of file diff --git a/Complete/Models/LittleCell.xaml b/Complete/Models/LittleCell.xaml new file mode 100644 index 0000000..d0ec1a1 --- /dev/null +++ b/Complete/Models/LittleCell.xaml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/Complete/Models/LittleCell.xaml.cs b/Complete/Models/LittleCell.xaml.cs new file mode 100644 index 0000000..cc60486 --- /dev/null +++ b/Complete/Models/LittleCell.xaml.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Media; +using SudokuWeek4.Models.Converters; +using SudokuWeek4.Models; + +namespace SudokuWeek4.Models +{ + public partial class LittleCell : UserControl, INotifyPropertyChanged + { + // Define a hashSet of the available options + private readonly HashSet _options = new HashSet(); + + // Define a hashSet of the possible solutions + private readonly HashSet _solutions = new HashSet(); + + // Define if the cell is selected + private Boolean _selected; + + // This will hold the X and Y position of the cell + public int X, Y; + + // Set the cell to be readOnly + private Boolean _readOnly; + + // Set the cell fontColor + private Color _fontColor; + + // Create a nullable int to check if the cell is already filled-in + private int? _inputPlaced; + + // Create the OnPropertyChanged Event + public event PropertyChangedEventHandler PropertyChanged; + + private void OnPropertyChanged(string name) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(name)); + } + + // Create the constructor + public LittleCell() + { + InitializeComponent(); + + // Set the color to the default color + FontColor = Colors.Green; + + // Bind the currently selected cell + Binding bind = new Binding("Selected"); + bind.Source = this; + bind.Converter = BorderValueConverter.Instance; + smallBorder.SetBinding(Border.BorderBrushProperty, bind); + + // Bind the cell if there is a solution (possible) + bind = new Binding("Solution"); + bind.Source = this; + bind.Converter = BackgroundValueConverter.Instance; + this.SetBinding(BackgroundProperty, bind); + + // Set the columns and the rows of the Options to the size of the gameField + optionsGrid.Columns = optionsGrid.Rows = BoardModel.GameFieldCount; + for (int i = 1; i <= BoardModel.GameFieldSize; i++) + { + Grid child = new Grid(); + child.Margin = new Thickness(2); + optionsGrid.Children.Add(child); + + // Bind the available options to the cells (Cheat Mode) + bind = new Binding("Options"); + bind.Source = this; + bind.Converter = OptionsValueConverter.Instance; + bind.ConverterParameter = i; + child.SetBinding(BackgroundProperty, bind); + } + + // Bind if the grid was placed + bind = new Binding("Determined"); + bind.Source = this; + bind.ConverterParameter = Constants.DefaultSmallCellFontColor; + bind.Converter = Number2BrushValueConverter.Instance; + inputGrid.SetBinding(BackgroundProperty, bind); + + // Bind if the inputGrid needs to be visible + bind = new Binding("IsDetermined"); + bind.Source = this; + bind.Converter = VisibilityValueConverter.Instance; + inputGrid.SetBinding(VisibilityProperty, bind); + + // Bind if the optionsGrid is determined + bind = new Binding("IsDetermined"); + bind.Source = this; + bind.Converter = VisibilityValueConverter.Instance; + bind.ConverterParameter = 0; + optionsGrid.SetBinding(VisibilityProperty, bind); + + Clear(); + } + + // This property will change the FontColor + public Color FontColor + { + get { return _fontColor; } + set { _fontColor = value; } + } + + // This function will clear the cell + public void Clear() + { + // Clear all the available options + _options.Clear(); + + // Add all the available options to the optionsGrid + for (int i = 1; i <= BoardModel.GameFieldSize; i++) + _options.Add(i); + + _inputPlaced = null; + _solutions.Clear(); + Refresh(); + } + + // Refresh all the bindings + public void Refresh() + { + OnPropertyChanged(null); + } + + // Create a property to get available Options (CheatMode) + public HashSet Options + { + get { return _options; } + } + + // Check if the cell can be set with a number + public Boolean CanSet(int number) + { + if (BoardModel.CheatMode) + return _options.Contains(number); + else + return true; + } + + // Remove the number from the specified cell + public void RemoveNumber(int number) + { + _inputPlaced = null; + Refresh(); + } + + // Add the option from the specified cell + public void AddOption(int number) + { + _options.Add(number); + Refresh(); + } + + // Remove the option from the specified cell + public void RemoveOption(int number) + { + _options.Remove(number); + Refresh(); + } + + // Create a property to check if the cell has a number + public bool IsDetermined + { + get { return _inputPlaced.HasValue; } + } + + // Create a property to get the current cellNumber + public int Determined + { + get { return _inputPlaced.GetValueOrDefault(); } + } + + // This method will make a decision on a specified cell + public void MakeDecision(int number, Boolean hint = false, Boolean readOnly = false) + { + if (!_readOnly) + { + _inputPlaced = number; + _readOnly = readOnly; + + if (readOnly || hint) + { + if (readOnly) + { + // Set the color of the font to the readOnly Font + FontColor = Constants.DefaultSmallCellReadOnlyFontColor; + } + else if (hint) + { + // Set the color of the font to the hint Font + FontColor = Constants.DefaultSmallCellHintFontColor; + } + + // Rebind the cell (with the new color) + Binding bind = new Binding("Determined"); + bind.Source = this; + bind.Converter = Number2BrushValueConverter.Instance; + bind.ConverterParameter = FontColor; + inputGrid.SetBinding(BackgroundProperty, bind); + } + Refresh(); + } + } + + // Create a property to check if the cell is readOnly + public Boolean ReadOnly + { + get { return _readOnly; } + } + + // Create a property to check if there is a solution + public Boolean Solution + { + get + { + if (!BoardModel.CheatMode) + return false; + + if (_inputPlaced.HasValue) + return false; + + if (_solutions.Count > 1) + return true; + + return _options.Count == 0; + } + } + + // Set the specified cell to a possible solution + public void SetPossible(int cell) + { + _solutions.Add(cell); + Refresh(); + } + + // Create a property to check which cell is selected + public Boolean Selected + { + get { return _selected; } + set + { + if (value != _selected) + { + _selected = value; + OnPropertyChanged("Selected"); + } + } + } + } +} \ No newline at end of file diff --git a/Complete/Models/NumberBrushes.cs b/Complete/Models/NumberBrushes.cs new file mode 100644 index 0000000..14b02a5 --- /dev/null +++ b/Complete/Models/NumberBrushes.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows; +using System.Windows.Media; +using SudokuWeek4.Models; + +namespace SudokuWeek4 +{ + internal static class NumberBrushes + { + // Create a dictionary for the cached brushes (per cell) + private static readonly Dictionary cachedBrushes = new Dictionary(); + + public static DrawingBrush GetBrush(int number, Color colorBrush) + { + // Check if the index is out of bounds + if (number < 0 || number > BoardModel.GameFieldSize) + throw new IndexOutOfRangeException(); + + // Get the cached brush (if exists) + string key = number + colorBrush.ToString(); + DrawingBrush brush; + + if (cachedBrushes.TryGetValue(key, out brush)) + return brush; + + // Create a new brush (not in cache) + FormattedText formtxt = new FormattedText(number.ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Times New Roman"), 100, Brushes.Black); + Geometry textGeometry = formtxt.BuildGeometry(new Point(0, 0)); + brush = new DrawingBrush(new GeometryDrawing(new SolidColorBrush(colorBrush), null, textGeometry)); + brush.Stretch = Stretch.Uniform; + + cachedBrushes[key] = brush; + return brush; + } + } +} \ No newline at end of file diff --git a/Complete/Properties/AssemblyInfo.cs b/Complete/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..aca0baf --- /dev/null +++ b/Complete/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle( "Sudoku" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany("SuperSmash")] +[assembly: AssemblyProduct( "Sudoku" )] +[assembly: AssemblyCopyright("Copyright © SuperSmash 2012")] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible( false )] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/Complete/Properties/Resources.Designer.cs b/Complete/Properties/Resources.Designer.cs new file mode 100644 index 0000000..d56fec4 --- /dev/null +++ b/Complete/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.544 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SudokuWeek4.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SudokuWeek4.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Complete/Properties/Resources.resx b/Complete/Properties/Resources.resx new file mode 100644 index 0000000..04e2214 --- /dev/null +++ b/Complete/Properties/Resources.resx @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + \ No newline at end of file diff --git a/Complete/Properties/Settings.Designer.cs b/Complete/Properties/Settings.Designer.cs new file mode 100644 index 0000000..9ff9493 --- /dev/null +++ b/Complete/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.544 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SudokuWeek4.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Complete/Properties/Settings.settings b/Complete/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/Complete/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Complete/Sudoku.csproj b/Complete/Sudoku.csproj new file mode 100644 index 0000000..d5d79b6 --- /dev/null +++ b/Complete/Sudoku.csproj @@ -0,0 +1,238 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC} + WinExe + Properties + SudokuWeek4 + Sudoku + v4.0 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + bin\Debug\Sudoku.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + bin\Release\Sudoku.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + + + + + + 3.5 + + + + + 3.5 + + + 3.5 + + + + + 3.0 + + + 3.0 + + + 3.0 + + + 3.0 + + + + + MSBuild:Compile + Designer + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + + + + MainWindow.xaml + Code + + + + + LargeCell.xaml + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + LittleCell.xaml + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + {FC98639C-8987-42D6-B20C-8BE179AB7C55} + 1 + 0 + 0 + tlbimp + False + True + + + + + \ No newline at end of file diff --git a/Complete/Sudoku.sln b/Complete/Sudoku.sln new file mode 100644 index 0000000..be91157 --- /dev/null +++ b/Complete/Sudoku.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sudoku", "Sudoku.csproj", "{C835CFCA-0A38-40C5-BEA8-3822441B27EC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|x86.ActiveCfg = Debug|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|x86.Build.0 = Debug|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|Any CPU.Build.0 = Release|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|x86.ActiveCfg = Release|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Complete/ViewModels/MainViewModel.cs b/Complete/ViewModels/MainViewModel.cs new file mode 100644 index 0000000..c2c2205 --- /dev/null +++ b/Complete/ViewModels/MainViewModel.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using SudokuWeek4.Models; + +namespace SudokuWeek4.ViewModels +{ + public class MainViewModel + { + private BoardModel _board; + private UniformGrid _gameField; + + public MainViewModel(UniformGrid gameField) + { + _board = new BoardModel(); + _gameField = gameField; + _gameField.Children.Add(GameField()); + } + + public void Reset(int boardSize) + { + _board.Reset(boardSize); + } + + public void Cheat(Boolean cheatMode) + { + _board.Cheat(cheatMode); + } + + public void ShowHint() + { + _board.ShowHint(); + } + + public void Save() + { + _board.Save(); + } + + public void Load() + { + _board.Load(); + } + + public UniformGrid GameField() + { + return _board.GameField; + } + + public void EnableDLL(Boolean state) + { + _board.SudokuDLL = state; + } + + public void SolvePuzzle(int cellsOver = 0) + { + _board.solvePuzzle(cellsOver); + } + + public void keyPressed(KeyEventArgs key) + { + _board.KeyPressed(key); + } + + public void mouseClicked(object sender, MouseEventArgs click) + { + _board.MouseClicked(sender, click); + } + } +} diff --git a/Complete/Views/MainWindow.xaml b/Complete/Views/MainWindow.xaml new file mode 100644 index 0000000..be575ab --- /dev/null +++ b/Complete/Views/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Complete/Views/MainWindow.xaml.cs b/Complete/Views/MainWindow.xaml.cs new file mode 100644 index 0000000..183d603 --- /dev/null +++ b/Complete/Views/MainWindow.xaml.cs @@ -0,0 +1,95 @@ +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System; +using SudokuWeek4.ViewModels; +using System.Windows.Input; + +namespace SudokuWeek4 +{ + public partial class MainWindow : Window + { + private int _boardSize = 3; + private Boolean _cheatMode = false; + private Boolean _sudokuDLL = true; + private MainViewModel _mainViewModel; + + public MainWindow() + { + InitializeComponent(); + _mainViewModel = new MainViewModel(mainGrid); + Reset(_boardSize); + } + + // Reset the gameField + private void Reset(int boardSize) { + _mainViewModel.Reset(boardSize); + } + + // Save the game + private void MenuItem_Save(object sender, RoutedEventArgs e) + { + _mainViewModel.Save(); + } + + // Load the game + private void MenuItem_Load(object sender, RoutedEventArgs e) + { + _mainViewModel.Load(); + } + + // Reset the gameField + private void MenuItem_ResetBoard(object sender, RoutedEventArgs e) + { + Reset(int.Parse(((MenuItem)sender).Tag.ToString())); + } + + // Get a hint + private void MenuItem_Hint(object sender, RoutedEventArgs e) + { + _mainViewModel.ShowHint(); + } + + // Enable the sudoku DLL + private void MenuItem_EnableDLL(object sender, RoutedEventArgs e) + { + _mainViewModel.EnableDLL(_sudokuDLL =! _sudokuDLL); + } + + // Solve the sudoku puzzle + private void MenuItem_Solve(object sender, RoutedEventArgs e) + { + _mainViewModel.SolvePuzzle(); + } + + // Solve the sudoku puzzle partially + private void MenuItem_SolvePartially(object sender, RoutedEventArgs e) + { + _mainViewModel.SolvePuzzle(2); + } + + // Cheat + private void MenuItem_CheatMode(object sender, RoutedEventArgs e) + { + _mainViewModel.Cheat(_cheatMode =! _cheatMode); + } + + // Exit the application + private void MenuItem_Quit(object sender, RoutedEventArgs e) + { + Application.Current.Shutdown(1); + } + + // This method will check what to do if a key is pressed + private void mainGrid_PreviewKeyDown(object sender, KeyEventArgs key) + { + _mainViewModel.keyPressed(key); + } + + private void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs click) + { + _mainViewModel.mouseClicked(sender, click); + } + } +} \ No newline at end of file diff --git a/Complete/app.config b/Complete/app.config new file mode 100644 index 0000000..e365603 --- /dev/null +++ b/Complete/app.config @@ -0,0 +1,3 @@ + + + diff --git a/Sudoku_-_DLL/Libraries/Sudoku.dll b/Sudoku_-_DLL/Libraries/Sudoku.dll new file mode 100644 index 0000000000000000000000000000000000000000..925b8723035b405a055787b10e1d5e841aeb520b GIT binary patch literal 77824 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 literal 0 HcmV?d00001 diff --git a/Sudoku_-_DLL/Libraries/SudokuDLL.dll b/Sudoku_-_DLL/Libraries/SudokuDLL.dll new file mode 100644 index 0000000000000000000000000000000000000000..24bafe57bce8a635b30ae50d3358d82390049e6a GIT binary patch literal 26624 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 _cheatDictionary = new Dictionary(); + + // Define if the sudokuDLL is used + private Boolean _sudokuDLL = true; + + // Define a gameFinished boolean + private Boolean _gameFinished = false; + + private int _inputCount; + + public BoardModel() + { + // Just keep smiling ^_^ + } + + // This property will get the gameField + public UniformGrid GameField + { + get { return _gameField; } + } + + // This method will set the cheatmode + public void Cheat(Boolean cheatMode = false) + { + CheatMode = cheatMode; + RefreshAllCells(); + } + + // Refresh all the cells on the gameField + public void RefreshAllCells() + { + for (int x = 0; x < GameFieldSize; x++) + { + for (int y = 0; y < GameFieldSize; y++) + { + smallCells[x, y].Refresh(); + } + } + } + + public void Reset(int gameFieldSize = 3) + { + // Clear the gameField + GameField.Children.Clear(); + + // Reset the inputCount + _inputCount = 0; + + // Reset the game Finished Boolean + _gameFinished = false; + + // Set the boardCount + GameFieldCount = gameFieldSize; + + // Set the boardSize + GameFieldSize = GameFieldCount * GameFieldCount; + + // Create all the gameField columns (depending on GameFieldSize) + GameField.Columns = GameField.Rows = GameFieldCount; + + // Create all the big cells (2D array of gamefield size) + bigCells = new LargeCell[GameFieldCount, GameFieldCount]; + + // Create the gameField + for (int i = 0; i < GameFieldSize; i++) + { + // Create a new border + Border border = new Border(); + + // Set the border thickness + border.BorderThickness = new Thickness(1); + + // Set the borderBrush color + border.BorderBrush = Brushes.Blue; + + // Add the border to the gameField + GameField.Children.Add(border); + + // Create a bigCell + LargeCell bigCell = new LargeCell(); + + // Add the bigCell as a child to the created border + border.Child = bigCell; + + // Set the bigcells relative to the gameField size + bigCells[i % GameFieldCount, i / GameFieldCount] = bigCell; + } + + // Load all the small cells + LoadAllSmallCells(); + + // Clear all the filled in values + _cheatDictionary.Clear(); + } + + // Load all the smallCells + private void LoadAllSmallCells() + { + // Check if the selected gameMode is for 3 x 3 (if not we need to disable the sudoku DLL) + if (GameFieldCount != 3) + { + _sudokuDLL = false; + MessageBox.Show("This gamemode cannot be played with the sudoku DLL. SudokuDLL unloaded"); + } + // If the sudoDLL is used we need to create a game + if (SudokuDLL) + { + try + { + _sudokuGame = new Sudoku.Game(); + _sudokuGame.create(); + Console.WriteLine("Sudoku DLL loaded successfully"); + } + catch (Exception ex) + { + Console.WriteLine("Error while loading sudoku DLL: \n\n" + ex.Message + "\n\n"); + SudokuDLL = false; + } + } + + // Create the new smallCells + smallCells = new LittleCell[GameFieldSize, GameFieldSize]; + + // Reset the current X and Y position (Selected cell) + currentX = 0; + currentY = 0; + + for (int x = 0; x < GameFieldSize; x++) + { + for (int y = 0; y < GameFieldSize; y++) + { + smallCells[x, y] = bigCells[x / GameFieldCount, y / GameFieldCount][x % GameFieldCount, y % GameFieldCount]; + smallCells[x, y].X = x; + smallCells[x, y].Y = y; + } + } + + // If the sudoku DLL is loaded we need to fill in the gameField + if (SudokuDLL) + { + FillSudokuFields(); + } + + + /* // Check array contents + Console.WriteLine("Soduku DLL contents: \n\n -------------------------------\n\n"); + for (int x = 1; x <= GameFieldSize; x++) + { + for (int y = 1; y <= GameFieldSize; y++) + { + int sudokuValue; + _sudokuGame.get(x, y, out sudokuValue); + Console.Write(sudokuValue); + if (sudokuValue == -1) + { + Console.WriteLine(); + } + } + } */ + + + smallCells[0, 0].Selected = true; + } + + // This method will fill in all the sudokuFields + private void FillSudokuFields() + { + for (int x = 0; x < GameFieldSize; x++) + { + for (int y = 0; y < GameFieldSize; y++) + { + try + { + int sudokuValue; + _sudokuGame.get(x + 1, y + 1, out sudokuValue); + + // Check if the sudoku value is not an empty (0) value + if (sudokuValue > 0) + { + // Set the specified value + SetNumber(x, y, sudokuValue, false, true); + _cheatDictionary[new IntegerPoint(x, y)] = sudokuValue; + } + } + catch (Exception ex) + { + Console.WriteLine("Error while generating the sudoku field when using the Sudoku DLL: \n\n" + ex.Message + "\n\n"); + break; + } + } + } + } + + // This method will solve the sudoku puzzle (partially) + public void solvePuzzle(int cellsOver = 0) + { + for (int i = _inputCount; i < smallCells.Length - cellsOver; i++) + { + ShowHint(); + System.Console.WriteLine(i); + } + } + + // This method will get the current clicked cell + public void MouseClicked(object sender, MouseEventArgs click) + { + /* if (sender != null) + { + UniformGrid _grid = sender as UniformGrid; + int _row = (int)_grid.GetValue(Grid.RowProperty); + int _column = (int)_grid.GetValue(Grid.ColumnProperty); + MessageBox.Show(string.Format("Grid clicked at column {0}, row {1}", _column, _row)); + } */ + } + + // This method will check what to do if a key is pressed + public void KeyPressed(KeyEventArgs e) + { + // Check if the keys left, right, up or down are pressed + if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down) + { + // Disable the current selected cell + smallCells[currentX, currentY].Selected = false; + + // Check which key is pressed and do the appropriate action + switch (e.Key) + { + case Key.Left: + currentX = (currentX + GameFieldSize - 1) % GameFieldSize; + break; + case Key.Right: + currentX = (currentX + 1) % GameFieldSize; + break; + case Key.Up: + currentY = (currentY + GameFieldSize - 1) % GameFieldSize; + break; + case Key.Down: + currentY = (currentY + 1) % GameFieldSize; + break; + } + + // Set the current (new) cell to be selected + smallCells[currentX, currentY].Selected = true; + } + + // Check if the numberkeys where pressed + if ((e.Key >= Key.D1 && e.Key <= Key.D9) || (e.Key >= Key.NumPad1 && e.Key <= Key.NumPad9)) + { + int number = 0; + if (e.Key >= Key.D1 && e.Key <= Key.D9) + { + number = e.Key - Key.D0; + } + else + { + number = e.Key - Key.NumPad0; + } + + IntegerPoint cellPoint = new IntegerPoint(currentX, currentY); + + // Check if the cheatmode contains the key to be pressed + if (_cheatDictionary.ContainsKey(cellPoint)) + { + // Remove the userinput at the specified location + _cheatDictionary.Remove(cellPoint); + } + + // Check if the cheatMode does not contains the pressed numberKey and if the current has a candidate that can be selected + if (!_cheatDictionary.ContainsKey(cellPoint) && smallCells[currentX, currentY].CanSet(number)) + { + if (SetNumber(currentX, currentY, number)) + { + _cheatDictionary[cellPoint] = number; + } + } + } + + if (e.Key == Key.Delete && !smallCells[currentX, currentY].ReadOnly) + { + // Add the option at the specified column + foreach (IntegerPoint cellPoint in GetPointsInColumn(currentX)) + { + smallCells[cellPoint.X, cellPoint.Y].AddOption(smallCells[currentX, currentY].Determined); + } + + // Add the option at the specified row + foreach (IntegerPoint cellPoint in GetPointsInRow(currentY)) + { + smallCells[cellPoint.X, cellPoint.Y].AddOption(smallCells[currentX, currentY].Determined); + } + + // Add the option at the specified BigCell + foreach (IntegerPoint cellPoint in GetPointsInParentBigCell(currentX, currentY)) + { + smallCells[cellPoint.X, cellPoint.Y].AddOption(smallCells[currentX, currentY].Determined); + } + + smallCells[currentX, currentY].RemoveNumber(smallCells[currentX, currentY].Determined); + } + } + + // Set the specified number + private Boolean SetNumber(int x, int y, int number, Boolean hint = false, Boolean readOnly = false) + { + if (!_gameFinished) + { + if (number < 1 || number > GameFieldSize || smallCells[x, y].ReadOnly) + { + Console.WriteLine("Cannot set the value: The value is less or greater than the GameField size. (Or the cell is readOnly)\nActual Value: " + number + "\n"); + return false; + } + + // Remove the option at the specified column + foreach (IntegerPoint cellPoint in GetPointsInColumn(x)) + { + smallCells[cellPoint.X, cellPoint.Y].RemoveOption(number); + } + + // Remove the option at the specified row + foreach (IntegerPoint cellPoint in GetPointsInRow(y)) + { + smallCells[cellPoint.X, cellPoint.Y].RemoveOption(number); + } + + // Remove the option at the specified BigCell + foreach (IntegerPoint cellPoint in GetPointsInParentBigCell(x, y)) + { + smallCells[cellPoint.X, cellPoint.Y].RemoveOption(number); + } + + // Set the userInput on the specified cell + smallCells[x, y].MakeDecision(number, hint, readOnly); + + _inputCount++; + + if (_sudokuDLL) + { + int canAdapt; + _sudokuGame.set(x + 1, y + 1, number, out canAdapt); + } + + if (CheatMode) + { + // Check which numbers are still posible to set + FindCheatNumbers(GetPointsInColumn(x)); + FindCheatNumbers(GetPointsInRow(y)); + FindCheatNumbers(GetPointsInParentBigCell(x, y)); + } + + // Check if we got a winner + if (_inputCount == smallCells.Length) + { + if (CheckWinner()) + { + _gameFinished = true; + MessageBox.Show("Game finished!"); + return false; + } + } + return true; + } + return false; + } + + // Show a hint + public void ShowHint() + { + if (_sudokuDLL) + { + int hintPossible, value, x, y; + _sudokuGame.hint(out hintPossible, out x, out y, out value); + + if (hintPossible == 1) + { + // Todo: We need to decrease the inputCount if the hint overrides a value that was already set + SetNumber(--x, --y , value, true); + } + } + } + + // Save the game + public void Save() + { + if (_sudokuDLL) + { + int write; + _sudokuGame.write(out write); + + if (write == 1) + { + MessageBox.Show("File has been saved succesfully"); + RefreshAllCells(); + } + } + } + + // Load the game + public void Load() + { + if (_sudokuDLL) + { + int read; + _sudokuGame.read(out read); + + if (read == 1) + { + MessageBox.Show("File has been loaded succesfully"); + RefreshAllCells(); + } + } + } + + public Boolean CheckWinner() + { + int endGame; + _sudokuGame.isValid(out endGame); + return endGame == 1; + } + + // Find the numbers that can be set (Cheat mode) + private void FindCheatNumbers(List optionPoints) + { + try + { + Dictionary dictionaryCount = new Dictionary(); + for (int i = 1; i <= GameFieldSize; i++) + { + dictionaryCount[i] = 0; + } + + foreach (IntegerPoint optionPoint in optionPoints) + { + foreach (int option in smallCells[optionPoint.X, optionPoint.Y].Options) + { + dictionaryCount[option]++; + } + } + + foreach (int cell in (from keys in dictionaryCount.Keys where dictionaryCount[keys] == 1 select keys).ToArray()) + { + foreach (IntegerPoint cellPoint in optionPoints) + { + if (smallCells[cellPoint.X, cellPoint.Y].CanSet(cell)) + smallCells[cellPoint.X, cellPoint.Y].SetPossible(cell); + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + + // Get the current points that where set in the bigCell + private static List GetPointsInParentBigCell(int x, int y) + { + int x0 = x - x % GameFieldCount; + int y0 = y - y % GameFieldCount; + + List cellPoints = new List(); + for (int i = 0; i < GameFieldSize; i++) + { + cellPoints.Add(new IntegerPoint(x0 + i % GameFieldCount, y0 + i / GameFieldCount)); + } + return cellPoints; + } + + // Get the current points that where set in the current row + private static List GetPointsInRow(int y) + { + List cellPoints = new List(); + for (int i = 0; i < GameFieldSize; i++) + { + cellPoints.Add(new IntegerPoint(i, y)); + } + return cellPoints; + } + + // Create a property to check if the sudokuDLL is used + public Boolean SudokuDLL + { + get { return _sudokuDLL; } + set + { + _sudokuDLL = value; + Reset(GameFieldCount); + } + } + + + // Get the current points that where set in the current column + private static List GetPointsInColumn(int x) + { + List cellPoints = new List(); + for (int i = 0; i < GameFieldSize; i++) + { + cellPoints.Add(new IntegerPoint(x, i)); + } + return cellPoints; + } + } +} \ No newline at end of file diff --git a/Sudoku_-_DLL/Models/Constants.cs b/Sudoku_-_DLL/Models/Constants.cs new file mode 100644 index 0000000..f6172ee --- /dev/null +++ b/Sudoku_-_DLL/Models/Constants.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Media; + +namespace SudokuWeek4.Models +{ + public static class Constants + { + public static Color DefaultSmallCellFontColor = Colors.Green; + public static Color DefaultSmallCellReadOnlyFontColor = Colors.Red; + public static Color DefaultSmallCellHintFontColor = Colors.Orange; + + public static Color CheatActivedFontColor = Colors.Blue; + + } +} diff --git a/Sudoku_-_DLL/Models/Converters/BackgroundValueConverter.cs b/Sudoku_-_DLL/Models/Converters/BackgroundValueConverter.cs new file mode 100644 index 0000000..c00bd47 --- /dev/null +++ b/Sudoku_-_DLL/Models/Converters/BackgroundValueConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class BackgroundValueConverter : IValueConverter + { + private static readonly BackgroundValueConverter _instance = new BackgroundValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Boolean && targetType == typeof(Brush)) + { + Boolean color = (Boolean)value; + if (color) + return Brushes.Red; + else + return Brushes.Transparent; + } + + // The type is not a brush + return null; + } + + // Create a property to get the instance of the BackgroundValue + public static BackgroundValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Sudoku_-_DLL/Models/Converters/BorderValueConverter.cs b/Sudoku_-_DLL/Models/Converters/BorderValueConverter.cs new file mode 100644 index 0000000..b03a8e4 --- /dev/null +++ b/Sudoku_-_DLL/Models/Converters/BorderValueConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class BorderValueConverter : IValueConverter + { + private static readonly BorderValueConverter _instance = new BorderValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Boolean && targetType == typeof(Brush)) + { + Boolean color = (Boolean)value; + if (color) + return Brushes.Orange; + else + return Brushes.Transparent; + } + + // The type is not a brush + return null; + } + + // Create a property to get the instance of the BorderValue + public static BorderValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Sudoku_-_DLL/Models/Converters/Number2BrushValueConverter.cs b/Sudoku_-_DLL/Models/Converters/Number2BrushValueConverter.cs new file mode 100644 index 0000000..6b99cba --- /dev/null +++ b/Sudoku_-_DLL/Models/Converters/Number2BrushValueConverter.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class Number2BrushValueConverter : IValueConverter + { + private static readonly Number2BrushValueConverter _instance = new Number2BrushValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is int) || targetType != typeof(Brush)) + throw new InvalidCastException(); + + int number = (int)value; + return NumberBrushes.GetBrush(number, (Color)parameter); + } + + // Create a property to get the instance of the Number2BrushValue + public static Number2BrushValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Sudoku_-_DLL/Models/Converters/OptionsValueConverter.cs b/Sudoku_-_DLL/Models/Converters/OptionsValueConverter.cs new file mode 100644 index 0000000..cfcc3df --- /dev/null +++ b/Sudoku_-_DLL/Models/Converters/OptionsValueConverter.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows.Media; + +namespace SudokuWeek4.Models.Converters +{ + internal class OptionsValueConverter : IValueConverter + { + private static readonly OptionsValueConverter _instance = new OptionsValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is HashSet) || targetType != typeof(Brush) || !(parameter is int)) + throw new InvalidCastException(); + + HashSet set = (HashSet)value; + int number = (int)parameter; + + if (set.Contains(number) && BoardModel.CheatMode) + return NumberBrushes.GetBrush(number, Constants.CheatActivedFontColor); + else + return Brushes.Transparent; + } + + // Create a property to get the instance of the OptionsValue + public static OptionsValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Sudoku_-_DLL/Models/Converters/VisibilityValueConverter.cs b/Sudoku_-_DLL/Models/Converters/VisibilityValueConverter.cs new file mode 100644 index 0000000..ba9d832 --- /dev/null +++ b/Sudoku_-_DLL/Models/Converters/VisibilityValueConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Data; +using System.Globalization; +using System.Windows; + +namespace SudokuWeek4.Models.Converters +{ + internal class VisibilityValueConverter : IValueConverter + { + private static readonly VisibilityValueConverter _instance = new VisibilityValueConverter(); + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (!(value is bool) || targetType != typeof(Visibility)) + throw new InvalidCastException(); + + bool visible = (bool)value; + if (parameter != null) + visible =! visible; + + if (visible) + return Visibility.Visible; + else + return Visibility.Hidden; + } + + // Create a property to get the instance of the OptionsValue + public static VisibilityValueConverter Instance + { + get { return _instance; } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Sudoku_-_DLL/Models/IntegerPoint.cs b/Sudoku_-_DLL/Models/IntegerPoint.cs new file mode 100644 index 0000000..19f1086 --- /dev/null +++ b/Sudoku_-_DLL/Models/IntegerPoint.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SudokuWeek4.Models +{ + internal struct IntegerPoint + { + public int X; + public int Y; + + public IntegerPoint(int x, int y) + { + X = x; + Y = y; + } + + // Check if the given objectPoint is an IntegerPoint + public override bool Equals(object objectPoint) + { + if( objectPoint == null || objectPoint.GetType() != typeof(IntegerPoint) ) + return false; + + return Equals((IntegerPoint)objectPoint); + } + + // Check if the X and Y are equal to eachother + public bool Equals(IntegerPoint objectPoint) + { + return objectPoint.X == X && objectPoint.Y == Y; + } + + // We do not need this (just to have all the overrides) + public override int GetHashCode() + { + return 0; + } + } +} \ No newline at end of file diff --git a/Sudoku_-_DLL/Models/LargeCell.xaml b/Sudoku_-_DLL/Models/LargeCell.xaml new file mode 100644 index 0000000..170c11e --- /dev/null +++ b/Sudoku_-_DLL/Models/LargeCell.xaml @@ -0,0 +1,6 @@ + + + diff --git a/Sudoku_-_DLL/Models/LargeCell.xaml.cs b/Sudoku_-_DLL/Models/LargeCell.xaml.cs new file mode 100644 index 0000000..7948e3a --- /dev/null +++ b/Sudoku_-_DLL/Models/LargeCell.xaml.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using SudokuWeek4.Models; + +namespace SudokuWeek4.Models +{ + public partial class LargeCell : UserControl + { + // This array will hold the smallCells + private LittleCell[,] _littleCells; + + // Create the contructor + public LargeCell() + { + try + { + InitializeComponent(); + Initialize(); + } + catch (Exception) { + System.Console.WriteLine("Cannot create the largeCell Sudoku Error."); + } + } + + // Intialize the game + private void Initialize() + { + // Clear all the contents of the bigCellGrid + bigCellGrid.Children.Clear(); + + // Set the rows and columns to the size of the gameField + bigCellGrid.Columns = bigCellGrid.Rows = BoardModel.GameFieldCount; + + // Create a new array with all the smallCells to the size of the gameField + _littleCells = new LittleCell[BoardModel.GameFieldCount, BoardModel.GameFieldCount]; + + // Create all the smallCells that will come inside the bigCells + for (int i = 0; i < BoardModel.GameFieldSize; i++) + { + Border border = new Border(); + border.BorderThickness = new Thickness (1); + border.BorderBrush = Brushes.Green; + border.Margin = new Thickness (-1, -1, 0, 0); + bigCellGrid.Children.Add (border); + + LittleCell smallCell = new LittleCell (); + border.Child = smallCell; + + _littleCells[i % BoardModel.GameFieldCount, i / BoardModel.GameFieldCount] = smallCell; + } + } + + // This property returns the specified SmallCell + public LittleCell this[int x, int y] + { + get { return _littleCells[x, y]; } + } + } +} \ No newline at end of file diff --git a/Sudoku_-_DLL/Models/LittleCell.xaml b/Sudoku_-_DLL/Models/LittleCell.xaml new file mode 100644 index 0000000..d0ec1a1 --- /dev/null +++ b/Sudoku_-_DLL/Models/LittleCell.xaml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/Sudoku_-_DLL/Models/LittleCell.xaml.cs b/Sudoku_-_DLL/Models/LittleCell.xaml.cs new file mode 100644 index 0000000..cc60486 --- /dev/null +++ b/Sudoku_-_DLL/Models/LittleCell.xaml.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Media; +using SudokuWeek4.Models.Converters; +using SudokuWeek4.Models; + +namespace SudokuWeek4.Models +{ + public partial class LittleCell : UserControl, INotifyPropertyChanged + { + // Define a hashSet of the available options + private readonly HashSet _options = new HashSet(); + + // Define a hashSet of the possible solutions + private readonly HashSet _solutions = new HashSet(); + + // Define if the cell is selected + private Boolean _selected; + + // This will hold the X and Y position of the cell + public int X, Y; + + // Set the cell to be readOnly + private Boolean _readOnly; + + // Set the cell fontColor + private Color _fontColor; + + // Create a nullable int to check if the cell is already filled-in + private int? _inputPlaced; + + // Create the OnPropertyChanged Event + public event PropertyChangedEventHandler PropertyChanged; + + private void OnPropertyChanged(string name) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(name)); + } + + // Create the constructor + public LittleCell() + { + InitializeComponent(); + + // Set the color to the default color + FontColor = Colors.Green; + + // Bind the currently selected cell + Binding bind = new Binding("Selected"); + bind.Source = this; + bind.Converter = BorderValueConverter.Instance; + smallBorder.SetBinding(Border.BorderBrushProperty, bind); + + // Bind the cell if there is a solution (possible) + bind = new Binding("Solution"); + bind.Source = this; + bind.Converter = BackgroundValueConverter.Instance; + this.SetBinding(BackgroundProperty, bind); + + // Set the columns and the rows of the Options to the size of the gameField + optionsGrid.Columns = optionsGrid.Rows = BoardModel.GameFieldCount; + for (int i = 1; i <= BoardModel.GameFieldSize; i++) + { + Grid child = new Grid(); + child.Margin = new Thickness(2); + optionsGrid.Children.Add(child); + + // Bind the available options to the cells (Cheat Mode) + bind = new Binding("Options"); + bind.Source = this; + bind.Converter = OptionsValueConverter.Instance; + bind.ConverterParameter = i; + child.SetBinding(BackgroundProperty, bind); + } + + // Bind if the grid was placed + bind = new Binding("Determined"); + bind.Source = this; + bind.ConverterParameter = Constants.DefaultSmallCellFontColor; + bind.Converter = Number2BrushValueConverter.Instance; + inputGrid.SetBinding(BackgroundProperty, bind); + + // Bind if the inputGrid needs to be visible + bind = new Binding("IsDetermined"); + bind.Source = this; + bind.Converter = VisibilityValueConverter.Instance; + inputGrid.SetBinding(VisibilityProperty, bind); + + // Bind if the optionsGrid is determined + bind = new Binding("IsDetermined"); + bind.Source = this; + bind.Converter = VisibilityValueConverter.Instance; + bind.ConverterParameter = 0; + optionsGrid.SetBinding(VisibilityProperty, bind); + + Clear(); + } + + // This property will change the FontColor + public Color FontColor + { + get { return _fontColor; } + set { _fontColor = value; } + } + + // This function will clear the cell + public void Clear() + { + // Clear all the available options + _options.Clear(); + + // Add all the available options to the optionsGrid + for (int i = 1; i <= BoardModel.GameFieldSize; i++) + _options.Add(i); + + _inputPlaced = null; + _solutions.Clear(); + Refresh(); + } + + // Refresh all the bindings + public void Refresh() + { + OnPropertyChanged(null); + } + + // Create a property to get available Options (CheatMode) + public HashSet Options + { + get { return _options; } + } + + // Check if the cell can be set with a number + public Boolean CanSet(int number) + { + if (BoardModel.CheatMode) + return _options.Contains(number); + else + return true; + } + + // Remove the number from the specified cell + public void RemoveNumber(int number) + { + _inputPlaced = null; + Refresh(); + } + + // Add the option from the specified cell + public void AddOption(int number) + { + _options.Add(number); + Refresh(); + } + + // Remove the option from the specified cell + public void RemoveOption(int number) + { + _options.Remove(number); + Refresh(); + } + + // Create a property to check if the cell has a number + public bool IsDetermined + { + get { return _inputPlaced.HasValue; } + } + + // Create a property to get the current cellNumber + public int Determined + { + get { return _inputPlaced.GetValueOrDefault(); } + } + + // This method will make a decision on a specified cell + public void MakeDecision(int number, Boolean hint = false, Boolean readOnly = false) + { + if (!_readOnly) + { + _inputPlaced = number; + _readOnly = readOnly; + + if (readOnly || hint) + { + if (readOnly) + { + // Set the color of the font to the readOnly Font + FontColor = Constants.DefaultSmallCellReadOnlyFontColor; + } + else if (hint) + { + // Set the color of the font to the hint Font + FontColor = Constants.DefaultSmallCellHintFontColor; + } + + // Rebind the cell (with the new color) + Binding bind = new Binding("Determined"); + bind.Source = this; + bind.Converter = Number2BrushValueConverter.Instance; + bind.ConverterParameter = FontColor; + inputGrid.SetBinding(BackgroundProperty, bind); + } + Refresh(); + } + } + + // Create a property to check if the cell is readOnly + public Boolean ReadOnly + { + get { return _readOnly; } + } + + // Create a property to check if there is a solution + public Boolean Solution + { + get + { + if (!BoardModel.CheatMode) + return false; + + if (_inputPlaced.HasValue) + return false; + + if (_solutions.Count > 1) + return true; + + return _options.Count == 0; + } + } + + // Set the specified cell to a possible solution + public void SetPossible(int cell) + { + _solutions.Add(cell); + Refresh(); + } + + // Create a property to check which cell is selected + public Boolean Selected + { + get { return _selected; } + set + { + if (value != _selected) + { + _selected = value; + OnPropertyChanged("Selected"); + } + } + } + } +} \ No newline at end of file diff --git a/Sudoku_-_DLL/Models/NumberBrushes.cs b/Sudoku_-_DLL/Models/NumberBrushes.cs new file mode 100644 index 0000000..14b02a5 --- /dev/null +++ b/Sudoku_-_DLL/Models/NumberBrushes.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows; +using System.Windows.Media; +using SudokuWeek4.Models; + +namespace SudokuWeek4 +{ + internal static class NumberBrushes + { + // Create a dictionary for the cached brushes (per cell) + private static readonly Dictionary cachedBrushes = new Dictionary(); + + public static DrawingBrush GetBrush(int number, Color colorBrush) + { + // Check if the index is out of bounds + if (number < 0 || number > BoardModel.GameFieldSize) + throw new IndexOutOfRangeException(); + + // Get the cached brush (if exists) + string key = number + colorBrush.ToString(); + DrawingBrush brush; + + if (cachedBrushes.TryGetValue(key, out brush)) + return brush; + + // Create a new brush (not in cache) + FormattedText formtxt = new FormattedText(number.ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Times New Roman"), 100, Brushes.Black); + Geometry textGeometry = formtxt.BuildGeometry(new Point(0, 0)); + brush = new DrawingBrush(new GeometryDrawing(new SolidColorBrush(colorBrush), null, textGeometry)); + brush.Stretch = Stretch.Uniform; + + cachedBrushes[key] = brush; + return brush; + } + } +} \ No newline at end of file diff --git a/Sudoku_-_DLL/Properties/AssemblyInfo.cs b/Sudoku_-_DLL/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..aca0baf --- /dev/null +++ b/Sudoku_-_DLL/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle( "Sudoku" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany("SuperSmash")] +[assembly: AssemblyProduct( "Sudoku" )] +[assembly: AssemblyCopyright("Copyright © SuperSmash 2012")] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible( false )] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/Sudoku_-_DLL/Properties/Resources.Designer.cs b/Sudoku_-_DLL/Properties/Resources.Designer.cs new file mode 100644 index 0000000..d56fec4 --- /dev/null +++ b/Sudoku_-_DLL/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.544 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SudokuWeek4.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SudokuWeek4.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Sudoku_-_DLL/Properties/Resources.resx b/Sudoku_-_DLL/Properties/Resources.resx new file mode 100644 index 0000000..04e2214 --- /dev/null +++ b/Sudoku_-_DLL/Properties/Resources.resx @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + \ No newline at end of file diff --git a/Sudoku_-_DLL/Properties/Settings.Designer.cs b/Sudoku_-_DLL/Properties/Settings.Designer.cs new file mode 100644 index 0000000..9ff9493 --- /dev/null +++ b/Sudoku_-_DLL/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.544 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SudokuWeek4.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Sudoku_-_DLL/Properties/Settings.settings b/Sudoku_-_DLL/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/Sudoku_-_DLL/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Sudoku_-_DLL/Sudoku.csproj b/Sudoku_-_DLL/Sudoku.csproj new file mode 100644 index 0000000..3f06601 --- /dev/null +++ b/Sudoku_-_DLL/Sudoku.csproj @@ -0,0 +1,217 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC} + Library + Properties + SudokuWeek4 + SudokuDLL + v4.0 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + bin\Debug\Sudoku.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + bin\Release\Sudoku.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + + + + + + 3.5 + + + + + 3.5 + + + 3.5 + + + + + 3.0 + + + 3.0 + + + 3.0 + + + 3.0 + + + + + Designer + MSBuild:Compile + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + MSBuild:Compile + Designer + + + + + + + + + + + + + LargeCell.xaml + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + LittleCell.xaml + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + {FC98639C-8987-42D6-B20C-8BE179AB7C55} + 1 + 0 + 0 + tlbimp + False + True + + + + + \ No newline at end of file diff --git a/Sudoku_-_DLL/Sudoku.sln b/Sudoku_-_DLL/Sudoku.sln new file mode 100644 index 0000000..be91157 --- /dev/null +++ b/Sudoku_-_DLL/Sudoku.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sudoku", "Sudoku.csproj", "{C835CFCA-0A38-40C5-BEA8-3822441B27EC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|x86.ActiveCfg = Debug|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|x86.Build.0 = Debug|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|Any CPU.Build.0 = Release|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|x86.ActiveCfg = Release|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Sudoku_-_DLL/ViewModels/MainViewModel.cs b/Sudoku_-_DLL/ViewModels/MainViewModel.cs new file mode 100644 index 0000000..c2c2205 --- /dev/null +++ b/Sudoku_-_DLL/ViewModels/MainViewModel.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using SudokuWeek4.Models; + +namespace SudokuWeek4.ViewModels +{ + public class MainViewModel + { + private BoardModel _board; + private UniformGrid _gameField; + + public MainViewModel(UniformGrid gameField) + { + _board = new BoardModel(); + _gameField = gameField; + _gameField.Children.Add(GameField()); + } + + public void Reset(int boardSize) + { + _board.Reset(boardSize); + } + + public void Cheat(Boolean cheatMode) + { + _board.Cheat(cheatMode); + } + + public void ShowHint() + { + _board.ShowHint(); + } + + public void Save() + { + _board.Save(); + } + + public void Load() + { + _board.Load(); + } + + public UniformGrid GameField() + { + return _board.GameField; + } + + public void EnableDLL(Boolean state) + { + _board.SudokuDLL = state; + } + + public void SolvePuzzle(int cellsOver = 0) + { + _board.solvePuzzle(cellsOver); + } + + public void keyPressed(KeyEventArgs key) + { + _board.KeyPressed(key); + } + + public void mouseClicked(object sender, MouseEventArgs click) + { + _board.MouseClicked(sender, click); + } + } +} diff --git a/Sudoku_-_View/App.xaml b/Sudoku_-_View/App.xaml new file mode 100644 index 0000000..1093c01 --- /dev/null +++ b/Sudoku_-_View/App.xaml @@ -0,0 +1,8 @@ + + + + + diff --git a/Sudoku_-_View/App.xaml.cs b/Sudoku_-_View/App.xaml.cs new file mode 100644 index 0000000..77619ef --- /dev/null +++ b/Sudoku_-_View/App.xaml.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Windows; + +namespace SudokuWeek4 +{ + public partial class App : Application + { + } +} diff --git a/Sudoku_-_View/Libraries/SudokuDLL.dll b/Sudoku_-_View/Libraries/SudokuDLL.dll new file mode 100644 index 0000000000000000000000000000000000000000..24bafe57bce8a635b30ae50d3358d82390049e6a GIT binary patch literal 26624 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 in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/Sudoku_-_View/Properties/Resources.Designer.cs b/Sudoku_-_View/Properties/Resources.Designer.cs new file mode 100644 index 0000000..d56fec4 --- /dev/null +++ b/Sudoku_-_View/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.544 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SudokuWeek4.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SudokuWeek4.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Sudoku_-_View/Properties/Resources.resx b/Sudoku_-_View/Properties/Resources.resx new file mode 100644 index 0000000..04e2214 --- /dev/null +++ b/Sudoku_-_View/Properties/Resources.resx @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + \ No newline at end of file diff --git a/Sudoku_-_View/Properties/Settings.Designer.cs b/Sudoku_-_View/Properties/Settings.Designer.cs new file mode 100644 index 0000000..9ff9493 --- /dev/null +++ b/Sudoku_-_View/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.544 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SudokuWeek4.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Sudoku_-_View/Properties/Settings.settings b/Sudoku_-_View/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/Sudoku_-_View/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Sudoku_-_View/Sudoku.csproj b/Sudoku_-_View/Sudoku.csproj new file mode 100644 index 0000000..f41e44a --- /dev/null +++ b/Sudoku_-_View/Sudoku.csproj @@ -0,0 +1,202 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC} + WinExe + Properties + SudokuWeek4 + Sudoku + v4.0 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + bin\Debug\Sudoku.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + bin\Release\Sudoku.exe.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + AllRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + false + + + + + + + Libraries\SudokuDLL.dll + + + + 3.5 + + + + + 3.5 + + + 3.5 + + + + + 3.0 + + + 3.0 + + + 3.0 + + + 3.0 + + + + + MSBuild:Compile + Designer + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + MSBuild:Compile + Designer + + + App.xaml + Code + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + \ No newline at end of file diff --git a/Sudoku_-_View/Sudoku.sln b/Sudoku_-_View/Sudoku.sln new file mode 100644 index 0000000..be91157 --- /dev/null +++ b/Sudoku_-_View/Sudoku.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sudoku", "Sudoku.csproj", "{C835CFCA-0A38-40C5-BEA8-3822441B27EC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|x86.ActiveCfg = Debug|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Debug|x86.Build.0 = Debug|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|Any CPU.Build.0 = Release|Any CPU + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|x86.ActiveCfg = Release|x86 + {C835CFCA-0A38-40C5-BEA8-3822441B27EC}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Sudoku_-_View/Views/MainWindow.xaml b/Sudoku_-_View/Views/MainWindow.xaml new file mode 100644 index 0000000..be575ab --- /dev/null +++ b/Sudoku_-_View/Views/MainWindow.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Sudoku_-_View/Views/MainWindow.xaml.cs b/Sudoku_-_View/Views/MainWindow.xaml.cs new file mode 100644 index 0000000..183d603 --- /dev/null +++ b/Sudoku_-_View/Views/MainWindow.xaml.cs @@ -0,0 +1,95 @@ +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System; +using SudokuWeek4.ViewModels; +using System.Windows.Input; + +namespace SudokuWeek4 +{ + public partial class MainWindow : Window + { + private int _boardSize = 3; + private Boolean _cheatMode = false; + private Boolean _sudokuDLL = true; + private MainViewModel _mainViewModel; + + public MainWindow() + { + InitializeComponent(); + _mainViewModel = new MainViewModel(mainGrid); + Reset(_boardSize); + } + + // Reset the gameField + private void Reset(int boardSize) { + _mainViewModel.Reset(boardSize); + } + + // Save the game + private void MenuItem_Save(object sender, RoutedEventArgs e) + { + _mainViewModel.Save(); + } + + // Load the game + private void MenuItem_Load(object sender, RoutedEventArgs e) + { + _mainViewModel.Load(); + } + + // Reset the gameField + private void MenuItem_ResetBoard(object sender, RoutedEventArgs e) + { + Reset(int.Parse(((MenuItem)sender).Tag.ToString())); + } + + // Get a hint + private void MenuItem_Hint(object sender, RoutedEventArgs e) + { + _mainViewModel.ShowHint(); + } + + // Enable the sudoku DLL + private void MenuItem_EnableDLL(object sender, RoutedEventArgs e) + { + _mainViewModel.EnableDLL(_sudokuDLL =! _sudokuDLL); + } + + // Solve the sudoku puzzle + private void MenuItem_Solve(object sender, RoutedEventArgs e) + { + _mainViewModel.SolvePuzzle(); + } + + // Solve the sudoku puzzle partially + private void MenuItem_SolvePartially(object sender, RoutedEventArgs e) + { + _mainViewModel.SolvePuzzle(2); + } + + // Cheat + private void MenuItem_CheatMode(object sender, RoutedEventArgs e) + { + _mainViewModel.Cheat(_cheatMode =! _cheatMode); + } + + // Exit the application + private void MenuItem_Quit(object sender, RoutedEventArgs e) + { + Application.Current.Shutdown(1); + } + + // This method will check what to do if a key is pressed + private void mainGrid_PreviewKeyDown(object sender, KeyEventArgs key) + { + _mainViewModel.keyPressed(key); + } + + private void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs click) + { + _mainViewModel.mouseClicked(sender, click); + } + } +} \ No newline at end of file diff --git a/Sudoku_-_View/app.config b/Sudoku_-_View/app.config new file mode 100644 index 0000000..e365603 --- /dev/null +++ b/Sudoku_-_View/app.config @@ -0,0 +1,3 @@ + + +