2.非唯一解挖坑
3.正确性判断
4.使用localStorage,制作继续游戏功能
5.简单使用jquery mobile
6.在某日早上,在地铁时代报上看到数独游戏,就想在网页上做一个试试
百度google了下生成算法,没有发现有效的生成算法,很多是随机回滚类型[还有错误的算法。。。]
在纸上随意写写,排排,发现还有个简单的生成数独的方法,但没有论证是否可以生成所有数独
一、步骤:
1.对每一个空格,根据规则推断它可能填入的数字,并存储它的所有可能值;
2.根据可能值的个数,确定填写的顺序。比如说,有些空格只有一种可能,那必然是正确的结果,首先填入。
3.将所有只有一种可能的空格填写完毕以后,回到步骤1,重新确定剩下空格的可能值;
4.当没有只有一种可能的空格时(即每个空格都有两种以上可能),按照可能值个数从小到大的顺序,使用深度(广度)优先搜索,完成剩下空格。
二、例程:
#include <windows.h>#include <stdio.h>
#include <time.h>
char sd[81]
bool isok = false
//显示数独
void show()
{
if (isok) puts("求解完成")
else puts("初始化完成")
for (int i = 0 i < 81 i++)
{
putchar(sd[i] + '0')
if ((i + 1) % 9 == 0) putchar('\n')
}
putchar('\n')
}
//读取数独
bool Init()
{
FILE *fp = fopen("in.txt", "rb")
if (fp == NULL) return false
fread(sd, 81, 1, fp)
fclose(fp)
for (int i = 0 i < 81 i++)
{
if (sd[i] >= '1' && sd[i] <= '9') sd[i] -= '0'
else sd[i] = 0
}
show()
return true
}
//递归解决数独
void force(int k)
{
if (isok) return
if (!sd[k])
{
for (int m = 1 m <= 9 m++)
{
bool mm = true
for (int n = 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)
}
}
int main()
{
system("CLS")
if (Init())
{
double start = clock()
force(0)
printf("耗时%.0fms", clock() - start)
}
else puts("初始化错误")
getchar()
}
这是数独啊,就是下面的图片所示,9*9的格,你还要输出所有的数独?你知道有6,670,903,752,021,072,936,960种不同的数独,就算计算机(运行效率极高的计算机)每秒生成10个数独你可以算算要几千年哈。具体的可以去看百度的百科,下面有一个用Pascal写的求数独的程序。
下面是有C++写的随机生成数独的算法,你要的输出所有数独在时间上来说是不可能的哈:
#ifndef SUDOKU_RICK_0701_
#define SUDOKU_RICK_0701_
class CSudoku
{
int map[9][9]
int smod
int solves
int check(int,int,int*)
void dfs()
public:
enum{ANY=0,ALL=1}
CSudoku(int n=40)// 随机生成数独,n越大越难
CSudoku(int *data)// 人工指定数独
virtual ~CSudoku()
void display()// 显示数独
int resolve(int mod=ALL)// 解数独
}
#endif
//#include "sudoku.h"
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
CSudoku::CSudoku(int n)
{
int i,j
srand(time(0))
do
{
for(i=0i<9++i)
{
for(j=0j<9++j)
map[i][j]=0
j=rand()%9
map[i][j]=i+1
}
}
while(!resolve(ANY))
// 挖窟窿
for(int k=0k<n)
{
i=rand()%81
j=i%9
i=i/9
if(map[i][j]>0)
{
map[i][j]=0
++k
}
}
//printf("(randomized sudoku created with %d blanks.)\n",blanks)
}
CSudoku::CSudoku(int *data)
{
int *pm=(int*)map
for(int i=0i<81++i)
pm[i]=data[i]
}
CSudoku::~CSudoku()
{
return
}
void CSudoku::display()
{
for(int i=0i<9++i)
{
for(int j=0j<9++j)
{
if(map[i][j]>0)
printf("< %d > ",map[i][j])
else
printf("[ ] ")
}
printf("\n")
}
}
int CSudoku::resolve(int mod)
{
smod=mod
if(mod==ALL)
{
solves=0
dfs()
return solves
}
else if(mod==ANY)
{
try
{
dfs()
return 0
}
catch(int)
{
return 1
}
}
return 0
}
int CSudoku::check(int y,int x,int *mark)
{
int i,j,is,js,count=0
for(i=1i<=9++i)
mark[i]=0
for(i=0i<9++i)
mark[map[y][i]]=1
for(i=0i<9++i)
mark[map[i][x]]=1
is=y/3*3
js=x/3*3
for(i=0i<3++i)
{
for(j=0j<3++j)
mark[map[is+i][js+j]]=1
}
for(i=1i<=9++i)
if(mark[i]==0)
count++
return count
}
void CSudoku::dfs()
{
int i,j,im=-1,jm,min=10
int mark[10]
for(i=0i<9++i)
{
for(j=0j<9++j)
{
if(map[i][j])
continue
int c=check(i,j,mark)
if(c==0)
return
if(c<min)
{
im=i
jm=j
min=c
}
}
}
if(im==-1)
{
if(smod==ALL)
{
printf("No. %d:\n",++solves)
display()
return
}
else if(smod==ANY)
{
throw(1)
}
}
check(im,jm,mark)
for(i=1i<=9++i)
{
if(mark[i]==0)
{
map[im][jm]=i
dfs()
}
}
map[im][jm]=0
}
#include <iostream>
//#include "sudoku.h"
using namespace std
int main()
{
int data1[]=
{4,9,0,0,0,6,0,2,7,
5,0,0,0,1,0,0,0,4,
6,0,0,0,0,8,0,0,3,
1,0,4,0,0,0,0,0,0,
0,6,0,0,0,0,0,5,0,
0,0,0,0,0,0,2,0,8,
7,0,0,2,0,0,0,0,5,
8,0,0,0,9,0,0,0,1,
3,4,0,5,0,0,0,6,2
}
int data2[]=
{7,4,0,0,8,0,0,1,6,
9,0,0,0,3,5,0,0,4,
0,0,0,7,0,0,0,0,0,
0,7,0,0,0,9,5,0,0,
6,1,0,0,5,0,0,8,7,
0,0,2,6,0,0,0,4,0,
0,0,0,0,0,4,0,0,0,
3,0,0,5,6,0,0,0,2,
5,6,0,0,1,0,0,3,9
}
int data3[]=
{
0,0,3,0,0,0,0,0,4,
9,0,0,0,0,3,0,5,0,
2,0,0,7,0,0,0,0,0,
0,8,0,0,1,0,0,0,6,
0,3,0,2,0,0,0,9,0,
4,0,0,0,0,0,0,1,0,
0,0,0,0,0,8,0,0,3,
0,6,0,9,0,0,0,0,8,
5,0,0,0,0,0,2,0,0
// 0,3,0,9,0,0,0,1,0,
// 0,8,0,0,0,0,0,7,0,
// 7,0,2,4,0,0,9,0,0,
// 0,7,0,0,1,0,0,4,0,
// 1,0,0,0,0,6,0,0,9,
// 0,6,0,0,0,0,0,3,0,
// 0,0,8,0,0,9,5,0,3,
// 0,1,0,0,0,0,0,9,0,
// 0,9,0,0,0,2,0,6,0
}
int blanks
cout<<"随机生成一个数独,输入空格数"
cin>>blanks
CSudoku s(blanks)
s.display()
cout<<"开始解数独:"<<endl
s.resolve()
cout<<"解数独:"<<endl
CSudoku t(data3)
t.display()
cout<<"开始解数独:"<<endl
t.resolve(1)
return 0
}