贪吃蛇实验报告

您所在的位置:网站首页 蛇的设计字体 贪吃蛇实验报告

贪吃蛇实验报告

2024-01-15 14:13| 来源: 网络整理| 查看: 265

一:概要设计

程序功能:通过“w a s d”按键实现对蛇移动方向的控制,通过吃豆增加蛇身长度, 同时获得并记录游戏分数;game over之后可以选择结束或再次进行游戏

函数定义调用关系:

int main():主函数; 调用所有函数;

void setpos(int x,int y):坐标设置函数;

int HitWall():判断是否撞墙函数;调用void setpos(int x,int y);

int SelfBite():判断蛇身是否打结;调用void setpos(int x,int y);system();

int Move():移动函数;调用int HitWall();int SelfBite();void setpos(int x,int y);sleep();free();

void Welcome():初始界面函数;调用void setpos(int x,int y);

void DrawFrame():画边框函数;

void InitSnake():初始化蛇函数;

void CreateFood():创建豆函数;调用void setpos(int x,int y);

void PlayGame():游戏移动循环函数;调用void setpos(int x,int y);

void free_snake(Snake*head):释放资源函数;

char GetKeyBoard():键盘控制函数;

void Restart():重新开始函数;调用 void setpos(int x,int y);

程序流程:

将蛇身,食物,墙数据化: 蛇身用链表表示并用“@”打印,食物位置由随机数函数确认并用“?”打印,而墙的范围 可随意改变,确认一组长宽后,用“#”打印。

设定初始参数:

规定一个适当的初始速度,一个初始蛇身长度。

获取键位指示,模拟蛇的移动:

规定蛇初始的移动方向为向右方向,用GetAsyncKeyState()函数来判断键位指令判断其合理性,如果键位输入的命令是有效命令,则执行这条命令。蛇的运动过程则用链表头插法表示,同时去除蛇尾。

判断吃到食物和撞到自己和撞到墙:

吃食物:

通过比较蛇头下一次出现的位置和目标处的物体,使用if-else语句做出判断如果目标处是食物,则将其变为新的蛇头,蛇尾不变。

撞到墙:

比较蛇头下一次出现的位置和目标处的物体,使用if-else语句做出判断,如果目标处是墙或者自己身体则游戏结束。

细节处理和游戏引导:

在游戏开始和结束出给出相应文字引导,过程中给出分数等基本信息。

调用库函数:stdio.h;conio.h;stdlib.h;time.h;string.h;windows.h;

二:详细设计

地图初始化

void DrawFrame(){ int i=0; for(i=0;iy==foody) {goto flag; } if(p->next==NULL) {break; } p=p->next; } setpos(foodx,foody); printf("?"); }

控制蛇身移动

int Move() {int ret; if((key!='a')&&(key!='w')&&(key!='s')&&(key!='d')) {return 0; } ret=HitWall(); ret+=SelfBite(); if(ret==1) { return 1; } p=(Snake*)malloc(sizeof(Snake)); p->next=head; switch(key) {case'd': p->x=head->x+2; p->y=head->y; break; case'w': p->x=head->x; p->y=head->y-1; break; case's': p->x=head->x; p->y=head->y+1; break; case'a': p->x=head->x-2; p->y=head->y; break; } setpos(p->x,p->y); printf("@"); head=p; Sleep(speed); if(p->x==foodx&&p->y==foody) { CreateFood(); score+=10; setpos(60,7); printf("得分%d",score); } else{ while(p->next->next!=NULL) p=p->next; setpos(p->x,p->y); printf(" "); free(p->next); p->next=NULL; p=head; } return 0; }

判断game是否over

int HitWall(){//判断是否撞墙 if(head->x==0||head->x==RIGHT_WALL||head->y==0||head->y==DOWN_WALL) { setpos(DOWN_WALL,14); printf("Game Over!"); return 1; } return 0; } int SelfBite(){//判断是否打结 while(p->next!=NULL) { p=p->next; if(head->x==p->x&&head->y==p->y) {setpos(DOWN_WALL,14); printf("Game Over!"); return 1; system("cls"); main(); } } return 0; }

通过键盘控制

char GetKeyBoard() {//获取键盘输入 char key=0; if(_kbhit()){ key=_getch(); } return key; }

三:功能展示

游戏开始

吃豆并获得分数

game over之后可以选择重开gg下一把或者摆烂不玩了

四:成员分工

@assassin_zzy :代码创建

@dlkd20:代码优化

@MySQL搬砖人:实验报告撰写

五:总结与建议

c语言功能之简陋实在是令人叹为观止,但不断编写新函数并使用也确实增强了我们的代码编写能力。在编写贪吃蛇的过程中,需要思考并逐步完成游戏的各项功能,并在不断修改调试之中对程序代码进行纠错与完善,无形之中提升了c语言能力,也给我们带来无与伦比的成就感与收获感。简而言之,获益良多。

六:于文末附上完整代码

#include #include #include #include #include #include #define DOWN_WALL 20 #define RIGHT_WALL 58 typedef struct s_snake { int x; //蛇头横坐标 int y;//蛇头纵坐标 struct s_snake*next ; } Snake; void setpos(int x,int y); int HitWall(); int SelfBite(); int Move(); Snake *head, *end; Snake *p; int speed=310; int level=0, score=0; int foodx, foody; char key; void Welcome(); void DrawFrame(); void InitSnake(); void CreateFood(); void PlayGame(); void free_snake(Snake*head); char GetKeyBoard(); void Restart(); int main(){ GetKeyBoard(); ConsoleSettings(); Welcome(); DrawFrame(); InitSnake(); CreateFood(); PlayGame(); Restart(); free_snake(head); return 0; } void setpos( int x, int y){//设置光标 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),(COORD){ x,y }); } int HitWall(){ if(head->x==0||head->x==RIGHT_WALL||head->y==0||head->y==DOWN_WALL) { setpos(DOWN_WALL,14); printf("Game Over!"); return 1; } return 0; } int SelfBite(){ while(p->next!=NULL) { p=p->next; if(head->x==p->x&&head->y==p->y) {setpos(DOWN_WALL,14); printf("Game Over!"); return 1; system("cls"); main(); } } return 0; } void DrawFrame(){ int i=0; for(i=0;iy=15; end->next=NULL; for(i=1;ix=20+2*i; head->y=15; head->next=end; end=head; } while(end->next!=NULL) {setpos(end->x,end->y); printf("@"); end=end->next; } } void CreateFood(){ srand(time(0)); flag: while(1) {foody=rand()%(DOWN_WALL-1+1-1)+1; foodx=rand()%(RIGHT_WALL-2+1-3)+3; if(foodx%2==0) break; } p=head; while(1) { if(p->x==foodx&&p->y==foody) {goto flag; } if(p->next==NULL) {break; } p=p->next; } setpos(foodx,foody); printf("?"); } void PlayGame(){ int mv_ret=0; key='d'; while(1) {if((GetAsyncKeyState(0x57)&&0x8000)&&key!='s') {key='w'; } else if((GetAsyncKeyState(0x53)&&0x8000)&&key!='w') {key='s'; } else if((GetAsyncKeyState(0x44)&&0x8000)&&key!='a') {key='d'; } else if((GetAsyncKeyState(0x41)&&0x8000)&&key!='d') {key='a'; } else if (GetAsyncKeyState(0x50)&&0x8000) {while(p->next!=NULL) p=p->next; setpos(p->x,p->y); printf("@"); while(1) { Sleep(100); if(GetAsyncKeyState(0x50)&&0x8000) {break; } } setpos(p->x,p->y); printf(" "); } else if(GetAsyncKeyState(0x51)&&0x8000) {return ; } if(score==level&&speed>10) {speed-=10; level+=30; } mv_ret=Move(); if(mv_ret==1) {break; } } } int Move() {int ret; if((key!='a')&&(key!='w')&&(key!='s')&&(key!='d')) {return 0; } ret=HitWall(); ret+=SelfBite(); if(ret==1) { return 1; } p=(Snake*)malloc(sizeof(Snake)); p->next=head; switch(key) {case'd': p->x=head->x+2; p->y=head->y; break; case'w': p->x=head->x; p->y=head->y-1; break; case's': p->x=head->x; p->y=head->y+1; break; case'a': p->x=head->x-2; p->y=head->y; break; } setpos(p->x,p->y); printf("@"); head=p; Sleep(speed); if(p->x==foodx&&p->y==foody) { CreateFood(); score+=10; setpos(60,7); printf("得分%d",score); } else{ while(p->next->next!=NULL) p=p->next; setpos(p->x,p->y); printf(" "); free(p->next); p->next=NULL; p=head; } return 0; } void Welcome() {DrawFrame(); setpos(25,8); printf("press any key to start!"); while((getch())==1) continue ; system("cls"); } char GetKeyBoard() {//获取键盘输入 char key=0; if(_kbhit()){ key=_getch(); } return key; } void ConsoleSettings(){//设置控制台字体 CONSOLE_CURSOR_INFO cursor; cursor.bVisible=FALSE; cursor.dwSize=sizeof(cursor); HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorInfo(handle, &cursor); CONSOLE_FONT_INFOEX cfi; cfi.cbSize=sizeof cfi; cfi.nFont=0; cfi.dwFontSize.X=20; cfi.dwFontSize.Y=20; cfi.FontFamily=FF_DONTCARE; cfi.FontWeight=FW_NORMAL; wcscpy_s(cfi.FaceName,_countof(cfi.FaceName),L"Raster"); SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE),FALSE,&cfi); } void free_snake(Snake*head) {if(head==NULL||head->next==NULL){ return; } while((p=head)!=NULL) {head=head->next; free(p); } } void Restart(){ while(1) { setpos(60,8); printf("Try again? y/n"); flag: getch(); if(getch()=='y') { system("cls"); score=0; main(); } if(getch()=='n') { exit (0); } else {setpos(60,9); printf("please choose one right key"); goto flag; } } }

感谢观看!take care of yourself and be well!



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3