告诉我每一步具体的代码
时间: 2023-07-10 16:13:57 浏览: 55
好的,下面是每一步具体的代码:
1. 打开 Visual Studio 2022,选择创建新项目,选择 Visual C#,选择 Windows 窗体应用程序,命名为 Sudoku,点击创建按钮。
2. 在窗体上拖拽一个 TableLayoutPanel 控件,将其行数和列数都设置为 9,每个单元格的大小都设置为相等。
3. 在 TableLayoutPanel 控件中添加 81 个 TextBox 控件,用于用户输入数独的初始数据。在窗体的 Form_Load 事件处理程序中,添加以下代码:
```
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
TextBox tb = new TextBox();
tb.Text = "";
tb.TextAlign = HorizontalAlignment.Center;
tb.Font = new Font("Arial", 12);
tb.MaxLength = 1;
tb.KeyPress += new KeyPressEventHandler(tb_KeyPress);
tablePanel.Controls.Add(tb, j, i);
}
}
}
```
其中,tablePanel 是 TableLayoutPanel 控件的名称,tb_KeyPress 是 TextBox 控件的 KeyPress 事件处理程序,用于限制用户输入的字符必须是数字 1 到 9。
4. 在窗体上添加一个 Button 控件,命名为 btnSolve,用于解决数独。双击 btnSolve 控件,打开按钮的 Click 事件处理程序,在其中编写解决数独的代码。添加以下代码:
```
private void btnSolve_Click(object sender, EventArgs e)
{
int[,] grid = new int[9, 9];
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
TextBox tb = (TextBox)tablePanel.GetControlFromPosition(j, i);
if (tb.Text == "")
{
grid[i, j] = 0;
}
else
{
grid[i, j] = Convert.ToInt32(tb.Text);
}
}
}
if (SolveSudoku(grid))
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
TextBox tb = (TextBox)tablePanel.GetControlFromPosition(j, i);
tb.Text = grid[i, j].ToString();
}
}
}
else
{
MessageBox.Show("无解!");
}
}
```
其中,SolveSudoku 是解决数独的函数,将在下一步中编写。该函数先将用户输入的数独数据存储到一个二维数组中,然后调用 SolveSudoku 函数解决数独。如果有解,则将解填入 TableLayoutPanel 中的 TextBox 控件。
5. 编写解决数独的代码。添加以下代码:
```
private bool SolveSudoku(int[,] grid)
{
int row = 0, col = 0;
if (!FindUnassignedLocation(grid, ref row, ref col))
{
return true;
}
for (int num = 1; num <= 9; num++)
{
if (IsSafe(grid, row, col, num))
{
grid[row, col] = num;
if (SolveSudoku(grid))
{
return true;
}
grid[row, col] = 0;
}
}
return false;
}
private bool FindUnassignedLocation(int[,] grid, ref int row, ref int col)
{
for (row = 0; row < 9; row++)
{
for (col = 0; col < 9; col++)
{
if (grid[row, col] == 0)
{
return true;
}
}
}
return false;
}
private bool UsedInRow(int[,] grid, int row, int num)
{
for (int col = 0; col < 9; col++)
{
if (grid[row, col] == num)
{
return true;
}
}
return false;
}
private bool UsedInCol(int[,] grid, int col, int num)
{
for (int row = 0; row < 9; row++)
{
if (grid[row, col] == num)
{
return true;
}
}
return false;
}
private bool UsedInBox(int[,] grid, int boxStartRow, int boxStartCol, int num)
{
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 3; col++)
{
if (grid[row + boxStartRow, col + boxStartCol] == num)
{
return true;
}
}
}
return false;
}
private bool IsSafe(int[,] grid, int row, int col, int num)
{
return !UsedInRow(grid, row, num) &&
!UsedInCol(grid, col, num) &&
!UsedInBox(grid, row - row % 3, col - col % 3, num);
}
```
其中,SolveSudoku 函数用于递归解决数独,FindUnassignedLocation 函数用于找到一个还未填写数字的格子,IsSafe 函数用于判断某个数字是否可以填入某个格子中,UsedInRow 函数用于判断某个数字是否已经在某行中出现过,UsedInCol 函数用于判断某个数字是否已经在某列中出现过,UsedInBox 函数用于判断某个数字是否已经在某宫中出现过。
6. 在窗体的 tb_KeyPress 事件处理程序中,添加以下代码,用于限制用户输入的字符必须是数字 1 到 9:
```
private void tb_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Back)
{
e.Handled = false;
}
else if (e.KeyChar >= '1' && e.KeyChar <= '9')
{
e.Handled = false;
}
else
{
e.Handled = true;
}
}
```
7. 在窗体上添加一个 Label 控件,命名为 lblTitle,用于显示程序的标题。在窗体的 Form_Load 事件处理程序中,添加以下代码:
```
private void Form1_Load(object sender, EventArgs e)
{
lblTitle.Text = "9*9数独";
lblTitle.Font = new Font("Arial", 16, FontStyle.Bold);
lblTitle.TextAlign = ContentAlignment.MiddleCenter;
lblTitle.Dock = DockStyle.Top;
this.Controls.Add(lblTitle);
//...
}
```
其中,this 是窗体的名称,lblTitle 是 Label 控件的名称。
8. 在窗体的 btnSolve_Click 事件处理程序中,添加以下代码,用于判断数独是否有解:
```
private void btnSolve_Click(object sender, EventArgs e)
{
//...
if (SolveSudoku(grid))
{
//...
}
else
{
MessageBox.Show("无解!");
}
}
```
到此,制作9*9数独c#程序的步骤和代码就全部介绍完毕了。