

1.数独单元
- public struct SudokuCell
- {
- public SudokuCell() : this(0, 0, 0)
- {
- }
- public SudokuCell(int x, int y, int number)
- {
- X = x; Y = y; Number = number;
- }
- public int X { get; set; }
- public int Y { get; set; }
- public int Number { get; set; }
- }
2.数独创建
- public class SudokuGenerator
- {
- private const int BoardSize = 9;
- private const int EmptyCellValue = 0;
-
- private Random random;
- private readonly ChaosRandomEx chaosRandomEx;
- public SudokuGenerator()
- {
- random = new Random();
- chaosRandomEx = new ChaosRandomEx();
- }
-
- public SudokuCell[,] GenerateSudoku(DifficultyLevel difficulty)
- {
- SudokuCell[,] board = new SudokuCell[BoardSize, BoardSize];
-
- // 初始化数独网格
- for (int row = 0; row < BoardSize; row++)
- {
- for (int col = 0; col < BoardSize; col++)
- {
- board[row, col] = new SudokuCell(row, col, EmptyCellValue);
- }
- }
-
- // 填充数独网格
- FillSudoku(board);
-
- // 根据难度要求移除部分单元格的值
- RemoveCells(board, difficulty);
-
- return board;
- }
-
-
- private void FillSudoku(SudokuCell[,] board)
- {
- SolveSudoku(board);
- }
-
- private bool SolveSudoku(SudokuCell[,] board)
- {
- int row = 0;
- int col = 0;
-
- if (!FindEmptyCell(board, ref row, ref col))
- {
- // 所有单元格都已填满,数独已解决
- return true;
- }
-
- List<int> numbers = GetRandomNumberSequence();
-
- foreach (int num in numbers)
- {
- if (IsValidMove(board, row, col, num))
- {
- // 尝试填充数字
- board[row, col].Number = num;
-
- if (SolveSudoku(board))
- {
- // 递归解决剩余的单元格
- return true;
- }
-
- // 回溯到上一个单元格
- board[row, col].Number = EmptyCellValue;
- }
- }
-
- return false;
- }
-
- private bool FindEmptyCell(SudokuCell[,] board, ref int row, ref int col)
- {
- for (row = 0; row < BoardSize; row++)
- {
- for (col = 0; col < BoardSize; col++)
- {
- if (board[row, col].Number == EmptyCellValue)
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
- public bool IsValidMove(SudokuCell[,] board, int row, int col, int num)
- {
- // 检查行是否合法
- for (int i = 0; i < BoardSize; i++)
- {
- if (board[i, col].Number == num)
- {
- return false;
- }
- }
-
- // 检查列是否合法
- for (int i = 0; i < BoardSize; i++)
- {
- if (board[row, i].Number == num)
- {
- return false;
- }
- }
-
- // 检查子网格是否合法
- int subgridRow = (row / 3) * 3;
- int subgridCol = (col / 3) * 3;
-
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- if (board[subgridRow + i, subgridCol + j].Number == num)
- {
- return false;
- }
- }
- }
-
- return true;
- }
-
- private List<int> GetRandomNumberSequence()
- {
- List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
- Shuffle(numbers);
- return numbers;
- }
-
- private void Shuffle<T>(List
list ) - {
- int n = list.Count;
- while (n > 1)
- {
- n--;
- int k = random.Next(n + 1);
- T value = list[k];
- list[k] = list[n];
- list[n] = value;
- }
- }
-
- private void RemoveCells(SudokuCell[,] board, DifficultyLevel difficulty)
- {
- int cellsToRemove = GetCellsToRemoveCount(difficulty);
-
- for (int i = 0; i < cellsToRemove; i++)
- {
- int row = random.Next(BoardSize);
- int col = random.Next(BoardSize);
-
- if (board[row, col].Number != EmptyCellValue)
- {
- board[row, col].Number = EmptyCellValue;
- }
- else
- {
- i--;
- }
- }
- }
-
- private int GetCellsToRemoveCount(DifficultyLevel difficulty)
- {
- return difficulty switch
- {
- DifficultyLevel.Medium => 32,
- DifficultyLevel.Hard => 44,
- DifficultyLevel.VeryHard => 56,
- DifficultyLevel.SuperHard => 68,
- DifficultyLevel.Insane => 80,
- _ => 20
- };
- }
- }
3.数独难度等级
- public enum DifficultyLevel
- {
- ///
- /// 简单
- ///
- [Remark("简单")]
- Easy,
- ///
- /// 中等
- ///
- [Remark("中等")]
- Medium,
- ///
- /// 困难
- ///
- [Remark("困难")]
- Hard,
- ///
- /// 极难
- ///
- [Remark("极难")]
- VeryHard,
- ///
- /// 超难
- ///
- [Remark("超难")]
- SuperHard,
- ///
- /// 疯狂
- ///
- [Remark("疯狂")]
- Insane
- }
4.递归回溯算法寻找答案
- ///
- /// 递归回溯算法
- ///
- public class SudokuSolver
- {
- public SudokuCell[,] SolveSudoku(SudokuCell[,] board)
- {
- var solution = new SudokuCell[board.GetLength(0), board.GetLength(1)];
- Array.Copy(board, solution, board.Length);
- if (BacktrackSolve(solution))
- {
- return solution;
- }
- else
- {
- // 没有找到解
- return null;
- }
- }
-
- private bool BacktrackSolve(SudokuCell[,] board)
- {
- for (int row = 0; row < 9; row++)
- {
- for (int col = 0; col < 9; col++)
- {
- if (board[row, col].Number == 0)
- {
- for (int num = 1; num <= 9; num++)
- {
- if (IsValid(board, row, col, num))
- {
- board[row, col].Number = num;
-
- if (BacktrackSolve(board))
- {
- return true;
- }
-
- board[row, col].Number = 0; // 回溯
- }
- }
-
- return false; // 所有数字都尝试过,没有找到合适的解
- }
- }
- }
-
- return true; // 数独已经填满,找到解
- }
-
- private bool IsValid(SudokuCell[,] board, int row, int col, int num)
- {
- // 检查同行是否有重复数字
- for (int i = 0; i < 9; i++)
- {
- if (board[row, i].Number == num)
- {
- return false;
- }
- }
-
- // 检查同列是否有重复数字
- for (int i = 0; i < 9; i++)
- {
- if (board[i, col].Number == num)
- {
- return false;
- }
- }
-
- // 检查同九宫格是否有重复数字
- int startRow = row - row % 3;
- int startCol = col - col % 3;
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- if (board[startRow + i, startCol + j].Number == num)
- {
- return false;
- }
- }
- }
-
- return true; // 没有重复数字
- }
- }
5.数独创建中心
- public class SudokuCenter : IDisposable
- {
- public bool IsStart { get; set; } = false;
- private int _width;
- private int _height;
- public const int CELLSNUMBER = 9;
- public const int CELLSNUMBER2 = 20;
- private int _cellSize;
- private int _rowSize;
- public int CellSize=> _cellSize;
- public int RowSize => _rowSize;
- public int Height => _height;
- public int Width => _width;
- public int Padding => CELLSNUMBER2;
- private Bitmap _bitmap;
- public Bitmap GetBitmap
- {
- get=>(Bitmap)_bitmap?.Clone();
- private set => _bitmap = value;
- }
- public SudokuCell[,] Suduku { get;private set; }
- public SudokuCell[,] PlayerSuduku { get; private set; }
- ///
- /// 生成棋盘图
- ///
- ///
- ///
- public void InitCheckerBoard(int w, int h)
- {
- w -= (CELLSNUMBER2 * 2 + 1);
- h -= (CELLSNUMBER2 * 2 + 1);
- _width = w;
- _height = h;
- _cellSize = _width / CELLSNUMBER;
- _rowSize = _height / CELLSNUMBER;
- Bitmap bitmap = new Bitmap(_width + CELLSNUMBER2, _height + CELLSNUMBER2);
- using (var g = Graphics.FromImage(bitmap))
- {
- g.SmoothingMode = SmoothingMode.AntiAlias;
- //g.Clear(Color.Gray);
- DrawCheckerBoard(g);
- }
- _bitmap?.Dispose();
- GetBitmap = bitmap;
- }
- public SudokuCell[,] GenerateSudoku(DifficultyLevel difficulty)
- {
- SudokuGenerator sudokuGenerator = new SudokuGenerator();
- Suduku = sudokuGenerator.GenerateSudoku(difficulty);
- PlayerSuduku = new SudokuCell[Suduku.GetLength(0), Suduku.GetLength(1)];
- Array.Copy(Suduku, PlayerSuduku, Suduku.Length);
- return Suduku;
- }
- public Color SudukuColor { get; set; }= Color.Black;
- public Color SolutionColor { get; set; } = Color.Red;
- public Color TransparentColor { get; } = Color.Transparent;
- public Font Font { get; set; }= new Font("Arial", 20, FontStyle.Bold);
-
- public Bitmap DrawSolution(SudokuCell[,] board)
- {
- using SolidBrush brush = new SolidBrush(SolutionColor);
- using SolidBrush brush2 = new SolidBrush(SudukuColor);
- var bm = GetBitmap;
- using var g = Graphics.FromImage(bm);
- for (int row = 0; row < CELLSNUMBER; row++)
- {
- for (int col = 0; col < CELLSNUMBER; col++)
- {
-
- int number = Suduku[row, col].Number;
- if (number != 0)
- {
- DrawString(g, row, col, number.ToString(), brush2);
- }
- else
- {
- number = board[row, col].Number;
- DrawString(g, row, col, number.ToString(), brush);
- }
- }
- }
- return bm;
- }
- public void DrawSudoku(Graphics g, SudokuCell[,] board)
- {
- using SolidBrush brush = new SolidBrush(SudukuColor);
-
-
- for (int row = 0; row < CELLSNUMBER; row++)
- {
- for (int col = 0; col < CELLSNUMBER; col++)
- {
- int num= board[row, col].Number;
- if((num != 0))
- {
- DrawString(g,row,col,num.ToString(), brush);
- }
- }
- }
- }
- public void DrawString(Graphics g,int row,int col,string number, SolidBrush brush)
- {
- int x = CELLSNUMBER2 + col * _cellSize + _cellSize / 2 - 8;
- int y = CELLSNUMBER2 + row * _rowSize + _rowSize / 2 - 10;
- g.DrawString(number, Font, brush, new Point(x, y));
-
- }
- public Rectangle DrawTransparent(Graphics g, int row, int col)
- {
- int off = 5;
- int off2 = 7;
- int x = CELLSNUMBER2 + col * _cellSize + off;
- int y = CELLSNUMBER2 + row * _rowSize+ off;
- using (SolidBrush brush = new SolidBrush(Color.White)) // 使用透明色进行擦除
- {
- var rec = new Rectangle(x, y, CellSize - off2, RowSize - off2);
- g.FillRectangle(brush, rec);
- return rec;
- }
- }
- public bool IsSolutionCorrect(SudokuCell[,] board, SudokuCell[,] solution)
- {
- for (int row = 0; row < CELLSNUMBER; row++)
- {
- for (int col = 0; col < CELLSNUMBER; col++)
- {
- if (board[row, col].Number != solution[row, col].Number)
- {
- return false;
- }
- }
- }
-
- return true;
- }
- public bool IsValidMove(SudokuCell[,] board, int row, int col, int num)
- {
- // 检查行是否合法
- for (int i = 0; i < CELLSNUMBER; i++)
- {
- if (board[i, col].Number == num)
- {
- return false;
- }
- }
-
- // 检查列是否合法
- for (int i = 0; i < CELLSNUMBER; i++)
- {
- if (board[row, i].Number == num)
- {
- return false;
- }
- }
-
- // 检查子网格是否合法
- int subgridRow = (row / 3) * 3;
- int subgridCol = (col / 3) * 3;
-
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- if (board[subgridRow + i, subgridCol + j].Number == num)
- {
- return false;
- }
- }
- }
-
- return true;
- }
- private void DrawCheckerBoard(Graphics g)
- {
- using Pen pen = new Pen(Color.Black, 1);
- using Pen pen2 = new Pen(Color.Black, 2);
- using Font font = new Font("Arial", 10, FontStyle.Regular);
- using SolidBrush brush = new SolidBrush(Color.Black);
-
- for (int i = 0; i < CELLSNUMBER + 1; i++)
- {
- if (i == 0 || i % 3 == 0)
- {
- g.DrawLine(pen2, new Point(CELLSNUMBER2, CELLSNUMBER2 + i * _rowSize), new Point(CELLSNUMBER2 + _cellSize * CELLSNUMBER, CELLSNUMBER2 + i * _rowSize));
- g.DrawLine(pen2, new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + 0), new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + _rowSize * CELLSNUMBER));
- }
- else
- {
- g.DrawLine(pen, new Point(CELLSNUMBER2, CELLSNUMBER2 + i * _rowSize), new Point(CELLSNUMBER2 + _cellSize * CELLSNUMBER, CELLSNUMBER2 + i * _rowSize));
- g.DrawLine(pen, new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + 0), new Point(CELLSNUMBER2 + i * _cellSize, CELLSNUMBER2 + _rowSize * CELLSNUMBER));
- }
-
-
- int x = CELLSNUMBER2 + i * _cellSize + _cellSize / 2 - 5;
- int y = 0;
- g.DrawString((i + 1).ToString(), font, brush, new Point(x, y));
-
- x = 0;
- y = CELLSNUMBER2 + i * _rowSize + _rowSize / 2 - 5;
- g.DrawString((i + 1).ToString(), font, brush, new Point(x, y));
- }
- }
-
- public void Dispose()
- {
- _bitmap?.Dispose();
- }
- }
6.数字键盘

- public partial class FrmNumber : Form
- {
- public FrmNumber()
- {
- InitializeComponent();
-
- foreach (Control item in this.Controls)
- {
- item.Click += Item_Click;
- }
- }
- public Action
NumberCallback; - public Point ClickPoint { get; set; }
- public Point RowCell { get; set; }
- public Graphics Graphics { get; set; }
- private void Item_Click(object? sender, EventArgs e)
- {
- Button btn = sender as Button;
- NumberArg numberArg = new NumberArg();
- if (btn.Name == "btnClear")
- {
- numberArg.Type = NumberType.Clear;
-
- }
- else if (btn.Name == "btnClose")
- {
- numberArg.Type = NumberType.Close;
- }
- else
- {
- numberArg.Type = NumberType.Number;
- numberArg.Value = btn.Text;
- }
- numberArg.CllickPoint = ClickPoint;
- numberArg.RowCell = RowCell;
- numberArg.Graphics = Graphics;
- NumberCallback?.Invoke(numberArg);
- this.Close();
- }
-
- private void FrmNumber_FormClosing(object sender, FormClosingEventArgs e)
- {
- this.Dispose();
- }
- }
- public struct NumberArg
- {
- public NumberType Type { get; set; }
- public string Value { get; set; }
- public Point CllickPoint { get; set; }
- public Graphics Graphics { get; set; }
- public Point RowCell { get; set; }
- }
- public enum NumberType
- {
- Clear,
- Close,
- Number
- }
7.主窗体
- public partial class FrmMain : Form
- {
- private SudokuCenter _sudokuCenter;
- private System.Windows.Forms.Timer _timer;
- public FrmMain()
- {
- InitializeComponent();
- this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer |
- ControlStyles.UserPaint |
- ControlStyles.AllPaintingInWmPaint,
- true);
- this.UpdateStyles();
- this.DoubleBuffered = true;
-
-
- _sudokuCenter = new SudokuCenter();
- _sudokuCenter.InitCheckerBoard(this.pbGameBack.Width, this.pbGameBack.Height);
- BindType(typeof(DifficultyLevel), this.cbDifficultyLevel, "Easy");
- }
- private void BindType(Type type, ComboBox comboBox, string defaultValue)
- {
- var enumValues = Enum.GetValues(type);
- var list = new List
(); - int index = 0, curIndex = 0;
- foreach (Enum value in enumValues)
- {
- int hc = value.GetHashCode();
- list.Add(new IdValues
- {
- Id = hc.ToString(),
- Value = value.ToString(),
- Display= value.GetEnumDesc(),
- Standby = hc
- });
- if (value.ToString() == defaultValue)
- index = curIndex;
-
- curIndex++;
- }
-
- comboBox.ValueMember = "Id";
- comboBox.DisplayMember = "Display";
- comboBox.DataSource = list;
- comboBox.SelectedIndex = index;
- }
- private void pbGameBack_Paint(object sender, PaintEventArgs e)
- {
- if (sudukuBitmap != null)
- {
- e.Graphics.DrawImage(sudukuBitmap, 0, 0, pbGameBack.Width, pbGameBack.Height);
- }
- }
- public string Compute(long time)
- {
- if (time < 60)
- return $"00:{ChangeString(time)}";
- long minute = time / 60;
- if (minute < 60)
- return $"{ChangeString(minute)}:{ChangeString(time % 60)}";
- long hour = minute / 60;
- return $"{ChangeString(hour)}:{Compute(time - hour * 3600)}";
- }
- private string ChangeString(long val)
- {
- return val.ToString("D2");
- }
-
- ///
- /// 开始
- ///
- ///
- ///
- private void btnStart_Click(object sender, EventArgs e)
- {
- StartGame();
- }
- Bitmap sudukuBitmap;
- private void StartGame()
- {
- if (_sudokuCenter.IsStart)
- {
- if (MessageBox.Show("你正在开始游戏,确认重新开始吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
- {
- return;
- }
- }
-
- if (_timer != null)
- {
- _timer.Stop();
- _timer.Dispose();
- }
-
- time = 0;
- _timer = new System.Windows.Forms.Timer();
- _timer.Interval = 1000;
- _timer.Tick += timer_Tick;
- _timer.Start();
-
- DifficultyLevel level = (DifficultyLevel)(this.cbDifficultyLevel.Items[cbDifficultyLevel.SelectedIndex] as IdValues).Standby;
- var sudoku = _sudokuCenter.GenerateSudoku(level);
- this.pbGameBack.Image?.Dispose();
- sudukuBitmap?.Dispose();
- sudukuBitmap = null;
- sudukuBitmap = _sudokuCenter.GetBitmap;
- using var g = Graphics.FromImage(sudukuBitmap);
- _sudokuCenter.DrawSudoku(g, sudoku);
- _sudokuCenter.IsStart = true;
-
- pbGameBack.Invalidate();
- }
- long time = 0;
- private void timer_Tick(object? sender, EventArgs e)
- {
- lblTime.ExecBeginInvoke(() =>
- {
- lblTime.Text = Compute(++time);
-
- });
- }
-
- ///
- /// 答案
- ///
- ///
- ///
- private void btnSolution_Click(object sender, EventArgs e)
- {
- if (!_sudokuCenter.IsStart)
- {
- return;
- }
- if (MessageBox.Show("你正在开始游戏,确认显示答案吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
- {
- return;
- }
- SudokuSolver sudokuSolver = new SudokuSolver();
- var solveSudoku = sudokuSolver.SolveSudoku(_sudokuCenter.Suduku);
- var bm = _sudokuCenter.DrawSolution(solveSudoku);
-
- pbGameBack.Image?.Dispose();
- sudukuBitmap?.Dispose();
- sudukuBitmap = null;
- sudukuBitmap = bm;
- //pbGameBack.Image = bm;
- _sudokuCenter.IsStart = false;
- pbGameBack.Invalidate();
- }
-
- private void pbGameBack_MouseDown(object sender, MouseEventArgs e)
- {
- if (_sudokuCenter.Suduku == null || !_sudokuCenter.IsStart)
- return;
-
- int row = (e.Y - _sudokuCenter.Padding * 2) / _sudokuCenter.RowSize;
- int col = (e.X - _sudokuCenter.Padding * 2) / _sudokuCenter.CellSize;
- // 检测鼠标是否在小方格内
- if (row >= 0 && row < 9 && col >= 0 && col < 9)
- {
- var number = _sudokuCenter.Suduku[row, col].Number;
- if (number != 0)
- return;
-
- using (FrmNumber fn = new FrmNumber())
- {
- fn.NumberCallback = NumberCallback;
- Point p = pbGameBack.PointToScreen(Point.Empty);
- fn.StartPosition = FormStartPosition.Manual;
-
- fn.Location = new Point(p.X + e.X + (_sudokuCenter.CellSize >> 1), p.Y + e.Y + (_sudokuCenter.RowSize >> 1));
- fn.ClickPoint = new Point(e.X, e.Y);
- fn.RowCell = new Point(row, col);
- fn.ShowDialog();
- }
-
-
- }
- }
- private void NumberCallback(NumberArg arg)
- {
- switch (arg.Type)
- {
- case NumberType.Number:
- DrawString(arg.RowCell.X, arg.RowCell.Y, arg.Value);
- int num = Convert.ToInt32(arg.Value);
- if (cbPrompt.Checked)
- {
- bool status = _sudokuCenter.IsValidMove(_sudokuCenter.PlayerSuduku, arg.RowCell.X, arg.RowCell.Y, num);
- lblPrompt.Text = status ? "你真棒!" : "重复了";
- }
- else
- {
- lblPrompt.Text = "已写入";
- }
- _sudokuCenter.PlayerSuduku[arg.RowCell.X, arg.RowCell.Y].Number = num;
- pbGameBack.Invalidate(new Rectangle(SudokuCenter.CELLSNUMBER2 + arg.RowCell.Y * _sudokuCenter.CellSize, SudokuCenter.CELLSNUMBER2 + arg.RowCell.X * _sudokuCenter.RowSize, SudokuCenter.CELLSNUMBER2 + _sudokuCenter.CellSize, SudokuCenter.CELLSNUMBER2 + _sudokuCenter.RowSize));
-
- break;
- case NumberType.Clear:
- using (var g = Graphics.FromImage(sudukuBitmap))
- {
- _sudokuCenter.PlayerSuduku[arg.RowCell.X, arg.RowCell.Y].Number = 0;
- var rec= _sudokuCenter.DrawTransparent(g, arg.RowCell.X, arg.RowCell.Y);
- lblPrompt.Text = "已清除";
- pbGameBack.Invalidate(rec);
- }
- break;
- }
- }
- private void DrawString(int row, int col, string num)
- {
- using (var g = Graphics.FromImage(sudukuBitmap))
- {
- using SolidBrush brush = new SolidBrush(_sudokuCenter.SolutionColor);
- _sudokuCenter.DrawTransparent(g, row, col);
- _sudokuCenter.DrawString(g, row, col, num, brush);
- }
- }
- private void DrawString(Graphics g, int row, int col, string num)
- {
- using SolidBrush brush = new SolidBrush(_sudokuCenter.SolutionColor);
- _sudokuCenter.DrawTransparent(g, row, col);
- _sudokuCenter.DrawString(g, row, col, num, brush);
- pbGameBack.Invalidate(new Rectangle(SudokuCenter.CELLSNUMBER2 + col * _sudokuCenter.CellSize, SudokuCenter.CELLSNUMBER2 + row * _sudokuCenter.RowSize, _sudokuCenter.CellSize, _sudokuCenter.RowSize));
- }
-
- ///
- /// 提交
- ///
- ///
- ///
- private void btnSubmit_Click(object sender, EventArgs e)
- {
- if (!_sudokuCenter.IsStart)
- {
- return;
- }
- if (MessageBox.Show("你正在开始游戏,确认提交答案吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
- {
- return;
- }
-
- _timer.Stop();
-
- SudokuSolver sudokuSolver = new SudokuSolver();
- var solveSudoku = sudokuSolver.SolveSudoku(_sudokuCenter.Suduku);
- bool status = _sudokuCenter.IsSolutionCorrect(_sudokuCenter.PlayerSuduku, solveSudoku);
- if (status)
- {
- lblPrompt.Text = "全对了,你真棒!";
- MessageBox.Show("全对了,你真棒!", "恭喜");
- }
- else
- {
- lblPrompt.Text = "很遗憾,有错误!";
- MessageBox.Show("很遗憾,有错误!", "失败");
- for (int row = 0; row < SudokuCenter.CELLSNUMBER; row++)
- {
- for (int col = 0; col < SudokuCenter.CELLSNUMBER; col++)
- {
- if (solveSudoku[row, col].Number != _sudokuCenter.PlayerSuduku[row, col].Number)
- {
- this.DrawString(row, col, solveSudoku[row, col].Number.ToString());
- }
- }
- }
- pbGameBack.Invalidate();
- }
- _sudokuCenter.IsStart = false;
- }
- ///
- /// 重新开始
- ///
- ///
- ///
- private void btnRestart_Click(object sender, EventArgs e)
- {
- StartGame();
- }
-
- private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
- {
- _sudokuCenter.Dispose();
- this.pbGameBack.Image?.Dispose();
- this.pbGameBack.Dispose();
-
- if (_timer != null)
- {
- _timer.Stop();
- _timer.Dispose();
- }
- this.Dispose();
- }
- }
8.其它
- public class RemarkAttribute : Attribute
- {
- ///
- /// 备注
- ///
- public string Remark { get; set; }
-
- public RemarkAttribute(string remark)
- {
- this.Remark = remark;
- }
- }
- public static class EnumEx
- {
- ///
- /// 根据枚举元素,获取该枚举元素的描述信息
- ///
- ///
- ///
- ///
- public static string GetEnumDesc<T>(this T tField) where T : Enum
- {
- var description = string.Empty; //结果
- var inputType = tField.GetType(); //输入的类型
- var descType = typeof(RemarkAttribute); //目标查找的描述类型
-
- var fieldStr = tField.ToString(); //输入的字段字符串
- var field = inputType.GetField(fieldStr); //目标字段
-
- var isDefined = field?.IsDefined(descType, false);//判断描述是否在字段的特性
- if (isDefined ?? false)
- {
- var enumAttributes = field.GetCustomAttributes(descType, false) as RemarkAttribute[]; //得到特性信息
- description = enumAttributes?.FirstOrDefault()?.Remark ?? string.Empty;
- // description = string.Join(',', enumAttributes?.Select(t => t.Remark));
- }
- return description;
- }
- }
- public class IdValues
- {
- public string Id { get; set; }
- public string Value { get; set; }
- public string Value2 { get; set; }
- public string Value3 { get; set; }
- public string Value4 { get; set; }
- public string Value5 { get; set; }
- public int Standby { get; set; }
- public string Display { get; set; }
- public static bool operator ==(IdValues idValues, IdValues idValues2)
- {
- return idValues.Equals(idValues2);
- }
- public static bool operator !=(IdValues idValues, IdValues idValues2)
- {
- return !idValues.Equals(idValues2);
- }
- public override int GetHashCode()
- {
- var code = (Id, Value, Value2, Value3, Value4, Value5, Standby).GetHashCode();
- return code;
- }
- public override bool Equals(object? obj)
- {
- return obj?.GetHashCode() == GetHashCode();
- }
- const int TARGET = 0x1F;
- ///
- /// 将连续字段的哈希代码左移两位或更多位来加权各个哈希代码(最佳情况下,超出位 31 的位应环绕,而不是被丢弃)
- ///
- ///
- ///
- ///
- public int ShiftAndWrap(int value, int positions = 3)
- {
- positions &= TARGET;
- uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
- uint wrapped = number >> (32 - positions);
- return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0);
- }
- }
- internal static class SystemEx
- {
- ///
- /// 跨线程操作控件
- ///
- ///
- ///
- public static void ExecBeginInvoke(this Control con, Action action)
- {
- if (action == null) return;
- if (con.InvokeRequired)
- {
- con.BeginInvoke(new Action(action));
- }
- else
- {
- action();
- }
- }
- ///
- /// 跨线程操作控件
- ///
- ///
- ///
- public static void ExecInvoke(this Control con, Action action)
- {
- if (action == null) return;
- if (con.InvokeRequired)
- {
- con.Invoke(new Action(action));
- }
- else
- {
- action();
- }
- }
- }