C# 实现数独游戏

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<T> 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{/// <summary>/// 简单/// </summary>[Remark("简单")]Easy,/// <summary>/// 中等/// </summary>[Remark("中等")]Medium,/// <summary>/// 困难/// </summary>[Remark("困难")]Hard,/// <summary>/// 极难/// </summary>[Remark("极难")]VeryHard,/// <summary>/// 超难/// </summary>[Remark("超难")]SuperHard,/// <summary>/// 疯狂/// </summary>[Remark("疯狂")]Insane}

4.递归回溯算法寻找答案

/// <summary>/// 递归回溯算法/// </summary>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; }/// <summary>/// 生成棋盘图/// </summary>/// <param name="w"></param>/// <param name="h"></param>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<NumberArg> 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<IdValues>();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");}/// <summary>/// 开始/// </summary>/// <param name="sender"></param>/// <param name="e"></param>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);});}/// <summary>/// 答案/// </summary>/// <param name="sender"></param>/// <param name="e"></param>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));}/// <summary>/// 提交/// </summary>/// <param name="sender"></param>/// <param name="e"></param>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;}/// <summary>/// 重新开始/// </summary>/// <param name="sender"></param>/// <param name="e"></param>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{/// <summary>/// 备注/// </summary>public string Remark { get; set; }public RemarkAttribute(string remark){this.Remark = remark;}}public static class EnumEx{/// <summary>/// 根据枚举元素,获取该枚举元素的描述信息/// </summary>/// <typeparam name="T"></typeparam>/// <param name="tField"></param>/// <returns></returns>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;/// <summary>/// 将连续字段的哈希代码左移两位或更多位来加权各个哈希代码(最佳情况下,超出位 31 的位应环绕,而不是被丢弃)/// </summary>/// <param name="value"></param>/// <param name="positions"></param>/// <returns></returns>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{/// <summary>/// 跨线程操作控件/// </summary>/// <param name="con"></param>/// <param name="action"></param>public static void ExecBeginInvoke(this Control con, Action action){if (action == null) return;if (con.InvokeRequired){con.BeginInvoke(new Action(action));}else{action();}}/// <summary>/// 跨线程操作控件/// </summary>/// <param name="con"></param>/// <param name="action"></param>public static void ExecInvoke(this Control con, Action action){if (action == null) return;if (con.InvokeRequired){con.Invoke(new Action(action));}else{action();}}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/138944.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

elementUI elfrom表单验证无效、不起作用常见原因

今天遇到一个变态的问题&#xff0c;因页面比较复杂&#xff0c;出现几组条件判断&#xff0c;每个template内部又包含很多表单&#xff01;&#xff01; <template v-if"transformTypeValue 1"></template><template v-else-if"transformTypeV…

LeetCode 接雨水 木桶理论、dp预处理

原题链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题面&#xff1a; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a…

如何使用微信文件传输助手?看这里!

微信文件传输助手在哪里&#xff1f;为什么我找不到&#xff1f;有哪位朋友能够告诉我吗&#xff1f; 微信文件传输助手是微信官方推出的一款辅助工具&#xff0c;为用户提供了便捷的文件传输方式。用户在使用微信的过程中&#xff0c;可以随时随地通过该功能在手机和电脑之间任…

【TCP】三次握手 与 四次挥手 详解

三次握手 与 四次挥手 1. 三次握手2. 四次挥手三次握手和四次挥手的区别 在正常情况下&#xff0c;TCP 要经过三次握手建立连接&#xff0c;四次挥手断开连接 1. 三次握手 服务端状态转化&#xff1a; [CLOSED -> LISTEN] 服务器端调用 listen 后进入 LISTEN 状态&#xff…

Flink--4、DateStream API(执行环境、源算子、基本转换算子)

星光下的赶路人star的个人主页 注意力的集中&#xff0c;意象的孤立绝缘&#xff0c;便是美感的态度的最大特点 文章目录 1、DataStream API1.1 执行环境&#xff08;Execution Environment&#xff09;1.1.1 创建执行环境 1.2 执行模式&#xff08;Execution Mode&#xff09;…

0基础学three.js环境搭建(2)

这是0基础学three.js系列中的第二篇&#xff0c;在这篇里面我会带着大家把开发环境搭建起来&#xff0c;关于开发环境&#xff0c;方式很多&#xff0c;如果你没有基础&#xff0c;就跟着我的步骤一步一步来&#xff0c;保你不出错。 首先安装node环境&#xff0c;关于node是干…

【MySQL】 MySQL的增删改查(进阶)--贰

文章目录 &#x1f6eb;新增&#x1f6ec;查询&#x1f334;聚合查询&#x1f6a9;聚合函数&#x1f388;GROUP BY子句&#x1f4cc;HAVING &#x1f38b;联合查询⚾内连接⚽外连接&#x1f9ed;自连接&#x1f3c0;子查询&#x1f3a1;合并查询 &#x1f3a8;MySQL的增删改查(…

C语言的文件操作(炒详解)

⭐回顾回顾文件操作的相关细节⭐ 欢迎大家指正错误 &#x1f4dd;在之前的学习中&#xff0c;不管增加数据&#xff0c;减少数据&#xff0c;当程序退出时&#xff0c;所有的数据都会销毁&#xff0c;等下次运行程序时&#xff0c;又要重新输入相关数据&#xff0c;如果一直像这…

linux 设置打开文件数

可以使用下面的文件进行设置 /etc/security/limits.d/90-nproc.conf 先来看/etc/security/limits.d/90-nproc.conf 配置文件&#xff1a; [root ~]# cat /etc/security/limits.d/90-nproc.conf # Default limit for number of users processes to prevent # accidental fork…

计算机网络常见问题

1.谈一谈对OSI七层模型和TCP/IP四层模型的理解&#xff1f; 1.1.为什么要分层&#xff1f; 在计算机中网络是个复杂的系统&#xff0c;不同的网络与网络之间由于协议&#xff0c;设备&#xff0c;软件等各种原因在协调和通讯时容易产生各种各样的问题。例如&#xff1a;各物流…

图像形态学操作(连通性、腐蚀、膨胀)

相关概念 形态学操作-腐蚀 参数&#xff1a; img: 要处理的图像kernal :核结构iteration &#xff1a;腐蚀的次数&#xff0c;默认是1 形态学操作-膨胀 参数&#xff1a; img : 要处理的图像kernal : 核结构iteration : 膨胀的次数&#xff0c;默认为1 import cv2 as cv im…

STM32F103RCT6学习笔记2:串口通信

今日开始快速掌握这款STM32F103RCT6芯片的环境与编程开发&#xff0c;有关基础知识的部分不会多唠&#xff0c;直接实践与运用&#xff01;文章贴出代码测试工程与测试效果图&#xff1a; 目录 串口通信实验计划&#xff1a; 串口通信配置代码&#xff1a; 测试效果图&#…

Cpp/Qt-day020918Qt

目录 完善登录框 点击登录按钮后&#xff0c;判断账号&#xff08;admin&#xff09;和密码&#xff08;123456&#xff09;是否一致&#xff0c;如果匹配失败&#xff0c;则弹出错误对话框&#xff0c;文本内容“账号密码不匹配&#xff0c;是否重新登录”&#xff0c;给定两…

用AVR128单片机的音乐门铃

一、系统方案 1、使用按键控制蜂鸣器模拟发出“叮咚”的门铃声。 2、“叮”声对应声音频率714Hz&#xff0c;“咚”对应声音频率500Hz,这两种频率由ATmega128的定时器生成&#xff0c;定时器使用的工作模式自定&#xff0c;处理器使用内部4M时钟。“叮”声持续时间300ms&#x…

上PICO,沉浸式观看亚运直播,参与跨国界游戏竞技

备受瞩目的杭州第19届亚运会&#xff0c;将于9月23日正式开幕。据悉&#xff0c;这也是有史以来项目最多的一届亚运会&#xff0c;除部分传统奥运项目外&#xff0c;还包含武术、藤球、板球、克柔术、柔术等亚洲特色项目&#xff0c;以及霹雳舞、电子竞技等深受年轻人喜爱的新兴…

英伟达 nvidia 官方code llama在线使用

新一代编程语言模型Code Llama面世&#xff1a;重新定义编程的未来 随着人工智能和机器学习技术的迅速发展&#xff0c;我们现在迎来了一款革命性的大型编程语言模型——Code Llama。该模型是基于Llama 2研发的&#xff0c;为开放模型中的佼佼者&#xff0c;其性能达到了行业领…

2023工博会强势回归!智微工业携八大系列重磅亮相

中国国际工业博览会&#xff08;简称"中国工博会"&#xff09;自1999年创办以来&#xff0c;历经二十余年发展创新&#xff0c;通过专业化、市场化、国际化、品牌化运作&#xff0c;已发展成为通过国际展览业协会&#xff08;UFI&#xff09;认证、中国工业领域规模最…

早餐与风景

来吧&#xff0c;我用流水账描述下这一天。 时维九月&#xff0c;北京的早上有点冷&#xff0c;因为今天有个市场活动要去支撑&#xff0c;按照会议时间的要求&#xff0c;我需要在早上7点半就赶到会场&#xff0c;所以昨天晚上我加班到凌晨处理完了今天要给出去的材料&#xf…

react实现动态递增展示数字特效

在可视化展示界面时有一种场景&#xff0c;就是页面在初始化的时候&#xff0c;有些数字展示想要从某个值开始动态递增到实际值&#xff0c;形成一种动画效果。例如&#xff1a; 写一个数字递增的组件&#xff0c;代码如下&#xff1a; import {useEffect, useRef, useState} f…

基于Java的Base64编解码优化探讨

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…