数独游戏报告
数 据 结 构 课 程 设 计
数独游戏 数独游戏
院 系:
班 级:
组 长:
组 员:
指导教师:
2010 年 12 月 29 日
数据结构课程
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
任务书
一、
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
目: 数独游戏
二、设计要求
(1)XXX(组长)、XXX(组员)和 XXX(组员)组成设计小组。
(2)小组成员分工协作完成,要求每个成员有自己相对独立的模块,同时要了解其他组员完成的内容。
(3)查阅相关资料,自学具体课题中涉及到的新知识。
(4)根据实现的功能,划分出合理的对象类,明确对象类间的关系。为每个对象类设计正确的属性和方法,为每个方法设计合理的方法体。
(5)编程简练,程序功能齐全,能正确运行。
(6)课题完成后提交课程设计报告,格式
规范
编程规范下载gsp规范下载钢格栅规范下载警徽规范下载建设厅规范下载
,内容详实。其主要内容包括:1-封皮、2-课程设计任务书,3-指导教师评语与成绩、4-目录、5-需求分析、6-概要设计、7-详细设计(含主要代码)、8-调试分析与测试结果、9-用户使用说明、10-附录或参考资料。报告用A4纸打印,中文字体为宋体,西文字体用Time New Roma,小四号字,行距采用“固定值”18磅,首行缩进2字符。
(7)课程设计报告内容的说明:需求分析-分析课题需要实现的功能以及要用到的知识点,分析课题涉及的对象间的关系;概要设计-根据实现的功能;详细设计-具体的功能的实现以及主要程序代码;调试分析与测试结果-用多组测试用例调试分析系统的正确性、完备性等各项性能指标,写出测试结果;用户使用说明-编写该系统的使用说明书;附录或参考资料-完整的程序代码以及查阅资料的参考文献。 三、课程设计工作量
由于是设计小组团结协作完成设计任务,一般每人的程序量在200行有效程序行左右,不得抄袭。
四、课程设计
工作计划
幼儿园家访工作计划关于小学学校工作计划班级工作计划中职财务部门工作计划下载关于学校后勤工作计划
2010年12月21日,指导教师讲课,学生根据题目准备资料;
2010年12月21日,2010年12月27日,设计小组进行总体
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
设计和任务分工;每人完成自己承担的程序模块并通过独立编译;
2010年12月28日,2010年12月29日,将各模块集成为一个完整的系统,并录入足够的数据进行调试运行;同时撰写报告。
2010年12月29日,验收;提交课程设计报告。
指导教师签章: 教研室主任签章
I
数据结构课程设计指导教师评语与成绩
指导教师评语:
课程设计表现成绩:
课程设计验收成绩:
课程设计报告成绩:
课程设计 总成绩:
指导教师签章
2010年 12 月 29 日
II
目 录
第1章 需求分析 .......................................................................................................... 1 1.1 性能需求........................................................................................................... 1 1.2 功能需求........................................................................................................... 1
第2章 概要设计 .......................................................................................................... 3 2.1功能模块设计 ...................................................................................................... 3
第3章 详细设计 .......................................................................................................... 4 3.1 保存游戏功能模块设计 ................................................................................... 4
3.1.1详细功能描述 ......................................................................................... 4
3.1.2设计思想 ................................................................................................. 4
3.1.3主要代码 ................................................................................................. 4
3.1.4程序流程图 ............................................................................................. 5 3.2更换另一局功能模块设计 .................................................................................. 6
3.2.1详细功能描述 ......................................................................................... 6
3.2.2设计思想 ................................................................................................. 6
3.2.3主要代码 ................................................................................................. 6
3.2.4程序流程图 ............................................................................................. 8 3.3提交验证功能模块设计 ...................................................................................... 9
3.3.1详细功能描述 ......................................................................................... 9
3.3.2设计思想 ................................................................................................. 9
3.3.3主要代码 ................................................................................................. 9
3.3.4程序流程图 ........................................................................................... 11 3.4查看答案功能模块设计 .................................................................................... 13
3.4.1详细功能描述 ....................................................................................... 13
3.4.2设计思想 ............................................................................................... 13
3.4.3主要代码 ............................................................................................... 13
3.4.4程序流程图 ........................................................................................... 14 3.5求解游戏答案函数功能模块设计 ..................................................................... 15
3.5.1详细功能描述 ....................................................................................... 15
3.5.2设计思想 ............................................................................................... 15
3.5.3主要代码 ............................................................................................... 15
3.5.4程序流程图 ........................................................................................... 17 3.6初始化函数功能模块设计 ................................................................................ 19
3.6.1详细功能描述 ....................................................................................... 19
3.6.2设计思想 ............................................................................................... 19
3.6.3主要代码 ............................................................................................... 19
I
3.6.4程序流程图 ........................................................................................... 21 3.7显示表情功能模块设计 .................................................................................... 22
3.7.1详细功能描述 ....................................................................................... 22
3.7.2设计思想 ............................................................................................... 22
3.7.3主要代码 ............................................................................................... 22
3.7.4程序流程图 ........................................................................................... 23 3.8显示时间功能模块设计 .................................................................................... 24
3.8.1详细功能描述 ....................................................................................... 24
3.8.2设计思想 ............................................................................................... 24
3.8.3主要代码 ............................................................................................... 24
3.8.4程序流程图 ........................................................................................... 25 3.9导入游戏功能模块设计 .................................................................................... 26
3.9.1详细功能描述 ....................................................................................... 26
3.9.2设计思想 ............................................................................................... 26
3.9.3主要代码 ............................................................................................... 26
3.9.4程序流程图 ........................................................................................... 27
第4章 调试分析与测试结果 ..................................................................................... 28 4.1 调试分析......................................................................................................... 28 4.2 测试结果......................................................................................................... 28
4.2.1程序开始界面 ....................................................................................... 28
4.2.2数独游戏界面 ....................................................................................... 29
4.2.3保存游戏界面 ....................................................................................... 29
4.2.4更换一局界面 ....................................................................................... 30
4.2.5提交验证界面 ....................................................................................... 30
4.2.6查看答案界面 ....................................................................................... 31
4.2.7储存后的数独文本文档 ........................................................................ 32
4.2.8显示答案的数独文本文档 .................................................................... 32
4.2.9显示表情界面 ....................................................................................... 33
4.2.10导入游戏界面 ..................................................................................... 34
第5章 游戏规则以及使用说明 ................................................................................. 35 5.1游戏规则 ........................................................................................................... 35 5.2使用说明 ........................................................................................................... 35
参考文献 ......................................................................................................................... 36
附 录 ......................................................................................................................... 37
II
第1章 需求分析
1.1 性能需求
程序开发环境:WIN-TC
1.2 功能需求
我们组研究的是数独游戏。
该游戏包括的功能:
1. 更换一局
2. 保存游戏
3. 导入游戏
4. 提交验证
5. 查看答案
6. 删除数字
7. 显示面部表情
8. 显示北京时间和已玩游戏的时间
涉及到的函数:
display_hanzi( ) 汉字显示函数
about( ) 成员信息函数
winhelp( ) 帮助窗口函数
youxikuangjia( ) 游戏框架函数
times( ) 显示北京时间和游戏时间的函数
message_face( ) 面部表情函数
CheckPalace( ) 检查小宫函数
CheckRow ( ) 检查列函数
CheckLine ( ) 检查行函数
AddCount ( ) 添加数函数
Pangduan ( ) 判断函数
chushihua( ) 初始化函数
right_wrong ( ) 判断对错函数
save_game ( ) 保存函数
load_game ( ) 导入上次保存的数独函数
game_answer ( ) 答案函数
1
程序涉及到的知道点:
? 回溯法与树的遍历
? 三元组顺序表示法
? for循环语句
?if???else语句
?while语句
?switch???case语句
2
第2章 概要设计
2.1功能模块设计
数独游戏
更保删显显导提查
换存除示示入交看
一游数面时游验答
局戏字部间戏证案
表
情
这个数独游戏的功能比较完善。使用主函数中的switch语句实现多分支选择结构,进而实现该数独游戏的各项功能。该系统能实现8项功能。设计本次实验所用到的知识点有:回溯法与树的遍历 ,三元组顺序表示法 ,for循环语句 ,if???else语句 , while语句,switch???case语句 等。
3
第3章 详细设计
3.1 保存游戏功能模块设计
3.1.1详细功能描述
该部分是用来保存游戏进度。
3.1.2设计思想
保存游戏的进度是通过创建两个文件,然后将游戏最初的状态和游戏最终的答案分别写入这两个文件来进行保存,这两个文件分别是SUDUGAME.TXT和SUCCESS.TXT。
该部分通过if???else语句、for循环语句和fopen语句实现其功能。
3.1.3主要代码
int save_game(int nowxy[9][9],int a) /*保存函数*/ {
FILE *fp;
int i,j;
char *p="保存成功";
if(a==2)
fp=fopen("success.txt","w");
else
fp=fopen("sudugame.txt","w");
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
fprintf(fp,"%d ",nowxy[i][j]);
fprintf(fp,"\n",NULL);
}
fprintf(fp,"\n",NULL);
fclose(fp);
message_face(4);
settextstyle(0,0,1);
display_hanzi(7,230,1,1,15,p,4);
return(0);
}
4
3.1.4程序流程图
开始
N 判断a是否等于2
Y
创建文件SUCCESS.TXT
创建文件SUDUGAME.TXT
将数据写入文件
5
3.2更换另一局功能模块设计
3.2.1详细功能描述
该部分是用来更换游戏进入另一局。
3.2.2设计思想
更换另一局游戏是同过调用随机产生0~9的随机数函数和初始化函数实现的。重新随
机产生新的数,然后分配到不同的位子上。
该部分通过if???else语句、for循环语句和数组实现其功能。
3.2.3主要代码
void chushihua(int (*nowxy)[9],int (*ys1)[9],int a) /*初始化函数*/
{
int k,r,r1,r2,x=4,y=4,x1,y1,x2,y2,i,j,rand_x[9],rand_y[9];
int
ys[9][9]={{1,8,5,4,7,9,2,3,6},{4,2,3,5,6,8,7,9,1},{9,6,7,2,3,1,5,8,4},{3,9,4,8,5,6,1,7,2},{6,
7,1,9,4,2,3,5,8},{8,5,2,7,1,3,6,4,9},{5,1,9,6,8,7,4,2,3},{7,3,8,1,2,4,9,6,5},{2,4,6,3,9,5,8,1,7
}}; /*样式举例*/
char *s=NULL; /*srand((unsigned)time(&t));*/
randomize();
setviewport(50,60,590,460,1); /*x:540 y:400*/
setcolor(1);/*数字的颜色 */
settextstyle(1,0,3);
qj=0; /*区间号*/
if(a==1)
{
rand0to9(rand_x);
rand0to9(rand_y);
for(i=0;i<9;i++)
for(j=0;j<9;j++)
*(*(ys1+i)+j)=*(*(ys+rand_x[i])+rand_y[j]);
for(i=0;i<9;i++)
for(j=0;j<9;j++)
*(*(nowxy+i)+j)=0;
for(k=0;k<3;k++)
{ for(j=0;j<3;j++)
{
r=((rand()%100)>80)?(random(2)+1):(random(3)+3);
for(i=0;i
5)&&(j>2&&j<6)||(j<3||j>5)&&(i>2&&i<6))?12:14);
bar(72+i*44,3+j*44,114+i*44,45+j*44);
if(*(*(nowxy+i)+j)!=0)
{
sprintf(s,"%d",nowxy[i][j]);
outtextxy(88+i*44,20+j*44,s); /*数字显示位置*/
qj++;
}
}
setfillstyle(1,10);
bar(73+x*44,4+y*44,73+40+x*44,4+40+y*44);
if(nowxy[x][y]!=0)
{
sprintf(s,"%d",nowxy[x][y]);
outtextxy(90+x*44,18+y*44,s);
}
first_time=time(NULL);
}
void rand0to9(int *a) /*这是随机产生0~9的随机数函数*/ {
int r,r1,i,j,k[6][3]={{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};
time_t t; /*randomize(); r=random(6);*/
srand((unsigned)time(&t)); /*add*/
r=rand()%6; /*add*/
for(i=0;i<3;i++)
{/*r1=random(6);*/
r1=rand()%6;
for(j=0;j<3;j++)
*(a+(k[r1][j]+i*3))=k[r][i]*3+j;
}
}
7
3.2.4程序流程图
开始
N 如果a= =1
Y
调用随机产生0~9的随机数函数
void rand0to9( )
i=1
N
i<9
Y
i++
调用setfillstyle(设置填充样式)函数
8
3.3提交验证功能模块设计
3.3.1详细功能描述
该部分是用来验证用户所写答案是否正确。
3.3.2设计思想
提交验证功能是通过先取出用户所写的答案,然后调用CheckPalace( ) 、CheckLine( ) 、CheckRow( )分别对其进行检查小宫、检查行、检查列的操作,然后再进行判断对错。
3.3.3主要代码
int GetListElem (ElemType *e, int i) /*取得元素 */ {
if (i < 0)
{
return 0;
}
*e = list[i];
return 1;
}
void AddListElem (ElemType e) /*把数独原本为空的坐标存入表中*/ {
len++;
list[len] = e;
}
int CheckPalace (int arr[][9], int line, int row, int count) /*检查小宫*/ {
int i, j;
int a, b;
i = line / 3 * 3;
j = row / 3 * 3; /*i,j为一个小宫的起始横纵下标 */
for (a = i; a < i + 3; ++a)
{
for (b = j; b < j + 3; ++b)
{
if (arr[a][b] == count)
{
return 1;
}
9
}
}
return 0;
}
int CheckRow (int arr[][9], int row, int count) /*检查列*/ {
int i;
for (i = 0; i < 9; ++i)
{
if (arr[i][row] == count)
{
return 1;
}
}
return 0;
}
int CheckLine (int arr[][9], int line, int count) /*检查行*/ {
int j;
for (j = 0; j < 9; ++j)
{
if (arr[line][j] == count)
{
return 1;
}
}
return 0;
}
int right_wrong(int nowxy[9][9],int ys[9][9]) /*判断对错函数*/ {
int i,j,k=4;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(nowxy[i][j]!=ys[i][j])
{
k=3;
break;
}
}
if(k==3)break;
}
for(i=0;i<9;i++)
for(j=0;j<9;j++)
if(pangduan(i,j,nowxy[i][j],nowxy)!=-1)
return(k);
10
save_game(nowxy,2);
qj=0;
return(k+1); }
3.3.4程序流程图
开始
i=1
N
i<9
Y
i++
i=0
N
i<9
Y
i++
11
调用save_game( 保存游戏 )函数
return(k+1)
12
3.4查看答案功能模块设计
3.4.1详细功能描述
该部分是用来查看游戏最终答案的。
3.4.2设计思想
查看答案功能是通过创建一个文件,然后将游戏最终的答案写入这个文件来进行保存,这个文件是ANSWER.TXT。
该部分通过if???else语句、for循环语句和fopen语句实现其功能。
3.4.3主要代码
void game_answer(int (*nowxy)[9]) /*答案函数*/
{
FILE *fp;
int i,j;
char *p=NULL;
if((fp=fopen("answer.txt","r"))!=NULL)
{
for(i=0;i<9;i++)
for(j=0;j<9;j++)
fscanf(fp,"%d",*(nowxy+i)+j);
fclose(fp);
p="再接再励";
message_face(1);
settextstyle(0,0,1);
display_hanzi(7,230,1,1,15,p,4);
}
else
{ message_face(2);
settextstyle(0,0,1);
p="没有记录";
display_hanzi(7,220,1,1,15,p,4);
p="请先保存";
display_hanzi(7,240,1,1,15,p,4);
}
}
13
3.4.4程序流程图
开始
FILE *fp;
N 创建文件
Y message_face(2)
i=0
N i<9
Y
往文件中写入数据
i++
关闭文件fclose(fp)
14
3.5求解游戏答案函数功能模块设计
3.5.1详细功能描述
该部分是用来求解出游戏的答案。
3.5.2设计思想
求解函数的是通过使用回溯法与树的遍历实现的。
该部分通过if???else语句、for循环语句、数组和调用回溯法实现其功能。
3.5.3主要代码
int qiujie (void) /*求解函数*/
{
int i, j;
ElemType e;
int arr[9][9];
/*输入一个数独谱,填0到9,0表示空位,然后把空位坐标保存起来 */
FILE* fp = fopen( "SUDUGAME.txt" , "r" ) ;
for (i = 0; i < 9; ++i)
{
for (j = 0; j < 9; ++j)
{
fscanf(fp,"%d",*(arr+i)+j);
if ( !arr[i][j] )
{
e.x = i;
e.y = j;
len++;
list[len] = e;
}
}
}
fclose(fp);
if ( AddCount (arr) )
{
FILE* fpw = fopen( "answer.txt" , "w" ) ;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
fprintf(fpw,"%d ",arr[i][j]);
fprintf(fpw,"\n",NULL);
}
fclose(fpw);
15
}
return 0;
}
int AddCount (int arr[][9]) /*回溯法*/
{/*添加数*/
int i, j, k;
int count;
ElemType e;
k = -1;
for (i = 0; i < 9; ++i)
{ for (j = 0; j < 9; )
{ count = 1;
if (!arr[i][j])
{ k++;
while ( ( CheckLine (arr, i, count) || CheckRow (arr, j, count)
|| CheckPalace (arr, i, j, count) ) && count <= 9 )
{ count ++;}
if (count > 9)
{ do
{ arr[i][j] = 0;
if ( GetListElem (&e, k - 1) )
{
k--;
i = e.x;
j = e.y;
}
else
{
return 0;
}
count = arr[i][j] + 1;
while ( ( CheckLine (arr, i, count) || CheckRow (arr, j, count)
|| CheckPalace (arr, i, j, count) ) && count <= 9 )
{
count++;
}
}while (count > 9);
arr[i][j] = count;
}
else
{ arr[i][j] = count;
j++;
}
}
else
16
{ j++;
}
}
}
return 1;
}
3.5.4程序流程图
开始
N i<9
Y
j=0
N j<9
j++
i++
17
fclose(fp)
调用AddCount( )函数 (回溯法)
18
3.6初始化函数功能模块设计
3.6.1详细功能描述
该部分是用来初始化游戏的。
3.6.2设计思想
初始化函数是通过调用随机产生0~9的随机数函数,随机的重新产生新的数,然后放入不同的位置。
3.6.3主要代码
void chushihua(int (*nowxy)[9],int (*ys1)[9],int a) /*初始化函数*/ {
int k,r,r1,r2,x=4,y=4,x1,y1,x2,y2,i,j,rand_x[9],rand_y[9];
int
ys[9][9]={{1,8,5,4,7,9,2,3,6},{4,2,3,5,6,8,7,9,1},{9,6,7,2,3,1,5,8,4},{3,9,4,8,5,6,1,7,2},{6,
7,1,9,4,2,3,5,8},{8,5,2,7,1,3,6,4,9},{5,1,9,6,8,7,4,2,3},{7,3,8,1,2,4,9,6,5},{2,4,6,3,9,5,8,1,7
}}; /*样式举例*/
char *s=NULL; /*srand((unsigned)time(&t));*/
randomize();
setviewport(50,60,590,460,1); /*x:540 y:400*/
setcolor(1);/*数字的颜色 */
settextstyle(1,0,3);
qj=0; /*区间号*/
if(a==1)
{
rand0to9(rand_x);
rand0to9(rand_y);
for(i=0;i<9;i++)
for(j=0;j<9;j++)
*(*(ys1+i)+j)=*(*(ys+rand_x[i])+rand_y[j]);
for(i=0;i<9;i++)
for(j=0;j<9;j++)
*(*(nowxy+i)+j)=0;
for(k=0;k<3;k++)
{
for(j=0;j<3;j++)
{
19
r=((rand()%100)>80)?(random(2)+1):(random(3)+3);
for(i=0;i5)&&(j>2&&j<6)||(j<3||j>5)&&(i>2&&i<6))?12:14);
bar(72+i*44,3+j*44,114+i*44,45+j*44);
if(*(*(nowxy+i)+j)!=0)
{
sprintf(s,"%d",nowxy[i][j]);
outtextxy(88+i*44,20+j*44,s); /*数字显示位置*/
qj++;
}
}
setfillstyle(1,10);
bar(73+x*44,4+y*44,73+40+x*44,4+40+y*44);
if(nowxy[x][y]!=0)
{
sprintf(s,"%d",nowxy[x][y]);
outtextxy(90+x*44,18+y*44,s);
}
first_time=time(NULL);
}
20
3.6.4程序流程图
开始
N 如果a= =1
Y
调用随机产生0~9的随机数函数
void rand0to9( )
i=1
N
i<9
Y
i++
调用setfillstyle(设置填充样式)函数
21
3.7显示表情功能模块设计
3.7.1详细功能描述
该部分是用来显示表情。
3.7.2设计思想
通过检测游戏者成功与否,从而显示不同的表情。
该部分通过switch语句实现其功能。
3.7.3主要代码
void message_face(int tag) /*面部表情函数*/ {
setviewport(523,61,600,459,1); /* x:77 y:598*/
setfillstyle(1,11);
bar(3,99,72,300);
setcolor(2);
setlinestyle(0,0,3);
circle(38,130,30);
setlinestyle(0,0,3);
circle(38,130,3);
setcolor(0);
setlinestyle(0,0,3);
circle(28,124,2); /*left_eye*/
setlinestyle(0,0,3);
circle(49,124,2); /*right_eye*/
setcolor(3);
setlinestyle(0,0,3);
switch(tag)
{
case 1:
line(28,145,49,145);
line(18,120,33,120); /*正常*/
line(43,120,58,120);
break;
case 2:
setcolor(4);
line(28,145,49,145);
line(18,128,28,116); /* input wrong*/
line(44,116,60,126);
break;
case 3:
line(18,128,28,116); /* faill */
line(44,116,60,126);
22
setcolor(4);
ellipse(38,145,0,180,10,7);
sound(700);
delay(1000000);
nosound();
break;
case 4:
case 5:
line(18,120,33,120); /* 成功 */
line(43,120,58,120);
ellipse(38,145,180,360,10,7);
sound(800);
delay(100000);
nosound();
break;
}
}
3.7.4程序流程图
开始
N 判断成功与否
Y
显示笑脸
显示哭脸
23
3.8显示时间功能模块设计
3.8.1详细功能描述
该部分是用来显示北京时间和游戏时间。
3.8.2设计思想
通过显示游戏时间和北京时间,让游戏者更好地把握游戏进度。
该部分通过指针实现其功能。
3.8.3主要代码
char *gametime(time_t first_time) /*游戏时间函数*/
{
time_t second_time;
char *s=NULL;
second_time=difftime(time(NULL),first_time);
sprintf(s,"%ld:%ld:%ld",second_time/3600,(second_time-second_time/3600)/60,second_ti
me%60);
return(s);
}
void times() /*这是北京时间和游戏时间的函数*/ {
struct time t;
char *s="北京时间";
gettime(&t);
setviewport(523,61,600,459,1); /*x:77 y:598*/
setfillstyle(1,11);
bar(4,65,70,75);
bar(4,380,70,395);
display_hanzi(8,40,1,1,15,s,8);
s=NULL;
sprintf(s,"%2d:%02d:%02d",t.ti_hour,t.ti_min,t.ti_sec);
settextstyle(0,0,1); /*文本样式函数:文本字体,显示方向,字符大小*/
setcolor(random(15)); /*时间颜色变换函数利用随机数产生函数*/
outtextxy(6,65,s);
s="游戏时间";
display_hanzi(8,355,1,1,15,s,8);
24
settextstyle(0,0,1);
setcolor(random(15));
outtextxy(16,380,gametime(first_time));
}
3.8.4程序流程图
开始
N 如果a, 最后在查阅了数据结构(C语言版)后,终于解决了问题。
4.2 测试结果
4.2.1程序开始界面
运行程序后,就会出现下图:
(图 一)
28
4.2.2数独游戏界面
按任意键后,就会出现下图:
(图二) 4.2.3保存游戏界面
根据提示,按S键,就会出现下图:
(图三)
29
4.2.4更换一局界面
根据提示,按R键,就会出现下图:
(图四) 4.2.5提交验证界面
根据提示,按C键,如果答案正确就会出现下图:
(图五)
30
如果答案不正确就会出现下图:
(图六) 4.2.6查看答案界面
根据提示,按A键,就会出现下图:
(图七)
31
4.2.7储存后的数独文本文档
(图八)
4.2.8显示答案的数独文本文档
(图九)
32
4.2.9显示表情界面
有哭笑两种表情:
(图十)
(图十一)
33
4.2.10导入游戏界面
根据提示,按L键,导入游戏成功后,就会出现下图:
(图十二)
34
第5章 游戏规则以及使用说明
5.1游戏规则
数独盘面是个九宫,每一宫又分为九个小格,一共有81个小格,在剩余的空格上填入1~9的数字,使得1~9每个数字在每一行、每一列和每一个宫格中都只出现一次。
5.2使用说明
该系统是数独游戏。运行程序时,首先进入操作界面,然后按任意键即可进入游戏界面,然后按照提示进行操作就行了:按R更换另一局;按S保存游戏;按L导入游戏;按C提交验证;按A查看答案;按Delete或Backspace删除数字;按ESC退出游戏界面。
35
参考文献 【1】严蔚敏、吴伟民 编著的数据结构(C语言版)
清华大学出版社2007年
36
附 录 #include #include #include #include #include #include #include
#include #include
#include #define ESC 0x011b #define ENTER 0x1c0d #define HOME 0x4700 #define END 0x4f00 #define BACKSPACE 0xe08 #define DELETE 0x5300 #define UP 0x4800 #define DOWN 0x5000 #define LEFT 0x4b00 #define RIGHT 0x4d00 #define TAB 0xf09 #define N1 0x231 #define N2 0x332 #define N3 0x433 #define N4 0x534 #define N5 0x635 #define N6 0x736 #define N7 0x837 #define N8 0x938 #define N9 0xa39 #define R 0x1372 #define C 0x2e63 #define S 0x1f73 #define L 0x266c #define A 0x1e61 #define ERROR 0
#define OVERFLOW -2
typedef struct
{
int i, j; /*该非零元的行下标和列下标 */
int e; /* 该非零元的值 */
}Triple;
typedef struct /* 三元组类型 */
{
Triple data[82]; /* 非零元三元组表,data[0]未用*/
37
int mu,nu,tu; /*矩阵的行数列数和非零元个数*/
}TSMatrix; /* 稀疏矩阵类型 */
TSMatrix M;
typedef struct
{
int x; /*存放数组的横坐标*/
int y; /*存入数组的纵坐标 */
}ElemType;
ElemType list[81]; /*定义一个表空间*/
int len = -1; /*len记录表的大小 */
int qj=0;time_t first_time;
void display_hanzi(int x,int y,int height,int ampl,int blank,char *s,int color)
/* 汉字显示函数*/
{
FILE *fp;
char buffer[32];
register m,n,i,j,k;
unsigned char qh,wh;
unsigned long offset;
if ((fp=fopen("hzk16","rb"))==NULL) /*文件必须在同文件夹下*/
{
printf("Can't open hzk16,Please add it");
getch();
closegraph();
exit(0);
}
while(*s)
{
qh=*(s)-0xa0;
wh=*(s+1)-0xa0;
offset=(94*(qh-1)+(wh-1))*32L;
fseek(fp,offset,SEEK_SET);
fread(buffer,32,1,fp);
for(i=0;i<16;i++)
for(n=0;n>(7-k))&0x1)!=NULL)
putpixel(x+8*j*ampl+k*ampl+m,y+i*height+n,color);
s+=2;
x+=blank;
}
fclose(fp);
38
}
void about() /*关于我们开发组的信息函数*/ {
char *hanzi="欢迎使用本组开发的数独游戏";
setviewport(50,60,590,460,1);/* x:540 y:400*/
display_hanzi(74,51,2,2,30,hanzi,3);
display_hanzi(75,50,2,2,30,hanzi,1);
hanzi="成员:季斌卢俊董光磊";
display_hanzi(110,130,2,2,30,hanzi,14);
hanzi="北华大学计算机学院";
display_hanzi(95,220,2,2,40,hanzi,3);
display_hanzi(96,219,2,2,40,hanzi,4);
hanzi="计算机二班";
display_hanzi(150,300,2,2,50,hanzi,4);
hanzi="请按任意键开始游戏";
display_hanzi(80,385,1,1,20,hanzi,3);
getch();
}
void winhelp() /*帮助窗口函数*/
{
char *p="-Help-",*s[17]={{"换另一局"},{"保存游戏"},{"导入游戏"},{"提交验证"},{"查看答案"},{"删除数字"},{"[R] key"},{"[S] key"},{"[L] key"},{"[C]
key"},{"[A]key"},{"[Delete]"},{"[Back..]"},{"请注意:"},{"必须先保"},{"存,才能"},{"看到答案"}};
int i;
setviewport(40,61,117,459,1); /* x:77 y:598*/
setfillstyle(1,11);
setcolor(4);
bar(1,1,76,398);
setlinestyle(0,0,3);
rectangle(1,3,74,398);
settextstyle(1,0,1);
setcolor(13);
outtextxy(13,15,p);
setcolor(2);
settextstyle(0,0,1);
p="移动光标";
display_hanzi(5,40,1,1,15,p,4);
setcolor(2);
line(10,60,10,75); /*箭头图标?*/
line(5,65,10,60);
line(10,60,15,65);
line(25,60,25,75); /*箭头图标?*/
line(20,70,25,75);
line(25,75,30,70);
line(35,68,50,68); /*箭头图标?*/
39
line(35,68,40,63);
line(35,68,40,73);
line(55,68,70,68); /*箭头图标?*/
line(65,63,70,68);
line(65,73,70,68);
for(i=0;i<=5;i++) /*利用循环将汉字和按键提示一次输出*/
{
p=*(s+i);
display_hanzi(5,86+i*30,1,1,15,p,4);
setcolor(2);
outtextxy(5,105+i*30,*(s+i+6));
}
outtextxy(5,270,*(s+12));
p=*(s+13);
display_hanzi(5,280,1,1,15,p,5);
p=*(s+14);
display_hanzi(5,300,1,1,15,p,5);
p=*(s+15);
display_hanzi(5,320,1,1,15,p,5);
p=*(s+16);
display_hanzi(5,340,1,1,15,p,5); }
void youxikuangjia() /*游戏框架函数*/
{
int i,j;
setviewport(50,60,590,460,1); /*x:540 y:400*/
setfillstyle(1,1); /*设置填充样式函数 */
bar(70,1,470,400); /* 画矩形条函数 */
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
setfillstyle(1,((i<3||i>5)&&(j>2&&j<6)||(j<3||j>5)&&(i>2&&i<6))?12:14);
bar(72+i*44,3+j*44,114+i*44,45+j*44);
}
}
setcolor(4);
setlinestyle(0,0,3); /* 设置线型函数 */
rectangle(71,2,468,398);
}
char *gametime(time_t first_time) /*游戏时间函数*/
{
time_t second_time;
char *s=NULL;
second_time=difftime(time(NULL),first_time);
sprintf(s,"%ld:%ld:%ld",second_time/3600,(second_time-
40
second_time/3600)/60,second_time%60);
return(s);
}
void times() /*这是北京时间和游戏时间的函数*/ {
struct time t;
char *s="北京时间";
gettime(&t);
setviewport(523,61,600,459,1); /*x:77 y:598*/
setfillstyle(1,11);
bar(4,65,70,75);
bar(4,380,70,395);
display_hanzi(8,40,1,1,15,s,8);
s=NULL;
sprintf(s,"%2d:%02d:%02d",t.ti_hour,t.ti_min,t.ti_sec);
settextstyle(0,0,1); /*文本样式函数:文本字体,显示方向,字符大小
*/
setcolor(random(15)); /*时间颜色变换函数利用随机数产生函数*/
outtextxy(6,65,s);
s="游戏时间";
display_hanzi(8,355,1,1,15,s,8);
settextstyle(0,0,1);
setcolor(random(15));
outtextxy(16,380,gametime(first_time));
}
void message_face(int tag) /*面部表情函数*/
{
setviewport(523,61,600,459,1); /* x:77 y:598*/
setfillstyle(1,11);
bar(3,99,72,300);
setcolor(2);
setlinestyle(0,0,3);
circle(38,130,30);
setlinestyle(0,0,3);
circle(38,130,3);
setcolor(0);
setlinestyle(0,0,3);
circle(28,124,2); /*left_eye*/
setlinestyle(0,0,3);
circle(49,124,2); /*right_eye*/
setcolor(3);
setlinestyle(0,0,3);
switch(tag)
41
{
case 1:
line(28,145,49,145);
line(18,120,33,120); /*正常*/
line(43,120,58,120);
break;
case 2:
setcolor(4);
line(28,145,49,145);
line(18,128,28,116); /* input wrong*/
line(44,116,60,126);
break;
case 3:
line(18,128,28,116); /* faill */
line(44,116,60,126);
setcolor(4);
ellipse(38,145,0,180,10,7);
sound(700);
delay(1000000);
nosound();
break;
case 4:
case 5:
line(18,120,33,120); /* 成功 */
line(43,120,58,120);
ellipse(38,145,180,360,10,7);
sound(800);
delay(100000);
nosound();
break;
}
}
/*------------------------------------------------------------------*/
int GetListElem (ElemType *e, int i) {/*取得元素 */
if (i < 0)
{
return 0;
}
*e = list[i];
return 1;
}
void AddListElem (ElemType e) {/*把数独原本为空的坐标存入表中 */
len++;
list[len] = e;
}
42
int CheckPalace (int arr[][9], int line, int row, int count)
{/*检查小宫 */
int i, j;
int a, b;
i = line / 3 * 3;
j = row / 3 * 3; /*i,j为一个小宫的起始横纵下标 */
for (a = i; a < i + 3; ++a)
{
for (b = j; b < j + 3; ++b)
{
if (arr[a][b] == count)
{
return 1;
}
}
}
return 0;
}
int CheckRow (int arr[][9], int row, int count)
{/*检查列*/
int i;
for (i = 0; i < 9; ++i)
{
if (arr[i][row] == count)
{
return 1;
}
}
return 0;
}
int CheckLine (int arr[][9], int line, int count)
{/*检查行 */
int j;
for (j = 0; j < 9; ++j)
{
if (arr[line][j] == count)
{
return 1;
}
}
return 0;
}
int CreateMatrix(TSMatrix M,int arr[][9])
{
int i,j,e,k=1;
43
M.mu=9;M.nu=9;
for (i=1;i<=M.mu;i++)
{
for (j=1;j<=M.nu;j++)
{
if (arr[i][j]!=0)
{
M.data[k].i=i;
M.data[k].j=j;
M.data[k].e=arr[i][j];
k++;
}
}
}
M.tu=k-1;
return 1;
}
int AddCount (int arr[][9]) {/*添加数*/
int i, j, k=-1;
int count;
ElemType e;
for (i = 0; i < 9; ++i)
{
for (j = 0; j < 9; )
{
count = 1;
if (!arr[i][j])
{
k++;
while ( ( CheckLine (arr, i, count) || CheckRow (arr, j, count)
|| CheckPalace (arr, i, j, count) ) && count <= 9 )
{
count ++;
}
if (count > 9)
{
do
{
arr[i][j] = 0;
if ( GetListElem (&e, k - 1) )
{
k--;
i = e.x;
j = e.y;
}
else
{
44
return 0;
}
count = arr[i][j] + 1;
while ( ( CheckLine (arr, i, count) || CheckRow (arr, j,
count)
|| CheckPalace (arr, i, j, count) ) && count <= 9 )
{
count++;
}
}while (count > 9);
arr[i][j] = count;
}
else
{
arr[i][j] = count;
j++;
}
}
else
{
j++;
}
}
}
return 1;
}
int qiujie (void)
{
int i, j;
ElemType e;
int arr[9][9];
/*输入一个数独谱,填0到9,0表示空位,然后把空位坐标保存起来 */
FILE* fp = fopen( "sudugame.txt" , "r" ) ;
for (i = 0; i < 9; ++i)
{
for (j = 0; j < 9; ++j)
{
fscanf(fp,"%d",*(arr+i)+j);
if ( !arr[i][j] )
{
e.x = i;
e.y = j;
len++;
list[len] = e;
}
}
}
fclose(fp);
45
if ( AddCount (arr) )
{
FILE* fpw = fopen( "answer.txt" , "w" ) ;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
fprintf(fpw,"%d ",arr[i][j]);
fprintf(fpw,"\n",NULL);
}
fclose(fpw);
}
return 0;
}
/*------------------------------------------------------------------*/
void rand0to9(int *a) /*这是随机产生0~9的随机数函数*/
{
int r,r1,i,j,k[6][3]={{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};
time_t t; /*randomize(); r=random(6);*/
srand((unsigned)time(&t)); /*add*/
r=rand()%6; /*add*/
for(i=0;i<3;i++)
{/*r1=random(6);*/
r1=rand()%6;
for(j=0;j<3;j++)
*(a+(k[r1][j]+i*3))=k[r][i]*3+j;
}
}
int pangduan(int x,int y,int value,int nowxy[9][9]) /*判断函数*/
{
int i,j;
for(i=(x/3)*3;i<(x/3)*3+3;i++)
for(j=(y/3)*3;j<(y/3)*3+3;j++)
if((i!=x||j!=y)&&nowxy[i][j]==value)
return(i*10+j);
for(i=0;i<9;i++)
{
if(y!=i&&nowxy[x][i]==value)return(x*10+i);
if(x!=i&&nowxy[i][y]==value)return(i*10+y);
}
return(-1);
}
void chushihua(int (*nowxy)[9],int (*ys1)[9],int a) /*初始化函数*/
{
int k,r,r1,r2,x=4,y=4,x1,y1,x2,y2,i,j,rand_x[9],rand_y[9];
int ys[9][9]={{1,8,5,4,7,9,2,3,6},{4,2,3,5,6,8,7,9,1},{9,6,7,2,3,1,5,8,4},
46
{3,9,4,8,5,6,1,7,2},{6,7,1,9,4,2,3,5,8},{8,5,2,7,1,3,6,4,9},{5,1,9,6,8,7,4,2,3},
{7,3,8,1,2,4,9,6,5},{2,4,6,3,9,5,8,1,7}}; /*样式举例*/
char *s=NULL; /*srand((unsigned)time(&t));*/
randomize();
setviewport(50,60,590,460,1); /*x:540 y:400*/
setcolor(1);/*数字的颜色 */
settextstyle(1,0,3);
qj=0; /*区间号*/
if(a==1)
{
rand0to9(rand_x);
rand0to9(rand_y);
for(i=0;i<9;i++)
for(j=0;j<9;j++)
*(*(ys1+i)+j)=*(*(ys+rand_x[i])+rand_y[j]);
for(i=0;i<9;i++)
for(j=0;j<9;j++)
*(*(nowxy+i)+j)=0;
for(k=0;k<3;k++)
{ for(j=0;j<3;j++)
{
r=((rand()%100)>80)?(random(2)+1):(random(3)+3);
for(i=0;i5)&&(j>2&&j<6)||(j<3||j>5)&&(i>2&&i<6))?12:14);
bar(72+i*44,3+j*44,114+i*44,45+j*44);
if(*(*(nowxy+i)+j)!=0)
{
sprintf(s,"%d",nowxy[i][j]);
outtextxy(88+i*44,20+j*44,s); /*数字显示位置*/
qj++;
}
}
47
setfillstyle(1,10);
bar(73+x*44,4+y*44,73+40+x*44,4+40+y*44);
if(nowxy[x][y]!=0)
{
sprintf(s,"%d",nowxy[x][y]);
outtextxy(90+x*44,18+y*44,s);
}
first_time=time(NULL);
}
int right_wrong(int nowxy[9][9],int ys[9][9]) /* return: right=4 or 5,wrong=3*/ /*
判断对错函数*/
{
int i,j,k=4;
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
if(nowxy[i][j]!=ys[i][j])
{
k=3;
break;
}
}
if(k==3)break;
}
for(i=0;i<9;i++)
for(j=0;j<9;j++)
if(pangduan(i,j,nowxy[i][j],nowxy)!=-1)
return(k);
save_game(nowxy,2);
qj=0;
return(k+1);
}
int save_game(int nowxy[9][9],int a) /*保存函数*/ {
FILE *fp;
int i,j;
char *p="保存成功";
if(a==2)
fp=fopen("success.txt","w");
else
fp=fopen("sudugame.txt","w");
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
fprintf(fp,"%d ",nowxy[i][j]);
fprintf(fp,"\n",NULL);
48
}
fprintf(fp,"\n",NULL);
fclose(fp);
message_face(4);
settextstyle(0,0,1);
display_hanzi(7,230,1,1,15,p,4);
return(0);
}
void load_game(int (*nowxy)[9]) /*导入上次保存的数独函数*/
{
FILE *fp;
int i,j;
char *p=NULL;
if((fp=fopen("sudugame.txt","r"))!=NULL)
{
for(i=0;i<9;i++)
for(j=0;j<9;j++)
fscanf(fp,"%d",*(nowxy+i)+j);
fclose(fp);
p="导入成功";
message_face(1);
settextstyle(0,0,1);
display_hanzi(7,230,1,1,15,p,4);
}
else
{
message_face(2);
settextstyle(0,0,1);
p="没有记录";
display_hanzi(7,220,1,1,15,p,4);
p="请先保存";
display_hanzi(7,240,1,1,15,p,4);
}
}
void game_answer(int (*nowxy)[9]) {
FILE *fp;
int i,j;
char *p=NULL;
if((fp=fopen("answer.txt","r"))!=NULL)
{
for(i=0;i<9;i++)
for(j=0;j<9;j++)
fscanf(fp,"%d",*(nowxy+i)+j);
fclose(fp);
p="再接再励";
49
message_face(1);
settextstyle(0,0,1);
display_hanzi(7,230,1,1,15,p,4);
}
else
{
message_face(2);
settextstyle(0,0,1);
p="没有记录";
display_hanzi(7,220,1,1,15,p,4);
p="请先保存";
display_hanzi(7,240,1,1,15,p,4);
}
}
void main()
{
int m_tag=1,i,k=0,gdirver,pang,gmode,key,no=0,nowxy[9][9]={0},ys[9]
[9],x=4,y=4,old_x=4,old_y=4;
char *s=NULL, *hanzi="数独游戏";
detectgraph(&gdirver,&gmode); /*registerbgidriver(EGAVGA_driver);*/
initgraph(&gdirver,&gmode,"");
setbkcolor(9); /*游戏背景颜色*/
setviewport(1,21,639,60,1); /* x:638 y:39*/
setfillstyle(1,1);
bar(119,1,519,40);
display_hanzi(245,5,2,2,40,hanzi,7);
display_hanzi(244,6,2,2,40,hanzi,8);
s="Message";
setviewport(523,61,600,459,1); /* x:77 y:598*/
setfillstyle(1,11);
setcolor(4);
bar(1,1,76,398);
setlinestyle(0,0,3);
rectangle(1,3,74,398);
settextstyle(1,0,1);
setcolor(13);
outtextxy(10,15,s);
winhelp(); /*调用窗口帮助函数*/
message_face(1); /*调用面部表情函数*/
about(); /*调用关于我们函数*/
youxikuangjia(); /*调用游戏框架函数*/
chushihua(nowxy,ys,1); /*调用初始化函数*/
while(1)
{
setviewport(50,60,590,460,1);/* x:540 y:400*/
setcolor(1); /*光标移动过后数字的颜色*/
settextstyle(1,0,3);
50
if(nowxy[x][y]==0&&no!=0)
{
pang=pangduan(x,y,no,nowxy);
if(pang>=0)
{
for(i=0;i<3;i++)
{
message_face(2);
setviewport(50,60,590,460,1);/* x:540 y:400*/
setcolor(2);
setlinestyle(0,0,3);
rectangle(74+pang/10*44,5+(pang%10)*44,112+pang/10*44,43+(pang%10)*44);
sound(700);delay(100000);
setcolor(((pang/10<3||pang/10>5)&&((pang%10)>2&&(pang%10)<6)||
((pang%10)<3||(pang%10)>5)&&(pang/10>2&&pang/10<6))?12:14);
rectangle(74+pang/10*44,5+(pang%10)*44,112+pang/10*44,43+(pang%10)*44);
nosound();
delay(10000);
}
message_face(1);
}
else
{
s=NULL;
nowxy[x][y]=no;
sprintf(s,"%d",nowxy[x][y]);
outtextxy(88+x*44,20+y*44,s);
qj++;
}
}
if(qj==81)
{
m_tag=0;
message_face(right_wrong(nowxy,ys));
}
no=0;
if(x!=old_x||y!=old_y)
{
setfillstyle(1,((old_x<3||old_x>5)&&(old_y>2&&old_y<6)||
(old_y<3||old_y>5)&&(old_x>2&&old_x<6))?12:14);
bar(73+old_x*44,4+old_y*44,113+old_x*44,44+old_y*44);
sprintf(s,"%d",nowxy[old_x][old_y]);
if(nowxy[old_x][old_y]!=0)
outtextxy(88+old_x*44,20+old_y*44,s); /*光标移动后的数字显示位置*/
setfillstyle(1,10);
51
bar(73+x*44,4+y*44,113+x*44,44+y*44);
sprintf(s,"%d",nowxy[x][y]);
if(nowxy[x][y]!=0)
outtextxy(90+x*44,18+y*44,s);
old_x=x;
old_y=y;
}
if(bioskey(1)!=0)
{
if(!m_tag)
{
message_face(1);
m_tag=1;
}
key=bioskey(0);
if(key==ESC)
break;
switch(key) /*判断按键情况*/
{
case ENTER:
break;
case UP:
y--;if(y==-1)y=8;
break;
case DOWN:
y++;if(y==9)y=0;
break;
case LEFT:
x--;if(x==-1)x=8;
break;
case RIGHT:
x++;if(x==9)x=0;
break;
case DELETE:
case BACKSPACE:
if(nowxy[x][y]!=0)
{
nowxy[x][y]=0;
setfillstyle(1,10);
bar(73+x*44,4+y*44,113+x*44,44+y*44);
qj--;
}
break;
case N1: no=1;
break;
case N2: no=2;
break;
case N3: no=3;
break;
case N4: no=4;
52
break;
case N5: no=5;
break;
case N6: no=6;
break;
case N7: no=7;
break;
case N8: no=8;
break;
case N9: no=9;
break;
case R:
x=4;y=4;old_x=4;old_y=4;
chushihua(nowxy,ys,1);
break;
case C:
m_tag=0;
message_face(right_wrong(nowxy,ys));
break;
case S:
m_tag=0;
save_game(nowxy,1);
qiujie();
break;
case L:
m_tag=0;
load_game(nowxy);
x=4;y=4;old_x=4;old_y=4;
chushihua(nowxy,NULL,2);
break;
case A:
m_tag=0;
game_answer(nowxy);
x=4;y=4;old_x=4;old_y=4;
chushihua(nowxy,NULL,2);
break;
}
}
k++;
if(k>10000)
{
times();
k=0;
}
}
closegraph();
}
53