C语言课程设计报告游戏.docx

上传人:b****5 文档编号:6917216 上传时间:2023-01-12 格式:DOCX 页数:19 大小:207.52KB
下载 相关 举报
C语言课程设计报告游戏.docx_第1页
第1页 / 共19页
C语言课程设计报告游戏.docx_第2页
第2页 / 共19页
C语言课程设计报告游戏.docx_第3页
第3页 / 共19页
C语言课程设计报告游戏.docx_第4页
第4页 / 共19页
C语言课程设计报告游戏.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

C语言课程设计报告游戏.docx

《C语言课程设计报告游戏.docx》由会员分享,可在线阅读,更多相关《C语言课程设计报告游戏.docx(19页珍藏版)》请在冰豆网上搜索。

C语言课程设计报告游戏.docx

C语言课程设计报告游戏

东华理工大学

C语言课程设计报告

 

学院:

国际教育学院学院

专业:

电子信息工程

班级:

1420606

学号:

2

姓名:

钟天运

一、课程设计题目:

游戏2048

二、课程设计要求:

a)使用C语言编写2048这款游戏

b)能够正常运行,拥有游戏界面。

c)能正常进行游戏从开始到结束。

d)用户操作方便

三、设计思路:

a)游戏介绍:

i.2048是一款简单的数字类游戏,界面是一个4*4的方形格子。

每个格子里可以为空或者有一个2^n的数值。

ii.用户可以输入4种指令,分别是:

上下左右,游戏会根据用户的指定的方向,将格子中的数值向对应方向进行移动,直至移动到最边上的格子或者有其他数值占用,如果碰到等大数值,将会进行合并。

此外,成功移动后,会在一个空格子随机生成一个2或者4

iii.游戏目标是合成2048这个数值或者更大的数值。

b)实现思路:

i.可以使用二维数组来保存4*4格子中的数值

ii.指令,可以通过输入字符函数,读取用户在键盘上的方向键,进行判断执行对应的代码。

iii.游戏界面,可以使用简单的特殊制表符,来实现,并通过清屏函数来进行反复同位置打印界面。

iv.需要判断游戏结束的函数,以及记录游戏分数和步骤的变量

v.当游戏结束时,能够询问用户是否重新开始。

vi.随机生成一个新数,可以调用随机函数,使用时间做种子。

c)实现难点:

i.打印游戏界面,要实现灵活能根据棋盘数组里面的数据灵活打印。

ii.执行操作时,数值的移动和合并。

 

四、流程图

五、C语言源代码

//游戏2048.c

#include"windows.h"

#include"time.h"

#include"stdio.h"

#include"conio.h"

#include"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(&board1);break;

caseUP:

strcpy_s(str,sizeof(str),"您上次输入的方向键为:

↑,已执行上向合并。

");board_backup=board1;operate(&board1);break;

caseRIGHT:

strcpy_s(str,sizeof(str),"您上次输入的方向键为:

→,已执行右向合并。

");board_backup=board1;operate(&board1);break;

caseDOWN:

strcpy_s(str,sizeof(str),"您上次输入的方向键为:

↓,已执行下向合并。

");board_backup=board1;operate(&board1);break;

default:

strcpy_s(str,sizeof(str),error_str);

}

}break;

case27:

exit(27);

default:

strcpy_s(str,sizeof(str),error_str);

}

system("cls");

show(&board1);

printf("\n%s\n\n请从键盘上单击方向键,指定下一步操作(ESC键退出游戏)……\n",str);

if(board1.over)

{

printf("\n游戏结束,是否重新开始?

(y重新开始/n或ECS退出/其他键无效)");

while

(1)

{

str[99]=_getch();

if(str[99]=='y')

{

newgame(&board1,0);

show(&board1);

break;

}

elseif(str[99]=='c')

{

change(&board1,&board_backup);

break;

}

elseif(str[99]=='n'||str[99]==27)

break;

}

}

}while(!

board1.over);

printf("\n按任意键退出……");

_getch();

return0;

}

//该函数为主要打印函数,包括棋盘的打印,分数,等信息

intshow(structboard*pboard)

{

inti,j,x,len,

numlen(int);

printf("游戏2048——游戏运行时间:

%ldS\n",time(NULL)-(*pboard).time);

printf("游戏分数:

%ld",(*pboard).num);

printf("已执行步骤数:

%ld\n",(*pboard).stepn);

//开始绘制棋盘

printf("╔═══╦═══╦═══╦═══╗\n║║║║║\n");

for(i=0;i<7;++i)

{

if(i%2==0)

{

printf("║");

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("");

printf("%d",(*pboard).place[i/2][j/2]);

for(x=0;x<(6-len)/2;++x)

printf("");

}

}

else

printf("║");

}

}

else

{

printf("║║║║║\n╠═══╬═══╬═══╬═══╣\n║║║║║");

}

printf("\n");

}

printf("║║║║║\n╚═══╩═══╩═══╩═══╝\n");

return0;

}

//这是show函数的附属函数,用于求一个整数长度。

intnumlen(inta)

{

inti,n=1;

for(i=1;i<11;++i)

{

n*=10;

if(a==a%n)

returni;

}

return0;

}

//开始新的游戏,将棋盘和数据初始化,或者载入棋盘,第二个参数决定初始化方案,默认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;

for(i=0;i<4;++i)

for(j=0;j<4;++j)

(*pboard).place[i][j]=0;

 

do

{

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;

do

{

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;

return0;

}

//主要操作函数,调用该函数,将执行结构体中对应按键值的方向的操作,并增加分数和操作次数。

intoperate(structboard*pboard)

{

inti,j,t,shun=-1,alter=0,//alter变量是用来判断执行步骤的时候是否改变了棋局。

shun用来记录已经进行合并的值对应的I或J,用来避免该值再次合并

randget(structboard*),

calczeronum(structboard*);

switch((*pboard).dtk)

{

caseUP:

{

for(j=0;j<4;++j,shun=-1)

{

for(i=1;i<4;++i)

{

if((*pboard).place[i][j]!

=0)

{

for(t=i-1;t>=0;--t)

{

if((*pboard).place[t][j]!

=0)

{

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];

(*pboard).place[i][j]=0;

alter=1;

}

break;

}

elseif(t==0)

{

(*pboard).place[t][j]=(*pboard).place[i][j];

(*pboard).place[i][j]=0;

alter=1;

break;

}

}

}

}

}

}break;

caseDOWN:

{

for(j=0;j<4;++j,shun=-1)

{

for(i=2;i>=0;--i)

{

if((*pboard).place[i][j]!

=0)

{

for(t=i+1;t<4;++t)

{

if((*pboard).place[t][j]!

=0)

{

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];

(*pboard).place[i][j]=0;

alter=1;

}

break;

}

elseif(t==3)

{

(*pboard).place[t][j]=(*pboard).place[i][j];

(*pboard).place[i][j]=0;

alter=1;

break;

}

}

}

}

}

}break;

caseRIGHT:

{

for(i=0;i<4;++i,shun=-1)

{

for(j=2;j>=0;--j)

{

if((*pboard).place[i][j]!

=0)

{

for(t=j+1;t<4;++t)

{

if((*pboard).place[i][t]!

=0)

{

if((*pboard).place[i][t]==(*pboard).place[i][j]&&shun!

=t)

{

(*pboard).num+=(*pboard).place[i][t]*=2;

(*pboard).place[i][j]=0;

shun=t;

alter=1;

}

elseif(t-1!

=j)

{

(*pboard).place[i][t-1]=(*pboard).place[i][j];

(*pboard).place[i][j]=0;

alter=1;

}

break;

}

elseif(t==3)

{

(*pboard).place[i][t]=(*pboard).place[i][j];

(*pboard).place[i][j]=0;

alter=1;

break;

}

}

}

}

}

}break;

caseLEFT:

{

for(i=0;i<4;++i,shun=-1)

{

for(j=1;j<4;++j)

{

if((*pboard).place[i][j]!

=0)

{

for(t=j-1;t>=0;--t)

{

if((*pboard).place[i][t]!

=0)

{

if((*pboard).place[i][t]==(*pboard).place[i][j]&&shun!

=t)

{

(*pboard).num+=(*pboard).place[i][t]*=2;

(*pboard).place[i][j]=0;

shun=t;

alter=1;

}

elseif(t+1!

=j)

{

(*pboard).place[i][t+1]=(*pboard).place[i][j];

(*pboard).place[i][j]=0;

alter=1;

}

break;

}

elseif(t==0)

{

(*pboard).place[i][t]=(*pboard).place[i][j];

(*pboard).place[i][j]=0;

alter=1;

break;

}

}

}

}

}

}break;

default:

return-1;

}

if(alter)

{

++(*pboard).stepn;

returnrandget(pboard);

}

return1;

}

//计算place数组中有多少个零,即多少个空位,返回值等同于board1.zeronum

intcalczeronum(structboard*pboard)

{

inti,j;

for((*pboard).zeronum=0,i=0;i<4;++i)

for(j=0;j<4;++j)

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;i<4;++i)

for(j=0;j<4;++j)

if((*pboard).place[i][j]==0)

if(++x==t)

{

(*pboard).place[i][j]=2*((int)(rand()/32768.0*2)+1);

if(!

(--(*pboard).zeronum)||(*pboard).zeronum<=0)

ifover(pboard);

return0;

}

return-1;

}

//用来判断游戏是否结束,当board.zeronum的值为零的时候,调用该函数进行判断。

游戏结束时返回1,over值为1,否则返回可操作方向值,DOWN或RIGHT

intifover(structboard*pboard)

{

inti;

for(i=0;i<4;++i)

{

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])

{

(*pboard).over=0;

returnRIGHT;

}

}

return(*pboard).over=1;

}

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 企业管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1