C語言實現(xiàn)鏈表貪吃蛇
本文實例為大家分享了C語言實現(xiàn)貪吃蛇的具體代碼,供大家參考,具體內(nèi)容如下
用C語言鏈表寫的貪吃蛇(程序設計時做的,做的不好大佬勿噴)

借助游戲內(nèi)容分析貪吃蛇所需的功能主要包括這幾塊:
1.移動光標模塊
2.打印地圖模塊和基本規(guī)則信息
讀取最高分文件
3.打印初始蛇模塊
打印時給予蛇的初始移動方向
4.產(chǎn)生食物模塊
1)、保證食物在地圖內(nèi)產(chǎn)生
2)、保證食物不能出現(xiàn)在蛇體
5.蛇的生命狀態(tài)判斷模塊
1)、撞墻導致死亡
2)、頭撞身體部位死亡
6.運行模塊
1)、讓蛇移動
2)、根據(jù)按鍵來改變蛇的移動方向
3)、對待分數(shù)的增加游戲難度的增加
4)、蛇在吃食物后分數(shù)的增加
7.結束模塊
在遇到撞墻或者撞自己部位死亡時結束程序,并進行分數(shù)與歷史最高分作比較,最終達到最高分的更新
以下為代碼
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>//控制臺輸入和輸出
#include <windows.h>//窗口函數(shù)
#include <time.h>
#define W 1//蛇的運動方向W:上 S:下 A: 左 D:右
#define S 2
#define A 3
#define D 4
/*
定義全局變量
*/
typedef struct{
int x;
int y;
}place;//定義坐標結構體
typedef struct ZB{
place data;
struct ZB *next;
}snake;//定義蛇的鏈表
/*
定義全局鏈表
*/
snake *head,*p,*q,*h;//
place food;//定義食物坐標
int score=0,bestscore,game_flag=0,ch,sleep=400;//定義得分score死亡判斷game_flag方向判斷ch蛇的速度sleep
/*
函數(shù)聲明
*/
void gotoxy(int x,int y);//定位光標
void map_creat();//運用定位函數(shù)打印地圖
void ini_snack();//隨機產(chǎn)生蛇
void cre_food();//隨機產(chǎn)生食物
void live_jud_1();//判斷自己是否撞墻死亡
void live_jud_2();//判斷自己是否撞到自己
void move();//蛇的移動
void rungame();//游戲運行
void gameover();//游戲結束界面
void changch();//改變方向
int color(int c);//改顏色函數(shù)
/*
構建定位函數(shù)
*/
int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c); //更改文字顏色
return 0;
}
void gotoxy(int x,int y)//定位光標
{
COORD pos;
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
pos.X=x;
pos.Y=y;
SetConsoleCursorPosition(handle,pos);
}
/*
打印地圖
*/
void map_creat()//運用定位函數(shù)打印地圖
{
FILE *fp;//創(chuàng)建一個記錄最高分的文件
fp=fopen("score.1","r");
fscanf(fp,"%d",&bestscore);//讀取最高分
fclose(fp);
gotoxy(54,26);
printf("Your Best Score : %d\t", bestscore);//打印出最高分
int i,j;
for(i=0;i<48;i++)
{
gotoxy(i,0);
printf("#");
color(6);
gotoxy(i,26);
printf("#");
color(6);
}
for(j=0;j<26;j++)
{
gotoxy(0,j);
printf("#");
color(6);
gotoxy(48,j);
printf("#");
color(6);
}
gotoxy(54,10);
printf("游戲規(guī)則:");
gotoxy(54,12);
printf("向上移動:↑\n");
gotoxy(54,14);
printf("向下移動:↓\n");
gotoxy(54,16);
printf("向左移動:←\n");
gotoxy(54,18);
printf("向右移動:→\n");
gotoxy(54,20);
printf("吃一個食物分數(shù)加10");
gotoxy(54,22);
printf("按空格鍵暫停游戲");
gotoxy(54,24);
printf("按ESC直接結束游戲");
}
/*
構建初始蛇
*/
void ini_snack()//產(chǎn)生蛇
{
int i;
/*
采用尾插法構建蛇的鏈表初始長度設為二
*/
head=(snake *)malloc(sizeof(snake));
head->data.x=48/2;
head->data.y=26/2;
head->next=NULL;
h=head;
for(i=1;i<=2;i++)
{
p=(snake *)malloc(sizeof(snake));
p->data.x=48/2+i;
p->data.y=26/2;
h->next=p;
h=p;
}
p->next=NULL;
/*
將蛇打印出來
*/
h=head;
while(h!=NULL)
{
gotoxy(h->data.x,h->data.y);
color(5);
printf("@");
h=h->next;
}
ch=W;//蛇的初始方向
}
/*
隨機產(chǎn)生食物
*/
void cre_food()//隨機產(chǎn)生食物
{
srand((unsigned)time(NULL));//為了防止每次產(chǎn)生的隨機數(shù)相同,種子設置為time
/*
隨機產(chǎn)生食物
*/
food.x=rand()%(48-2)+1;
food.y=rand()%(26-2)+1;
while(p!=NULL)
{
/*
判斷食物是否與蛇重合,如果重合重新產(chǎn)生
*/
if(p->data.x==food.x&&p->data.y==food.y)
cre_food();
p=p->next;
}
gotoxy(food.x,food.y);
color(1);
printf("$");//打印食物
}
/*
判斷是否死亡
*/
void live_jud_1()//判斷自己是否撞墻死亡
{
if(head->data.x==0||head->data.x==48||head->data.y==0||head->data.y==26)//撞墻
{
game_flag=1;
gameover();
}
}
void live_jud_2()//判斷自己是否撞到自己
{
q=head->next;
while(q!=NULL)
{
if(head->data.x==q->data.x&&head->data.y==q->data.y)//撞自己
{
{
game_flag=2;
gameover();
}
break;
}
q=q->next;
}
}
/*
游戲進行界面
*/
void move()
{
snake *l;
live_jud_1();
l=(snake *)malloc(sizeof(snake));
/*
構建一個新的節(jié)點通,過新節(jié)點來表示下一次頭節(jié)點所在的位置
將新節(jié)點當作移動后的頭節(jié)點
如果新頭節(jié)點的坐標等于食物的坐標得分加10,食物的標志變?yōu)?
因為蛇的鏈表長度加了一,如果是移動的話找出尾節(jié)點并打印出 然后刪掉該尾節(jié)點
如果吃到了食物就直接將蛇打印出來
*/
if(ch==W)
{
l->data.x=head->data.x;
l->data.y=head->data.y-1;
if(l->data.x==food.x&&l->data.y==food.y)
{
l->next=head;
head=l;
q=head;
while(q!=NULL)//將蛇重新打印一邊
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
score+=10;
cre_food();//構建新的食物
}
else
{
l->next=head;
head=l;
q=head;
while(q->next->next!=NULL)
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
gotoxy(q->next->data.x,q->next->data.y);
printf(" ");//將蛇尾去掉
free(q->next);
q->next=NULL;
}
}
if(ch==A)
{
l->data.x=head->data.x-1;
l->data.y=head->data.y;
if(l->data.x==food.x&&l->data.y==food.y)
{
l->next=head;
head=l;
q=head;
while(q!=NULL)
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
score+=10;
cre_food();
}
else
{
l->next=head;
head=l;
q=head;
while(q->next->next!=NULL)
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
gotoxy(q->next->data.x,q->next->data.y);
printf(" ");
free(q->next);
q->next=NULL;
}
}
if(ch==S)
{
l->data.x=head->data.x;
l->data.y=head->data.y+1;
if(l->data.x==food.x&&l->data.y==food.y)
{
l->next=head;
head=l;
q=head;
while(q!=NULL)
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
score+=10;
cre_food();
}
else
{
l->next=head;
head=l;
q=head;
while(q->next->next!=NULL)
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
gotoxy(q->next->data.x,q->next->data.y);
printf(" ");
free(q->next);
q->next=NULL;
}
}
if(ch==D)
{
l->data.x=head->data.x+1;
l->data.y=head->data.y;
if(l->data.x==food.x&&l->data.y==food.y)
{
l->next=head;
head=l;
q=head;
while(q!=NULL)
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
score+=10;
cre_food();
}
else
{
l->next=head;
head=l;
q=head;
while(q->next->next!=NULL)
{
gotoxy(q->data.x,q->data.y);
color(5);
printf("@");
q=q->next;
}
gotoxy(q->next->data.x,q->next->data.y);
printf(" ");
free(q->next);
q->next=NULL;
}
}
live_jud_2();//判斷是否撞自己死亡
}
void rungame()//運行游戲
{
while(1)
{
gotoxy(54,8);
printf("Your Score:%d",score);
/*
以下確保不能向上運動時改方向為向下等情況
*/
if(GetAsyncKeyState(VK_UP)&&ch!=S)
ch=W;
else if(GetAsyncKeyState(VK_DOWN)&&ch!=W)
ch=S;
else if(GetAsyncKeyState(VK_LEFT)&&ch!=D)
ch=A;
else if(GetAsyncKeyState(VK_RIGHT)&&ch!=A)
ch=D;
/*
根據(jù)分數(shù)和Sleep函數(shù)來確定游戲難度
*/
if(score>=50&&score<100)
sleep=300;
else if(score>=100&&score<300)
sleep=250;
else if(score>=300)
sleep=200;
if(GetAsyncKeyState(VK_SPACE))//輸入space暫停游戲
{
while(1)
{
Sleep(300);
if(GetAsyncKeyState(VK_SPACE))
break;
}
}
else if (GetAsyncKeyState(VK_ESCAPE))//輸入ESC直接結束游戲
{
game_flag=3;
gameover();
}
Sleep(sleep);
move();
}
}
/*
游戲結束界面
*/
void gameover()//游戲結束界面
{
FILE *fp;
system("cls");//清屏
gotoxy(48/2,26/2-2);
printf("\tGame Over!!!");//打印出游戲結束界面
gotoxy(48/2,26/2);
if(game_flag==1)
printf("\t你撞墻了?。?!\n");
else if(game_flag==2)
printf("\t傻孩子!你不能吃你自己?。?!\n");
else if(game_flag==3)
printf("\t您已結束游戲!");
gotoxy(48/2,26/2+2);
printf("\tYour score:%d\n",score);//打印出得到的分數(shù)
if(score>bestscore)//如果此次游戲分數(shù)大于以前最高分
{
fp=fopen("score.1","w");
fprintf(fp,"%d",score);//將此次分數(shù)保存在最高分文件里
fclose(fp);
}
system("pause");
exit(0);
}
/*
主函數(shù)
*/
int main()
{
system("color 9");
map_creat();
ini_snack();
cre_food();
rungame();
return 0;
}
更多有趣的經(jīng)典小游戲實現(xiàn)專題,分享給大家:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
vscode配置遠程開發(fā)環(huán)境并遠程調試運行C++代碼的教程
這篇文章主要介紹了vscode配置遠程開發(fā)環(huán)境并遠程調試運行C++代碼的教程,本文通過截圖實例相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
C++異步操作future和aysnc與function和bind
這篇文章主要介紹了C++異步操作future和aysnc與function和bind,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09

