用C语言写一个程序生成有唯一解的数独游戏
时间: 2023-12-29 12:09:28 浏览: 81
一个c语言编写的解数独的程序
好的,下面是一个简单的用C语言实现的生成有唯一解的数独游戏的程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL 9
#define BOX 3
#define EMPTY 0
int board[ROW][COL];
void init_board()
{
int i, j, k, n;
srand(time(NULL)); //设置随机种子
for(i = 0; i < ROW; i++)
{
for(j = 0; j < COL; j++)
{
board[i][j] = EMPTY; //初始化为空
}
}
for(k = 1; k <= 9; k++) //随机填充1~9
{
for(n = 1; n <= 10; n++) //每个数字填10次
{
i = rand() % ROW; //随机位置
j = rand() % COL;
if(board[i][j] == EMPTY && check_valid(i, j, k)) //如果该位置为空且填入该数字不冲突
{
board[i][j] = k; //填入该数字
}
}
}
}
int check_row(int row, int num)
{
int j;
for(j = 0; j < COL; j++)
{
if(board[row][j] == num) //如果该行已经有该数字了
return 0;
}
return 1;
}
int check_col(int col, int num)
{
int i;
for(i = 0; i < ROW; i++)
{
if(board[i][col] == num) //如果该列已经有该数字了
return 0;
}
return 1;
}
int check_box(int row, int col, int num)
{
int i, j;
int r = row - row % BOX; //找到所在宫的左上角坐标
int c = col - col % BOX;
for(i = r; i < r + BOX; i++)
{
for(j = c; j < c + BOX; j++)
{
if(board[i][j] == num) //如果该宫已经有该数字了
return 0;
}
}
return 1;
}
int check_valid(int row, int col, int num)
{
return check_row(row, num) && check_col(col, num) && check_box(row, col, num); //判断该数字是否合法
}
int solve_board(int row, int col)
{
if(row == ROW) //找到一个解
return 1;
if(board[row][col] != EMPTY) //该位置已经填过了,跳到下一个位置
{
if(col == COL - 1) //该行填完了,跳到下一行的第一个位置
return solve_board(row + 1, 0);
else //该行没填完,跳到下一个位置
return solve_board(row, col + 1);
}
else //该位置没有填过
{
int i;
for(i = 1; i <= 9; i++) //枚举1~9
{
if(check_valid(row, col, i)) //如果该数字合法
{
board[row][col] = i; //填入该数字
if(col == COL - 1) //该行填完了,跳到下一行的第一个位置
{
if(solve_board(row + 1, 0)) //递归求解下一行
return 1;
}
else //该行没填完,跳到下一个位置
{
if(solve_board(row, col + 1)) //递归求解下一个位置
return 1;
}
}
}
board[row][col] = EMPTY; //没有找到合法解,回溯
return 0;
}
}
void remove_numbers(int n)
{
int i, j;
int count = 0;
while(count < n) //随机挖去n个数字
{
i = rand() % ROW; //随机位置
j = rand() % COL;
if(board[i][j] != EMPTY) //如果该位置已经有数字了
{
int temp = board[i][j]; //暂时保存该位置的数字
board[i][j] = EMPTY; //挖去该数字
int backup[ROW][COL]; //备份数独
for(int x = 0; x < ROW; x++)
{
for(int y = 0; y < COL; y++)
{
backup[x][y] = board[x][y];
}
}
int count_sol = 0;
solve_board(0, 0); //求解数独
for(int x = 0; x < ROW; x++)
{
for(int y = 0; y < COL; y++)
{
board[x][y] = backup[x][y];
}
}
if(count_sol == 1) //如果有唯一解
{
count++; //挖去的数字数加1
}
else //没有唯一解,还原该位置的数字
{
board[i][j] = temp;
}
}
}
}
void print_board()
{
int i, j;
printf(" -----------------------\n");
for(i = 0; i < ROW; i++)
{
printf("| ");
for(j = 0; j < COL; j++)
{
if(board[i][j] == EMPTY)
printf(". ");
else
printf("%d ", board[i][j]);
if((j+1) % 3 == 0)
printf("| ");
}
printf("\n");
if((i+1) % 3 == 0)
printf(" -----------------------\n");
}
}
int main()
{
init_board(); //初始化数独
remove_numbers(40); //挖去40个数字
print_board(); //打印数独
return 0;
}
```
程序的主要思路是先随机填充1~9,再用回溯法求解数独,并随机挖去一些数字,直到产生一个唯一解的数独。具体实现细节可以参考代码中的注释。
阅读全文