C语言课程设计报告游戏Word文档格式.docx
《C语言课程设计报告游戏Word文档格式.docx》由会员分享,可在线阅读,更多相关《C语言课程设计报告游戏Word文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
iii.游戏界面,可以使用简单的特殊制表符,来实现,并通过清屏函数来进行反复同位置打印界面。
iv.需要判断游戏结束的函数,以及记录游戏分数和步骤的变量
v.当游戏结束时,能够询问用户是否重新开始。
vi.随机生成一个新数,可以调用随机函数,使用时间做种子。
c)实现难点:
i.打印游戏界面,要实现灵活能根据棋盘数组里面的数据灵活打印。
ii.执行操作时,数值的移动和合并。
四、流程图
五、C语言源代码
//游戏2048.c
#include"
windows.h"
time.h"
stdio.h"
conio.h"
string.h"
//宏定义常量方向键值
//constintLEFT=75,UP=72,RIGHT=77,DOWN=80;
#defineLEFT75
#defineUP72
#defineRIGHT77
#defineDOWN80
constcharerror_str[]="
您上次输入的指令无法识别,请重新输入。
"
;
structboard
{
intplace[4][4];
longintstepn;
longintnum;
//存储游戏分数
longinttime;
intdtk;
//directionkey记录方向键,及操作方向
intover;
intzeronum;
};
//该函数为游戏运行函数,当只是玩游戏的时候。
进入该函数,游戏控制函数。
intmain()
//place数组为棋盘,其中为零代表空,-1代表不能合并的牌,其他2的倍数值为本身含义,初始化为全0。
structboardboard1,board_backup;
intnewgame(structboard*,int),
show(structboard*),
operate(structboard*);
charstr[100]="
首次运行游戏"
//用于记录系统返回给用户的信息,例如:
上一步执行向左合并,按键有误等
newgame(&
board1,0);
//调用函数为新局初始化,第二个参数为初始化方式
show(&
board1);
printf("
\n%s\n\n请从键盘上单击方向键,指定下一步操作(ESC键退出游戏)……\n"
str);
do
{
switch(_getch())
{
case224:
switch(board1.dtk=_getch())
{
caseLEFT:
strcpy_s(str,sizeof(str),"
您上次输入的方向键为:
←,已执行左向合并。
);
board_backup=board1;
operate(&
break;
caseUP:
↑,已执行上向合并。
caseRIGHT:
→,已执行右向合并。
caseDOWN:
↓,已执行下向合并。
default:
strcpy_s(str,sizeof(str),error_str);
}
}break;
case27:
exit(27);
default:
}
system("
cls"
show(&
printf("
if(board1.over)
printf("
\n游戏结束,是否重新开始?
(y重新开始/n或ECS退出/其他键无效)"
while
(1)
str[99]=_getch();
if(str[99]=='
y'
)
{
newgame(&
show(&
break;
}
elseif(str[99]=='
c'
change(&
board1,&
board_backup);
n'
||str[99]==27)
}while(!
board1.over);
\n按任意键退出……"
_getch();
return0;
}
//该函数为主要打印函数,包括棋盘的打印,分数,等信息
intshow(structboard*pboard)
inti,j,x,len,
numlen(int);
游戏2048——游戏运行时间:
%ldS\n"
time(NULL)-(*pboard).time);
游戏分数:
%ld"
(*pboard).num);
已执行步骤数:
%ld\n"
(*pboard).stepn);
//开始绘制棋盘
╔═══╦═══╦═══╦═══╗\n║║║║║\n"
for(i=0;
i<
7;
++i)
if(i%2==0)
║"
for(j=0;
j<
8;
++j)
if(j%2==0)
if((*pboard).place[i/2][j/2]==0)
printf("
"
//如果值为0,输入六个空格
else//打印值时。
调用numlen判断值的位数,控制数值前后的空格数量,最长为6,若为奇数,前面空格比后面多一个。
{
len=numlen((*pboard).place[i/2][j/2]);
for(x=0;
x<
(6-len+1)/2;
++x)
printf("
%d"
(*pboard).place[i/2][j/2]);
(6-len)/2;
}
else
printf("
else
║║║║║\n╠═══╬═══╬═══╬═══╣\n║║║║║"
\n"
}
║║║║║\n╚═══╩═══╩═══╩═══╝\n"
//这是show函数的附属函数,用于求一个整数长度。
intnumlen(inta)
inti,n=1;
for(i=1;
11;
n*=10;
if(a==a%n)
returni;
//开始新的游戏,将棋盘和数据初始化,或者载入棋盘,第二个参数决定初始化方案,默认0
intnewgame(structboard*pboard,intproject)
inti,j,t;
(*pboard).stepn=0;
(*pboard).num=0;
(*pboard).time=(longint)time(NULL);
//取当前时间为开始时间
(*pboard).dtk=0;
(*pboard).over=0;
(*pboard).zeronum=14;
4;
for(j=0;
(*pboard).place[i][j]=0;
i=(int)(rand()/32768.0*4);
j=(int)(rand()/32768.0*4);
}while((*pboard).place[i][j]);
t=2*((int)(rand()/32768.0*2)+1);
(*pboard).place[i][j]=t;
//主要操作函数,调用该函数,将执行结构体中对应按键值的方向的操作,并增加分数和操作次数。
intoperate(structboard*pboard)
inti,j,t,shun=-1,alter=0,//alter变量是用来判断执行步骤的时候是否改变了棋局。
shun用来记录已经进行合并的值对应的I或J,用来避免该值再次合并
randget(structboard*),
calczeronum(structboard*);
switch((*pboard).dtk)
caseUP:
++j,shun=-1)
for(i=1;
if((*pboard).place[i][j]!
=0)
for(t=i-1;
t>
=0;
--t)
if((*pboard).place[t][j]!
{
if((*pboard).place[t][j]==(*pboard).place[i][j]&
&
shun!
=t)
{
(*pboard).num+=(*pboard).place[t][j]*=2;
(*pboard).place[i][j]=0;
shun=t;
alter=1;
}
elseif(t+1!
=i)
(*pboard).place[t+1][j]=(*pboard).place[i][j];
break;
}
elseif(t==0)
(*pboard).place[t][j]=(*pboard).place[i][j];
(*pboard).place[i][j]=0;
alter=1;
}break;
caseDOWN:
for(i=2;
i>
--i)
for(t=i+1;
t<
++t)
elseif(t-1!
(*pboard).place[t-1][j]=(*pboard).place[i][j];
elseif(t==3)
caseRIGHT:
for(i=0;
++i,shun=-1)
for(j=2;
j>
--j)
for(t=j+1;
if((*pboard).place[i][t]!
if((*pboard).place[i][t]==(*pboard).place[i][j]&
(*pboard).num+=(*pboard).place[i][t]*=2;
=j)
(*pboard).place[i][t-1]=(*pboard).place[i][j];
(*pboard).place[i][t]=(*pboard).place[i][j];
caseLEFT:
for(j=1;
for(t=j-1;
(*pboard).place[i][t+1]=(*pboard).place[i][j];
default:
return-1;
if(alter)
++(*pboard).stepn;
returnrandget(pboard);
return1;
//计算place数组中有多少个零,即多少个空位,返回值等同于board1.zeronum
intcalczeronum(structboard*pboard)
inti,j;
for((*pboard).zeronum=0,i=0;
if((*pboard).place[i][j]==0)
++(*pboard).zeronum;
return(*pboard).zeronum;
//新数生成函数。
每次有效执行操作函数时,进行新的数生成
intrandget(structboard*pboard)
inti,j,t,x,
ifover(structboard*);
calczeronum(pboard);
t=(int)(rand()/32768.0*(*pboard).zeronum)+1;
for(x=0,i=0;
if(++x==t)
(*pboard).place[i][j]=2*((int)(rand()/32768.0*2)+1);
if(!
(--(*pboard).zeronum)||(*pboard).zeronum<
ifover(pboard);
return0;
return-1;
//用来判断游戏是否结束,当board.zeronum的值为零的时候,调用该函数进行判断。
游戏结束时返回1,over值为1,否则返回可操作方向值,DOWN或RIGHT
intifover(structboard*pboard)
inti;
if((*pboard).place[i][0]==(*pboard).place[i][1]||(*pboard).place[i][1]==(*pboard).place[i][2]||(*pboard).place[i][2]==(*pboard).place[i][3])
(*pboard).over=0;
returnDOWN;
if((*pboard).place[0][i]==(*pboard).place[1][i]||(*pboard).place[1][i]==(*pboard).place[2][i]||(*pboard).place[2][i]==(*pboard).place[3][i])
returnRIGHT;
return(*pboard).over=1;
六