c语言数独游戏
1. 求用c语言编写一个解数独的程序,急
用0代表要填的数
#include <stdio.h>
#include <stdlib.h>
#define SIZE 9
#define get_low_bit(x) ((~x&(x-1))+1)
struct{
int left;
char num;
char try;
}board[SIZE][SIZE];
int bit2num(int bit)
{
switch(bit){
case 1:case 2:
return bit;
case 4:
return 3;
case 8:
return 4;
case 16:
return 5;
case 32:
return 6;
case 64:
return 7;
case 128:
return 8;
case 256:
return 9;
}
}
void printf_res()
{
int i, j, k;
for(i=0; i<SIZE; i++)
{
if(i%3==0)
{
for(j=0; j<SIZE*2+4; j++)
putchar('-');
putchar('\n');
}
for(j=0; j<SIZE; j++)
{
if(j%3==0)
putchar('|');
if(board[i][j].num > 0)
printf("\033[0;31m%2d\033[0m", board[i][j].num);
else
printf("%2d", board[i][j].try);
}
printf("|\n");
}
for(i=0; i<SIZE*2+4; i++)
putchar('-');
putchar('\n');
}
void sub(int i, int j, int bit)
{
int k, m;
for(k=0; k<SIZE; k++)
{
board[k][j].left &= ~bit;
board[i][k].left &= ~bit;
}
for(k=i/3*3; k<(i/3+1)*3; k++)
for(m=j/3*3; m<(j/3+1)*3; m++)
board[k][m].left &= ~bit;
}
void init()
{
int i, j;
for(i=0; i<SIZE; i++)
for(j=0; j<SIZE; j++)
if(board[i][j].num > 0)
sub(i, j, 1<<(board[i][j].num-1));
else if(board[i][j].try > 0)
sub(i, j, 1<<(board[i][j].try-1));
}
void add(int i, int j, int bit)
{
int k, m;
for(k=0; k<SIZE; k++)
{
board[k][j].left |= bit;
board[i][k].left |= bit;
}
for(k=i/3*3; k<(i/3+1)*3; k++)
for(m=j/3*3; m<(j/3+1)*3; m++)
board[k][m].left |= bit;
}
void solve(int pos)
{
int i=pos/SIZE;
int j=pos%SIZE;
int bit, left;
if(pos == SIZE*SIZE)
{
printf_res();
exit(0);
}
if(board[i][j].num > 0)
solve(pos+1);
else
for(left=board[i][j].left; left; left&=(left-1))
{
bit = get_low_bit(left);
sub(i, j, bit);
board[i][j].try = bit2num(bit);
solve(pos+1);
add(i, j, bit);
board[i][j].try=0;
init();
}
}
int main()
{
int i, j, c;
for(i=0; i<SIZE; i++)
for(j=0; j<SIZE; j++)
{
while((c=getchar())<'0' || c>'9')
;
board[i][j].num = c-'0';
board[i][j].try = 0;
board[i][j].left = 0x0001FF;
}
init();
solve(0);
return 0;
}
2. 用c语言写一个简易数独的思路。要代码
#include<stdio.h>
intnum[9][9],xy[9][9];
intcheck(intx,inty){
inti,m,n;
for(i=0;i<9;i++)
if((xy[x][y]==xy[i][y]&&i!=x)||(xy[x][y]==xy[x][i]&&i!=y))
return0;
for(i=0,m=x/3*3,n=y/3*3;i<9;i++)
if(xy[x][y]==xy[m+i/3][n+i%3]&&m+i/3!=x&&n+i%3!=y)
return0;
return1;
}
voidsearch(intx,inty){
if(x==9)
for(x=0;x<9;x++){
for(y=0;y<9;y++)
printf("%d",xy[x][y]);
printf(" ");
}
elseif(num[x][y])
search(x+(y+1)/9,(y+1)%9);
else
for(xy[x][y]=1;xy[x][y]<=9;xy[x][y]++)
if(check(x,y))
search(x+(y+1)/9,(y+1)%9);
return;
}
intmain(){
inti,j;
for(i=0;i<9;i++)
for(j=0;j<9;j++){
scanf("%d",&num[i][j]);
xy[i][j]=num[i][j];
}
search(0,0);
return0;
}
输入为9行9列整数,已知的整数填写对应的数字,尚待计算的未知数字填写0。
该代码的思路很简单,就是从第一行第一列开始依次填入数字,检查是否是在同一行、同一列、同一宫有没有填入重复数字,如果没有就继续填入下一个数字,如果有就返回。
虽然效率稍低,但原理简单、表述直白、易于理解,更有效率的代码是使用十字链表完成,如有兴趣可继续深入
3. c语言 编程 数独
当年我们做大程的时候本来也想做数独来着,后来时间不够没做成.不知道专业人士怎么编的,只能提供一点当时的思路给你,
1.9*9个格子对应一个数组A,数组的第一个值从0到9表示其中填的数字,0就是不填,另一个值表示它在桌面上的位置就是坐标
2.需要10张图片,空白和9个数字
3.通过对鼠标点击的反应改变格子数组A的值,且将相应图片覆盖在相应坐标上
4.事先输入若干组数组A的值(每组81个数),作为题库
5.进行游戏时随机抽取题库中的一组,再随机抽取若干格子显示出来,其他留白.
6.填完后用三个循环判断下每行每列每块是否有相同的数字,没有则通过.
具体编按钮、放图、鼠标点击响应等各种问题查一下书,有很多书上有很多教的这种一小段一小段的程序源代码,直接抄下就行了。
加油^^
4. 求C语言数独游戏辅助代码
/*************************************************************
功能:数独游戏助手。
*************************************************************/
#include<stdio.h>
int fun(int a[9][9][10],int i,int j,int t);
void main()
{
int a[9][9][10];//三维数组
int i,j,k=0;
int t;
int p=0;
int n=10;
//对数独初始化
for(i=0;i<9;i++)
for(j=0;j<9;j++)
for(k=0;k<10;k++)
a[i][j][k]=k;
//开始输入题目
printf("请输入数独表:\n");
for(i=0;i<9;i++)
{
printf("第%d行:",i+1);
for(j=0;j<9;j++)
{
scanf("%d",&t);
if(t!=0)
{
a[i][j][0]=t;
fun(a,i,j,t);
}
}
}
//自动寻找可能值中为
while(n--)
{
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
if(a[i][j][0]==0)
{
for(k=1;k<10;k++)
{
if(a[i][j][k]!=0)
{
p++;
if(p==1)
t=a[i][j][k];
if(p>=2)
{
p=0;
t=0;
break;
}
}
}
if(p!=0)
{
if(t!=0)
{
a[i][j][0]=t;
fun(a,i,j,t);
p=0;
}
}
}
}
}
//输出可能值
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
printf("i=%d,j=%d",i+1,j+1);
for(k=1;k<10;k++)
if(a[i][j][k])
printf("%3d",a[i][j][k]);
printf("\n");
}
//开始输出
k=0;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
printf("%3d",a[i][j][0]),k++;
if(k%9==0)
printf("\n");
}
}
//求出每一个未知数的可能的值
int fun(int a[9][9][10],int i,int j,int t)
{
int k;
for(k=1;k<10;k++)
a[i][j][k]=0;//a[i][j]为全部为0
for(int j1=0;j1<9;j1++)
{
if(j1!=j)
a[i][j1][t]=0;//第j列不能有t,将t置0
}
for(int i1=0;i1<9;i1++)
{
if(i1!=i)
a[i1][j][t]=0;//第i行不能有t,将t置0
}
if(i<3)//行0,1,2
{
if(j<3)//列0,1,2
{
for(int i1=0;i1<=2;i1++)
for(int j1=0;j1<=2;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第一个九宫格
else if(j>5)//列6,7,8
{
for(int i1=0;i1<=2;i1++)
for(int j1=6;j1<=8;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第三个九宫格
else//列3,4,5
{
for(int i1=0;i1<=2;i1++)
for(int j1=3;j1<=5;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第二个九宫格
}
else if(i>5)//行6,7,8
{
if(j<3)//列0,1,2
{
for(int i1=6;i1<=8;i1++)
for(int j1=0;j1<=2;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第七个九宫格
else if(j>5)//列6,7,8
{
for(int i1=6;i1<=8;i1++)
for(int j1=6;j1<=8;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第九个九宫格
else//列3,4,5
{
for(int i1=6;i1<=8;i1++)
for(int j1=3;j1<=5;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第八个九宫格
}
else//行3,4,5
{
if(j<3)//列0,1,2
{
for(int i1=3;i1<=5;i1++)
for(int j1=0;j1<=2;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第四个九宫格
else if(j>5)//列6,7,8
{
for(int i1=3;i1<=5;i1++)
for(int j1=6;j1<=8;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第六个九宫格
else//列3,4,5
{
for(int i1=3;i1<=5;i1++)
for(int j1=3;j1<=5;j1++)
{
if(i1!=i && j1!=j)
a[i1][j1][t]=0;
}
}//第五个九宫格
}
return 1;
}
//对三维数组排序
void paixu(int a[9][9][10])
{
int i,j,k;
int t;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
{
for(int i1=1;i1<=9;i1++)
{
k=i1;
for(int j1=i1;j1<=9;j1++)
if(a[i][j][j1]>a[i][j][k])
k=j1;
t=a[i][j][k];
a[i][j][k]=a[i][j][i1];
a[i][j][i1]=t;
}
}
}
//程序在VC++6,.0环境中可运行。不懂的追问哦!
5. 基于SAT的数独游戏求解程序,求C语言代码
用0代表要填的数
#include <stdio.h>
#include <stdlib.h>
#define SIZE 9
#define get_low_bit(x) ((~x&(x-1))+1)
struct{
int left;
char num;
char try;
}board[SIZE][SIZE];
int bit2num(int bit)
{
switch(bit){
case 16:
case 256:
return 9;
基础解法
排除法(摒除法)
摒除法:用数字去找单元内唯一可填空格,称为摒除法,数字可填唯一空格称为排除法 (Hidden Single)。
根据不同的作用范围,摒余解可分为下述三种:
数字可填唯一空格在“宫”单元称为宫排除(Hidden Single in Box),也称宫摒除法。
数字可填唯一空格在“行”单元称为行排除法(Hidden Single in Row),也称行摒除法。
6. 数独 算法 C语言 代码
一、步骤:
1.对每一个空格,根据规则推断它可能填入的数字,并存储它的所有可能值;
2.根据可能值的个数,确定填写的顺序。比如说,有些空格只有一种可能,那必然是正确的结果,首先填入。
3.将所有只有一种可能的空格填写完毕以后,回到步骤1,重新确定剩下空格的可能值;
4.当没有只有一种可能的空格时(即每个空格都有两种以上可能),按照可能值个数从小到大的顺序,使用深度(广度)优先搜索,完成剩下空格。
二、例程:
#include<windows.h>
#include<stdio.h>
#include<time.h>
charsd[81];
boolisok=false;
//显示数独
voidshow()
{
if(isok)puts("求解完成");
elseputs("初始化完成");
for(inti=0;i<81;i++)
{
putchar(sd[i]+'0');
if((i+1)%9==0)putchar(' ');
}
putchar(' ');
}
//读取数独
boolInit()
{
FILE*fp=fopen("in.txt","rb");
if(fp==NULL)returnfalse;
fread(sd,81,1,fp);
fclose(fp);
for(inti=0;i<81;i++)
{
if(sd[i]>='1'&&sd[i]<='9')sd[i]-='0';
elsesd[i]=0;
}
show();
returntrue;
}
//递归解决数独
voidforce(intk)
{
if(isok)return;
if(!sd[k])
{
for(intm=1;m<=9;m++)
{
boolmm=true;
for(intn=0;n<9;n++)
{
if((m==sd[k/27*27+(k%9/3)*3+n+n/3*6])||(m==sd[9*n+k%9])||(m==sd[k/9*9+n]))
{
mm=false;
break;
}
}
if(mm)
{
sd[k]=m;
if(k==80)
{
isok=true;
show();
return;
}
force(k+1);
}
}
sd[k]=0;
}
else
{
if(k==80)
{
isok=true;
show();
return;
}
force(k+1);
}
}
intmain()
{
system("CLS");
if(Init())
{
doublestart=clock();
force(0);
printf("耗时%.0fms",clock()-start);
}
elseputs("初始化错误");
getchar();
}
7. C语言编写一个3*3数独,保证每行每列的和都相等!!求求各位大神了
/*
因为你说是数独可是你只表述了行列相等,如果是数独应该对角线相加也相等,所以我写了两个判断函数,judge1为对角线也相等的情况,judge为你描述的行列和相等(情况太多了)
结题方案只需要做一次dfs就可以了,还需要配合一个栈来存储dfs的路径,将每个符合条件的路径做一次行列和是否相等的判断然后输出就是要的结果!
*/
#include<stdio.h>
#include<memory.h>
#include<stdbool.h>
//stack
inta[9]={0};//a[0]--a[0][0]a[1]--a[0][1]andsoonsimulatestack
intlen=0;
//dfs
intvisited[10]={0};
booljudge()//行列相等
{
inti,j;
inttmp[6]={0};
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[i]+=a[3*i+j];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[3+i]+=a[i+3*j];
intjud=tmp[0];
for(i=1;i<6;i++)
{
if(jud!=tmp[i])
returnfalse;
}
returntrue;
}
booljudge1()//行列相等对角线也相等
{
inti,j;
inttmp[8]={0};
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[i]+=a[3*i+j];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
tmp[3+i]+=a[i+3*j];
tmp[7]=a[0]+a[4]+a[8];
tmp[6]=a[2]+a[4]+a[6];
intjud=tmp[0];
for(i=1;i<8;i++)
{
if(jud!=tmp[i])
returnfalse;
}
returntrue;
}
voidprinta()
{
intt,p;
for(t=0;t<3;t++)
{
for(p=0;p<3;p++)
{
printf("%d",a[3*t+p]);
}
printf(" ");
}
}
voiddfs(inti,intv[])
{
if(i==10)//findonesolution
{
if(judge1())//给你写了两个判断函数如果对角线也相等那么用judge1()即可判断
printa();
return;
}
intj;
for(j=1;j<=9;j++)
{
inttmp[10];
memcpy(tmp,v,10*sizeof(int));
if(tmp[j]==0)
{
tmp[j]=1;
a[len++]=j;
//printf("%d%d ",len-1,a[len-1]);
dfs(i+1,tmp);
len--;
}
}
}
intmain(void)
{
dfs(1,visited);
return0;
}
8. 急!C语言递归解数独
我从网上随便找个一个帮你改了改。首先把你要解的数独放入一个文件sudo_input里,和你编译后的exe文件在同一目录。内容为:
1 0 0 0
0 0 0 2
0 0 4 0
0 3 0 0
代码如下(备注:基本上这个也可以做9路甚至更多的,只需改动LENGTH和SUBLEN值即可):
#include<stdlib.h>
#include<stdio.h>
#defineLENGTH4
#defineSUBLEN2
intanswer=0;
voidprintSudo(intarray[][LENGTH]){
printf(" ");
inti,j;
for(i=0;i<LENGTH;i++){
if((i+1)%SUBLEN==0)
printf(" ");
for(j=0;j<LENGTH;j++){
if((j+1)%SUBLEN==0)
printf(" ");
printf("%d",array[i][j]);
}
printf(" ");
}
exit(0);
}
voidinitSudoArray(intarray[][LENGTH]){
inti,j;
FILE*fp;
if((fp=fopen("sudo_input","r"))==NULL){
printf("Fileopenfailed! ");
exit(-1);
}
for(i=0;i<LENGTH;i++){
for(j=0;j<LENGTH;j++){
fscanf(fp,"%d",&array[i][j]);
}
}
fclose(fp);
}
intcheckSudo(intarray[][LENGTH],inti,intj,inttestVal){
introw,col;
printf("checkSudofor[%d][%d]testVal=%d ",i,j,testVal);
//fixedtocolj,checkfortherows
for(row=0;row<LENGTH;row++){
printf("checkforrows![%d][%d]=%d ",row,j,array[row][j]);
if(array[row][j]==testVal)
return0;
}
//fixedtorowi,checkforcols
for(col=0;col<LENGTH;col++){
printf("checkforcols![%d][%d]=%d ",i,col,array[i][col]);
if(array[i][col]==testVal)
return0;
}
//checkforthesub-square
introw_subSquare=(i/SUBLEN)*SUBLEN;
intcol_subSquare=(j/SUBLEN)*SUBLEN;
printf("[%d][%d] ",row,col);
for(row=row_subSquare;row<row_subSquare+SUBLEN;row++){
for(col=col_subSquare;col<col_subSquare+SUBLEN;col++){
printf("checkforsub-square![%d][%d]=%d ",row,col,array[row][col]);
if(array[row][col]==testVal)
return0;
}
}
return1;
}
//
voidsudo_solve(intarray[][LENGTH],intlength){
//iforrows,jforcols
inti,j;
inttestVal;
inttempArray[LENGTH][LENGTH];
//mpthearraytotempArray
for(i=0;i<LENGTH;i++){
for(j=0;j<LENGTH;j++)
tempArray[i][j]=array[i][j];
}
i=length/LENGTH;
j=length%LENGTH;
printf("array[%d][%d]=%d",i,j,array[i][j]);
if(array[i][j]!=0){
//thereisavalintheslotarray[i][j]
if(length==80)
printSudo(tempArray);
else
sudo_solve(tempArray,length+1);
}else{
//thereisnovalintheslotarray[i][j]
for(testVal=1;testVal<=LENGTH;testVal++){
if(checkSudo(tempArray,i,j,testVal)!=0){
tempArray[i][j]=testVal;
if(length==LENGTH*LENGTH-1)
printSudo(tempArray);
else
sudo_solve(tempArray,length+1);
tempArray[i][j]=0;
}
}
}
}
intmain(void){
intarray[LENGTH][LENGTH];
initSudoArray(array);
sudo_solve(array,0);
if(answer==0)
printf("Thereisnoanswerforthissudo!");
return0;
}