Sudoku/Complete/Models/LittleCell.xaml.cs

259 lines
7.9 KiB
C#

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<int> _options = new HashSet<int>();
// Define a hashSet of the possible solutions
private readonly HashSet<int> _solutions = new HashSet<int>();
// 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<int> 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");
}
}
}
}
}