1、 C语言的三维数组的应用 姓 名: 杜晓伟 学 号: 105030540037 班 级: 103511 指导老师: 张 印 2012年05月29日 c语言程序设计课程期末论文 I 目 录1.概述:11.1俄罗斯方块的题目的描述11.2俄罗斯方块的设计思想11.3开发环境:21.3.1硬件环境21.3.2软件环境22.总体设计22.1开发与设计的总体思想22.2模块设计32.2.1主要模块:32.2.2 按键及功能对照表 :32.2.3主要函数名称以及功能表:32.3模块设计小结43.实验结果分析及程序代码44、结果分析:23 c语言程序设计课程期末论文 32【摘要】:利用程序语言C语言编写一个
2、俄罗斯方块游戏,加深对程序入口、出口的理解和编制,掌握数组的运用,以及对知识的拓展。【关键字】:C语言; 俄罗斯方块,;三维数组1.概述:1.1俄罗斯方块的题目的描述运行游戏时.界面随机的产生不同形状的方块,游戏者通过自己的操作使方块进行合理的堆积.如果每层达到饱和状态的时候会自动消除.然后游戏有规则的进行加分.分数达到一定的阶段.游戏的级别也会越来越高.然后方块下降的速度也会随之慢慢加快.以迎合游戏者的挑战,达到最加有趣的游戏!1.2俄罗斯方块的设计思想游戏是用来给大家娱乐的,所以要能在使用的过程中给大家带来快乐,消除大家的疲劳,所以我们在游戏中添加了漂亮的场景和动听的音乐,设置了过关升级的
3、功能,激发大家的娱乐激情。 从游戏的基本玩法出发,主要就是俄罗斯方块的形状和旋转,利用三维数组每个方块含有各自的状态,变换只需改变到下一个状态就行了,完全可以用数组来实现(不用写旋转算法了:)比如:/* 方块类型为 */char244 B1=0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0 ,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0 ;含两种状态,每个状态是一个4*4数组,为1表示实心,为0表示空心.因此我们总共设计了7种造型,每种造型又可以通过旋转而变化出2到4种形状,利用随机函数在一个预览窗体中提前展示形状供用户参考,然后将展示的形状复制到游戏窗体中进行
4、摆放,在游戏窗体中用户就可以使用键盘的方向键来控制方块的运动,然后利用递归语句对每一行进行判断,如果有某行的方块是满的,则消除这行的方块,并且使上面的方块自由下落,其中,方块向下的速度是有时钟控件控制的,在游戏中,用户也可以使用向下键加快下落速度,定义一个变量,对消除的函数进行记录,最后就可以得出用户的分数,用if 语句对分数判断,达到一定的积分就可以升级到下一个档次。 俄罗斯方块游戏设计的主要步骤为以下几个方面: 1.游戏界面的设计。 2.俄罗斯方块的造型。 3.俄罗斯方块的旋转。 4.俄罗斯方块的运动情况(包括向左,向右和向下)。 5.俄罗斯方块的自动消行功能。 6.游戏级别的自由选择。
5、7.游戏速度的自由选择。 8.游戏得分的计算。 9.游戏菜单选项的设计及功能实现。1.3开发环境:1.3.1硬件环境一台电脑386,486,586及兼容机以上,包括键盘、鼠标,最小硬盘空间1G,内存M以上。 1.3.2软件环境本系统的设计采用的是C语言开发,Windows操作系统,win-tc v1.9.1以上2.总体设计2.1开发与设计的总体思想程序的设计方法是采用结构化程序设计方法,用c语言进行开发。2.2模块设计2.2.1主要模块:先画出主要窗口界面,由外边框、盒状收缩,百页窗效果、主题字及功能函数组成。根据函数顺序来完成相应功能,进入游戏(先建立游戏界面,屏幕提示选择按任意键开始游戏,
6、);游戏规则(满一行加一分);最后是工作人员(显示小组人员名单后返回主界面);最后按任意键结束整个游戏系统。2.2.2 按键及功能对照表 :名 称 作用Up 上键变形Down 下键下落Esc 退出Enter 暂停Left 左移 Right 右移 Space 直速下落2.2.3主要函数名称以及功能表:函数函数作用说明boxrad()随机得到当前方块和下个方块的形状和方向init()初始化图形模式cls()在图形模式下的清屏clscr()在图形模式下的高级清屏minbox()最小方块的绘制box()最小方块的高级绘制txt()游戏中出现的文字win()界面的绘制re90()把方块的方向旋转fx个9
7、0度(fx最大等于3)funbox()当前方块的绘制nextfunbox()下一个方块的绘制interrupt newhandler()时间中断定义delcol()由于游戏的规则,消掉都有最小方块的一行*numgochar()把数字转换为字符串delete()消掉所有都有最小方块的行KillTimer()时间中断结束downok()测试当前方块是否可以向下落leftok()测试当前方块是否可以向左行rightok()测试当前方块是否可以向右行upok()测试当前方块是否可以变形setgril()当前方块落下之后,给屏幕坐标作标记gameover()游戏结束call_key()按键的设置time
8、zd()时间中断开始byc()百叶窗函数hzss()盒状收缩代码show_word()调用点阵函数,在指定位置上输出汉字prep_word()开辟内存空间move_word()移动文字main()主程序开始2.3模块设计小结由上述模块分析和设计可知,本游戏的核心模块是主界面模块,图形修饰模块与函数模块均是为其而服务。3.实验结果分析及程序代码#include #include #include #include #include #define MINBOXSIZE 20 /* 最小方块的尺寸 */ #define BGCOLOR 6 /* 背景着色 */ #define GX 200 #de
9、fine GY 10 #define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/ /* 按键码*/ #define VK_LEFT 0x4b00 /*左*/#define VK_RIGHT 0x4d00 /*右*/#define VK_DOWN 0x5000 /*下*/#define VK_UP 0x4800 /*上*/#define VK_SPACE 0x3920 /*空格*/#define VK_ESC 0x011b /*退出*/#define VK_ENTER 0x1c0d /*回车*/* 定义俄罗斯方块的方向(我定义他为4种)*/ #define F_DONG 0
10、/*东*/#define F_NAN 1 /*南*/#define F_XI 2 /*西*/#define F_BEI 3 /*北*/#define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/ #define NEXTROW 12 /* 要出的下一个方块的横坐标*/ #define MAXROW 14 /* 游戏屏幕大小*/ #define MAXCOL 20 #define SCCOL 50 /*游戏屏幕在显示器上的相对位置*/#define SCROW 30 #define X_Z 0 /* 定义方块的形状(共八种)*/ #define X_REZ 1 #define X_7
11、 2 #define X_RE7 3 #define X_I 4 #define X_REI 5 #define X_TIAN 6 #define X_T 7 void *buf; /*定义无类型指针,用于将来指向内存空间*/int gril2216; /* 游戏屏幕坐标*/ int col=1,row=7; /* 当前方块的横纵坐标*/ int boxfx=0,boxgs=0; /* 当前方块的形状和方向*/int nextboxfx,nextboxgs,maxcol=22;/*下一个方块的形状和方向*/ int minboxcolor,nextminboxcolor;/*小方块的颜色,下一
12、个小方块的颜色*/int num=0; /*游戏分*/ int dj=0,gamedj10=18,16,14,12,10,8,6,4,2,1;/* 游戏等级*/ Struct all int x,y; int fangxiang; /*方向*/int gesu; /*第几个方块*/; /* 以下我用了一个3维数组来纪录方块的最初形状和方向*/ int boxstr844= 0,0,0,0, 0,0,0,0, 0,1,1,0, 0,0,1,1, 0,0,0,0, 0,0,0,0, 0,0,1,1, 0,1,1,0, 0,0,0,0, 0,0,1,1, 0,0,0,1, 0,0,0,1, 0,0,
13、0,0, 0,0,1,1, 0,0,1,0, 0,0,1,0, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,1,1, 0,0,1,1, 0,0,0,0, 0,0,0,0, 0,1,1,1, 0,0,1,0 ; /* 随机得到当前方块和下一个方块的形状和方向*/ void boxrad() minboxcolor=nextminboxcolor; /*下一个方块的颜色*/boxfx=nextboxfx; /*下一个方块的方向*/boxgs=nextbox
14、gs; /*下一个方块是第几个方块*/nextminboxcolor=random(16); /*随机产生下一个方块的颜色*/if(nextminboxcolor=6|nextminboxcolor=7) /*如果颜色是棕色或淡灰色*/nextminboxcolor=9; /*将其改为淡蓝色*/nextboxfx=random(4); /*随机产生下一个方块的方向*/nextboxgs=random(8); /*随机产生下一个方块是第几个方块*/ /*初始化图形模式*/ void init(void)int gh=DETECT,gm=0;int errorcode;registerbgidri
15、ver(EGAVGA_driver);initgraph(&gh,&gm, );/* 在图形模式下的清屏 */ void cls() setfillstyle(SOLID_FILL,0);/*以背景颜色实填充*/setcolor(0); bar(0,0,640,480); /*基本图形函数*/ /*在图形模式下的高级清屏*/void clscr(int a,int b,int c,int d,int color) setfillstyle(SOLID_FILL,color); /*以color颜色实填充*/setcolor(color); /*设置当前前景色为color*/bar(a,b,c,
16、d); /*基本图形函数*/ /*最小方块的绘制*/ void minbox(int asc,int bsc,int color) int a=0,b=0; a=SCCOL+asc; /*SCCOL 50,SCROW 30游戏屏幕在显示器上的相对位置*/b=SCROW+bsc; clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color); /* MINBOXSIZE 20最小方块的尺寸 */if(color!=BGCOLOR)/*如果当前色是背景色,将其改为白色*/ setcolor(15); line(a+1,b+1,a-1+MINBOXSIZE,b
17、+1); line(a+1,b+1,a+1,b-1+MINBOXSIZE); setcolor(0);line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE);line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); /*最小方块的高级绘制*/ void box(int a,int b,int color)clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color); setcolor(15); line(a+1,b+1,a-1+MINBOXSIZE
18、,b+1); line(a+1,b+1,a+1,b-1+MINBOXSIZE); setcolor(0); line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE); line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); /*游戏中出现的文字*/ void txt(int a,int b,char *txt,int font,int color) setcolor(color); settextstyle(0,0,font); outtextxy(a,b,txt); /*windows
19、 绘制*/ void win(int a,int b,int c,int d,int bgcolor,char *text,int font,int textcolor) clscr(a,b,c,d,7); clscr(a+3,b+24,c-3,d-3,bgcolor); clscr(a+3,b+3,c-3,b+20,9); setcolor(15); line(a,b,c,b); line(a,b,a,d); line(a+2,b+21,c-2,b+21); line(c-2,b+2,c-2,b+21); line(a+2,d-2,c-2,d-2); line(c-2,b+23,c-2,d-
20、2); txt(a+5,b+8,text,font,textcolor);setcolor(0); line(a,d,c,d); line(c,b,c,d); line(a+3,b+2,c-3,b+2); line(a+2,b+2,a+2,b+20); line(a+2,b+24,a+2,d-2); line(a+2,b+23,c-3,b+23); /*把方块的方向旋转fx个90度(fx最大等于3)*/ void re90(int boxxy44,int fx) int i,j,k,zero; int a44; for(k=0;kfx;k+) for(i=0;i4;i+) for(j=0;j4
21、;j+) aij=boxxy3-ji; for(i=0;i4;i+) for(j=0;j4;j+) boxxyij=aij; for(i=0;i4;i+) zero=1; for(j=0;j4;j+) if(boxxyj3!=0) zero=0; if(zero) for(j=0;j4;j+) boxxyj3=boxxyj2; boxxyj2=boxxyj1; boxxyj1=boxxyj0; boxxyj0=0; /* 当前方块的绘制*/ void funbox(int a,int b,int color) int i,j; int boxz44; for(i=0;i4;i+) for(j=
22、0;j4;j+) boxzij=boxstrboxgsij; re90(boxz,boxfx); for(i=0;i4;i+) for(j=0;j4;j+) if(boxzij=1) minbox(j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color); /*下一个方块的绘制*/ void nextfunbox(int a,int b,int color) int i,j; int boxz44; for(i=0;i4;i+) for(j=0;j4;j+) boxzij=boxstrnextboxgsij; re90(boxz,nextboxfx); f
23、or(i=0;i4;i+) for(j=0;j1;i-) for(j=1;j=1;i+) ai=0+ (x % 10); x=x/10; for(j=0;j=i/2;j+) k=aj; aj=ai-j; ai-j=k; ai+1=0; return(a); /*消掉所有都有最小方块的行*/ void delete() int i,j,zero,delgx=0; char *nm; for(i=1;i21;i+) zero=0; for(j=1;j15;j+) if(grilij=0) zero=1; if(zero=0) delcol(i); delgx+; num=num+delgx*del
24、gx*10; dj=num/10000; nm=numgochar(num); clscr(456,173,500,200,BGCOLOR); txt(456,173,Number:,1,15); txt(456,193,nm,1,15); /*时间中断结束*/ void KillTimer() disable(); setvect(TIMER,oldhandler); enable(); /* 测试当前方块是否可以向下落*/ int downok() int i,j,k=1,a44; for(i=0;i4;i+) for(j=0;j4;j+) aij=boxstrboxgsij; re90(
25、a,boxfx); for(i=0;i4;i+) for(j=0;j4;j+) if(aij & grilcol+i+1row+j) k=0; return(k); /* 测试当前方块是否可以向左行*/ int leftok() int i,j,k=1,a44; for(i=0;i4;i+) for(j=0;j4;j+) aij=boxstrboxgsij; re90(a,boxfx); for(i=0;i4;i+) for(j=0;j4;j+) if(aij & grilcol+irow+j-1) k=0; return(k); /* 测试当前方块是否可以向右行*/ int rightok(
26、) int i,j,k=1,a44; for(i=0;i4;i+) for(j=0;j4;j+) aij=boxstrboxgsij; re90(a,boxfx); for(i=0;i4;i+) for(j=0;j4;j+) if(aij & grilcol+irow+j+1) k=0; return(k); /* 测试当前方块是否可以变形*/ int upok() int i,j,k=1,a44; for(i=0;i4;i+) for(j=0;j=0;i-) for(j=3;j=0;j-) if(aij & grilcol+irow+j) k=0; return(k); /*当前方块落下之后
27、,给屏幕坐标作标记*/ void setgril() int i,j,a44; funbox(0,0,minboxcolor); for(i=0;i4;i+) for(j=0;j4;j+) aij=boxstrboxgsij; re90(a,boxfx); for(i=0;i4;i+) for(j=0;j=0;i-) for(j=2;j3) boxfx=0; funbox(0,0,minboxcolor); break; case VK_LEFT: /*左方向键,纵坐标减一*/ if(leftok() row-; funbox(0,0,minboxcolor); break; case VK_
28、RIGHT: /*右方向键,纵坐标加一*/ if(rightok() row+; funbox(0,0,minboxcolor); break; case VK_SPACE: /*空格键,直接落到最后可以落到的们置*/ while(downok() col+; funbox(0,0,minboxcolor); setgril(); nextfunbox(NEXTCOL,NEXTROW,BGCOLOR); boxrad(); nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor); delete(); break; default: win(423,53,620,
29、95,15,Enter Key Error!,1,15);txt(428,80,Plese Enter Anly Key AG!,1,4);getch(); clscr(420,50,622,97,BGCOLOR); /*时间中断开始*/ void timezd(void) int key; SetTimer(newhandler); boxrad(); nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor); for(;) if(bioskey(1) key=bioskey(0); funbox(0,0,BGCOLOR); if(key=VK_ESC) bre
30、ak; call_key(key); if(TimerCountergamedjdj) TimerCounter=0; if(downok() funbox(0,0,BGCOLOR); col+; funbox(0,0,minboxcolor); else if(col=1) gameover(); getch(); break; setgril(); delete(); funbox(0,0,minboxcolor); col=1;row=7; funbox(0,0,BGCOLOR); nextfunbox(NEXTCOL,NEXTROW,BGCOLOR); boxrad(); nextfu
31、nbox(NEXTCOL,NEXTROW,nextminboxcolor); /*百叶窗函数*/void byc(void) int i,j; for(i=0;i40;i+) for(j=0;j640;j= j +40) /*每隔40像素画一条线*/ setcolor(BLUE); /*设置前景色*/ line(j+i,0,j+i,479); delay(500); /*盒状收缩代码*/void hzss(void) int x1=0,y1=0,x2=639,y2=479; setcolor(1); for(;y1=0&y1=0&x2=639&y2=479;x1-,y1-,x2+,y2+) r
32、ectangle(x1,y1,x2,y2); delay(1000); void drawmat(char *mat,int matsize,int x,int y,int color)/*汉字点阵输出函数*/ int i,j,k,m; m=(matsize-1)/8+1; for(j=0;jmatsize;j+) for(i=0;im;i+) for(k=0;kk) putpixel(x+i*8+k,y+j,color);char zu48H=/* 以下是 组 的 48点阵黑体 字模,288 byte */ ; char zhang_48H=/* 以下是 长 的 48点阵黑体 字模,288
33、byte */ ;char dian48H=/* 以下是 : 的 48点阵黑体 字模,288 byte */ ;char yuan_48H=/* 以下是 员 的 48点阵黑体 字模,288 byte */ ;char zhang48K=/* 以下是 张 的 48点阵楷体_GB2312 字模,288 byte */ ; char fang48K=/* 以下是 方 的 48点阵楷体_GB2312 字模,288 byte */ ;char yuan48K=/* 以下是 元 的 48点阵楷体_GB2312 字模,288 byte */ ; char jie48K=/* 以下是 解 的 48点阵楷体_G
34、B2312 字模,288 byte */ ; char ying48K=/* 以下是 莹 的 48点阵楷体_GB2312 字模,288 byte */ ;char zhao48K=/* 以下是 赵 的 48点阵楷体_GB2312 字模,288 byte */ ; char jing48K=/* 以下是 静 的 48点阵楷体_GB2312 字模,288 byte */ ;char tao48K=/* 以下是 陶 的 48点阵楷体_GB2312 字模,288 byte */ ;char yuan_48K=/* 以下是 园 的 48点阵楷体_GB2312 字模,288 byte */ ;char h
35、uo48K=/* 以下是 霍 的 48点阵楷体_GB2312 字模,288 byte */ ;char shuai48K=/* 以下是 帅 的 48点阵楷体_GB2312 字模,288 byte */ ;char e64H=/* 以下是 俄 的 64点阵黑体 字模,512 byte */ ;char luo64H=/* 以下是 罗 的 64点阵黑体 字模,512 byte */ ; char si64H=/* 以下是 斯 的 64点阵黑体 字模,512 byte */ ;char fang64H=/* 以下是 方 的 64点阵黑体 字模,512 byte */ ;char kuai64H=/*
36、 以下是 块 的 64点阵黑体 字模,512 byte */ ;void youximing(void) int x=80,y=200,color=1,space=100; drawmat(e64H,64,x,y,color); drawmat(luo64H,64,x+=space,y,color); drawmat(si64H,64,x+=space,y,color); drawmat(fang64H,64,x+=space,y,color); drawmat(kuai64H,64,x+=space,y,color); void show_word(void)/*调用点阵函数,在指定位置上输出汉字*/