最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言循環(huán)鏈表實現(xiàn)貪吃蛇游戲

 更新時間:2020年11月08日 17:03:35   作者:yzw丶  
這篇文章主要為大家詳細介紹了C語言循環(huán)鏈表實現(xiàn)貪吃蛇,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了C語言表實現(xiàn)貪吃蛇游戲的具體代碼,供大家參考,具體內(nèi)容如下

總體思想

利用循環(huán)鏈表將一條蛇的坐標進行存儲,然后利用gotoxy()函數(shù)(可以將光標定位到指定的位置),此時根據(jù)蛇的坐標進行輸出“@”,輸出多幾個既可以產(chǎn)生一條蛇。通過遍歷循環(huán)鏈表進行蛇的移動,對循環(huán)鏈表的插入元素,產(chǎn)生蛇變長的效果。下面為各功能實現(xiàn)的函數(shù)

1.貪吃蛇地圖函數(shù)map()
2.蛇的移動move(),up(),left()等函數(shù)
3.產(chǎn)生食物food()和吃到食物eat_food()
4.蛇吃到食物時產(chǎn)生的變長效果snake_link()函數(shù)
5.判斷蛇的死亡,分別為撞墻hit_wall()和自殺suicide()

1.貪吃蛇地圖函數(shù)map()

游戲地圖采用的是應該封閉的區(qū)域,采用一個數(shù)組a[25][50],將此數(shù)組初始化為0,將游戲墻的邊緣賦值為1,當數(shù)組為0,輸出" ",數(shù)組為1,輸出“#”,產(chǎn)生一個地圖。

代碼如下:

void map() //創(chuàng)建蛇的地圖
{
 int a[25][50] = {0};
 int i,j;
 for(i = 0; i < 50; i++)
 {
 a[0][i] = 1;
 a[24][i] =1;
 }
 for(i = 0; i < 25; i++)
 {
 a[i][0] = 1;
 a[i][49] =1;
 }
 for(i = 0; i < 25; i++)
 for(j = 0; j < 50; j++)
 {
  if(j%50 == 0)
  printf("\n");
  if(a[i][j] == 0)
  {
  printf(" ");
  }
  else
  {
  printf("#");
  }
 }
}

2.蛇的移動move(),up(),left()等函數(shù)

move()函數(shù)主要對蛇的上下左右進行更改在此采用switch函數(shù)進行解決(下面代碼中ch為全局變量)
代碼如下

void move(struct snake *p) //蛇的移動函數(shù)
{
 while(1)
 {
 ch = getch();
 switch(ch)
 {
 case 'W':p = up(p);break;
 case 'A':p = left(p);break;
 case 'D':p = right(p);break;
 case 'S':p = down(p);break;
 }
 }
}

讓蛇動起來的即我們主要對蛇的坐標進行更改,此時蛇頭移動一次我們就利用gotoxy()函數(shù)進行輸出“@”,然后在蛇尾輸出“ ”,循環(huán)往復就可以產(chǎn)生蛇移動的效果,蛇的上下左右則只需在移動一個方向的時候?qū)我坏淖鴺藊或y進行更改,然后對更改的坐標保存進循環(huán)鏈表即可。移動函數(shù)則主要有up(),left()等,因為做法差不多,在此只對up()函數(shù)進行展示

代碼如下

struct snake *up(struct snake *p) //向上移動
{

 int x;
 int y;
 x = p->pre->x;   //將蛇頭坐標賦值給x,y
 y = p->pre->y;
 while(p)   //對循環(huán)鏈表的遍歷,即蛇的遍歷
 {
 Sleep(SNAKE_SPEED); //蛇移動的速度
 y--;   //向上移動則只需將縱坐標進行減,就可以實現(xiàn)蛇向上移動的效果
 gotoxy(p->x,p->y);  //定位到蛇尾,輸出“ ”即蛇尾消失
 printf(" ");
 gotoxy(x, y);  //定位到蛇頭輸出,"@",結(jié)合上面的蛇尾消失又進行蛇頭打印,產(chǎn)生蛇移動的效果
 printf("@");
 suicide(p,x,y);  //判斷蛇頭是否撞到蛇身
 p = p->next;  //將蛇頭的坐標變?yōu)橄乱粋€
 p->pre->x = x;  //此時將前一個蛇頭變成蛇尾,通過不斷的遍歷產(chǎn)生不斷移動的效果
 p->pre->y = y;
 food();   //產(chǎn)生食物
 eat_food(p,x,y);  //判斷是否吃到食物
 hit_wall(y);  //判斷是否撞墻
 if(kbhit()) break; //判斷是否有按鍵輸入,有就進行蛇移動方向的改變
 }

 return p;
}

3.產(chǎn)生食物food()和吃到食物eat_food()

食物和吃到食物,產(chǎn)生食物則采用了產(chǎn)生隨機數(shù),產(chǎn)生一個食物的x,y坐標分別存放在全局變量food_xy[2]數(shù)組里面,最后利用gotoxy(food_xy[0],food_xy[1])隨機產(chǎn)生食物
代碼如下

void food()   //產(chǎn)生食物
{
 int i;
 if(!flag)   //根據(jù)flag的值來判斷地圖上是否有食物
 {
 srand( (unsigned)time( NULL ) );
 for( i = 0; i < 2; i++ ) //對food_(x,y)來隨機賦值
 {
  food_xy[i] = rand()%24+2;
  while(food_xy[0] == 1 || food_xy[0] == 25) //這兩個while為了防止食物
  food_xy[0] = rand()%24+2;  //的坐標與地圖的邊緣重疊
  while(food_xy[1] >= 49 || food_xy[1] == 1)
  food_xy[1] =rand()%24+2;
 }
 gotoxy(food_xy[0],food_xy[1]); //打印食物
 printf("*");
 flag = 1;
 }
}

吃到食物eat_food(),則我們只需判斷蛇頭是否和食物的坐標重疊,若重疊則表明蛇吃到了食物

代碼如下

void eat_food(struct snake *p,int x, int y)  //蛇吃到食物,即主要是對蛇頭的x,y坐標和
{       //food_xy的坐標進行匹配對比,若相同即調(diào)
 if(x == food_xy[0] && y == food_xy[1])  //snake_link函數(shù)即可
 {
 p = snake_link(p);
 flag = 0;     //表明食物被吃,準備重新產(chǎn)生食物
 printSnake(p);
 gotoxy(8,0);
 score = score + 1;    //得分
 printf("%d",score);
 }
}

4.蛇吃到食物時產(chǎn)生的變長效果snake_link()函數(shù)

蛇的變長,當蛇吃到食物的時候,此時我們將食物的坐標變成蛇頭,然后進行重新的打印蛇,即可以有蛇變成的效果產(chǎn)生,實質(zhì)為對循環(huán)鏈表進行元素的插入。

即通過這樣將食物的坐標插進去循環(huán)鏈表,達到蛇變成的效果
代碼如下

struct snake *snake_link(struct snake *p) //蛇的連接
{
 struct snake *q;
 q = (struct snake *)malloc(sizeof(struct snake)); //即主要是實現(xiàn)了對循環(huán)鏈表的插入元素,再
 q->x = food_xy[0];    //進行打印蛇,即可有吃到食物蛇變長的結(jié)果
 q->y = food_xy[1];
 q->pre = p->pre;
 p->pre->next = q;
 p->pre = q;
 q->next = p;
 return p;
}

5.判斷蛇的死亡,分別為撞墻hit_wall()和自殺suicide()

撞墻,則只需判斷蛇頭的單一坐標x軸或者y軸是否與墻壁的坐標是否相等,若相等則說明蛇撞墻了
代碼如下

void hit_wall(int n) //判斷蛇是否撞墻,即對蛇的單一坐標x或者y進行判斷,若等于墻壁的值,即游戲結(jié)束
{
 if(ch == 'W'|| ch == 'S' )
 if(n == 1 || n == 25)  //墻壁的坐標值
 {
  gotoxy(0,26);
  printf("游戲結(jié)束!");
  printf("你的得分:%d",score);
  exit(0);
 }
 if(ch == 'A'|| ch == 'D' )
 if(n == 0 || n == 49)
 {
  gotoxy(0,26);
  printf("游戲結(jié)束!");
  printf("你的得分:%d",score);
  exit(0);
 }
}

自殺suicide()即蛇頭是否有撞到了蛇身,做法是把蛇頭的坐標拿出來,與蛇身的坐標進行對比如果相等,說明蛇頭撞到了蛇身,本質(zhì)上是循環(huán)鏈表的值進行匹配,遍歷

代碼如下

void suicide(struct snake *p, int x, int y) //自殺,即撞到自己本身的時候游戲結(jié)束
{
 struct snake *q;    //把蛇頭坐標傳遞進來,然后與其自己身體坐標做對比若有相等則表明,蛇頭撞到了蛇身
 q = p;
 while(q != p->next)   //即對循環(huán)鏈表的遍歷匹配
 {
 if(p->x == x && p->y == y)
 {
  gotoxy(0,26);
  printf("游戲結(jié)束!");
  printf("你的得分:%d",score);
  exit(0);
 }
 else
  p = p->next;
 }
}

到此蛇的基本功能已經(jīng)講完,以下是全部代碼。

全部代碼如下

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define SNAKE_SPEED 200 //蛇移動的速度
int score = 0;  //成績得分
int flag = 0;  //用于判斷地圖上是否存在食物,0為不存在食物
int food_xy[2];  //定位食物的位置
char ch;  //用來決定蛇的移動方向
struct snake //定義一條循環(huán)鏈表的蛇
{
 int x;
 int y;
 struct snake *next;
 struct snake *pre;
};

void HideCursor()//把蛇移動的時候產(chǎn)生的光標進行隱藏,隱藏光標函數(shù)
{
 CONSOLE_CURSOR_INFO cursor;
 cursor.bVisible = FALSE;
 cursor.dwSize = sizeof(cursor);
 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
 SetConsoleCursorInfo(handle, &cursor);
}

void gotoxy(int x, int y) //定位光標函數(shù),用來實現(xiàn)蛇的移動,和食物的出現(xiàn)(傳送x,y可以將光標定位到x,y)
{
 HideCursor();
 COORD coord = {x,y};
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void map() //創(chuàng)建蛇的地圖
{
 int a[25][50] = {0};
 int i,j;
 for(i = 0; i < 50; i++)
 {
 a[0][i] = 1;
 a[24][i] =1;
 }
 for(i = 0; i < 25; i++)
 {
 a[i][0] = 1;
 a[i][49] =1;
 }
 for(i = 0; i < 25; i++)
 for(j = 0; j < 50; j++)
 {
  if(j%50 == 0)
  printf("\n");
  if(a[i][j] == 0)
  {
  printf(" ");
  }
  else
  {
  printf("#");
  }
 }
}

struct snake *createSnake() //給蛇進行初始化,構(gòu)建一條蛇,本質(zhì)為循環(huán)鏈表
{
 int i;
 struct snake *head,*p,*q;
 p = q = (struct snake *)malloc(sizeof(struct snake));
 head = NULL;
 head = p;
 head->pre = NULL;
 for( i = 0; i < 5; i++)
 {
 p->x = 25 - i;
 p->y = 13;
 p->pre = head->pre;
 head->pre = p;
 q->next = p;
 q = p;
 p = (struct snake *)malloc(sizeof(struct snake));
 }
 q->next = head;
 return head;

}

void printSnake(struct snake *p) //打印蛇,利用gotoxy()來對蛇進行打印,只需遍歷一次循環(huán)鏈表即可將坐標可視化為一條蛇
{
 struct snake *q;
 q = p;
 while(q != p->next)  //循環(huán)鏈表的遍歷
 {
 gotoxy(p->x,p->y);  //根據(jù)坐標和定位光標函數(shù)來打@,實現(xiàn)輸出蛇
 printf("@");
 p = p->next;
 }
 gotoxy(p->x,p->y);
 printf("@");
 gotoxy(0,0);
 printf("你的得分:");  //初始化得分
}

void food()   //產(chǎn)生食物
{
 int i;
 if(!flag)   //根據(jù)flag的值來判斷地圖上是否有食物
 {
 srand( (unsigned)time( NULL ) );
 for( i = 0; i < 2; i++ ) //對food_(x,y)來隨機賦值
 {
  food_xy[i] = rand()%24+2;
  while(food_xy[0] == 1 || food_xy[0] == 25) //這兩個while為了防止食物的坐標與地圖的邊緣重疊
  food_xy[0] = rand()%24+2;
  while(food_xy[1] >= 49 || food_xy[1] == 1)
  food_xy[1] =rand()%24+2;
 }
 gotoxy(food_xy[0],food_xy[1]); //打印食物
 printf("*");
 flag = 1;
 }
}

struct snake *snake_link(struct snake *p) //蛇的連接
{
 struct snake *q;
 q = (struct snake *)malloc(sizeof(struct snake)); //即主要是實現(xiàn)了對循環(huán)鏈表的插入元素,再進行打印蛇,即可有吃到食物蛇變長的結(jié)果
 q->x = food_xy[0];
 q->y = food_xy[1];
 q->pre = p->pre;
 p->pre->next = q;
 p->pre = q;
 q->next = p;
 return p;
}

void eat_food(struct snake *p,int x, int y)  //蛇吃到食物,即主要是對蛇頭的x,y坐標和food_xy的坐標進行匹配對比,若相同即調(diào)用snake_link函數(shù)即可
{
 if(x == food_xy[0] && y == food_xy[1])
 {
 p = snake_link(p);
 flag = 0;
 printSnake(p);
 gotoxy(8,0);
 score = score + 1;
 printf("%d",score);
 }
}

void hit_wall(int n) //判斷蛇是否撞墻,即對蛇的單一坐標x或者y進行判斷,若等于墻壁的值,即游戲結(jié)束
{
 if(ch == 'W'|| ch == 'S' )
 if(n == 1 || n == 25)
 {
  gotoxy(0,26);
  printf("游戲結(jié)束!");
  printf("你的得分:%d",score);
  exit(0);
 }
 if(ch == 'A'|| ch == 'D' )
 if(n == 0 || n == 49)
 {
  gotoxy(0,26);
  printf("游戲結(jié)束!");
  printf("你的得分:%d",score);
  exit(0);
 }
}


void suicide(struct snake *p, int x, int y) //自殺,即撞到自己本身的時候游戲結(jié)束
{
 struct snake *q;    //把蛇頭坐標傳遞進來,然后與其自己身體坐標做對比若有相等則表明,蛇頭撞到了蛇身
 q = p;
 while(q != p->next)   //即對循環(huán)鏈表的遍歷匹配
 {
 if(p->x == x && p->y == y)
 {
  gotoxy(0,26);
  printf("游戲結(jié)束!");
  printf("你的得分:%d",score);
  exit(0);
 }

 else
  p = p->next;
 }
}

struct snake *up(struct snake *p) //向上移動
{

 int x;
 int y;
 x = p->pre->x;   //將蛇頭坐標賦值給x,y
 y = p->pre->y;
 while(p)   //對循環(huán)鏈表的遍歷,即蛇的遍歷
 {

 Sleep(SNAKE_SPEED); //蛇移動的速度
 y--;   //向上移動則只需將縱坐標進行減,就可以實現(xiàn)蛇向上移動的效果
 gotoxy(p->x,p->y);  //定位到蛇尾,輸出“ ”即蛇尾消失
 printf(" ");
 gotoxy(x, y);  //定位到蛇頭輸出,"@",結(jié)合上面的蛇尾消失又進行蛇頭打印,產(chǎn)生蛇移動的效果
 printf("@");
 suicide(p,x,y);  //判斷蛇頭是否撞到蛇身
 p = p->next;  //將蛇頭的坐標變?yōu)橄乱粋€
 p->pre->x = x;  //此時將前一個蛇頭變成蛇尾,通過不斷的遍歷產(chǎn)生不斷移動的效果
 p->pre->y = y;
 food();   //產(chǎn)生食物
 eat_food(p,x,y);  //判斷是否吃到食物
 hit_wall(y);  //判斷是否撞墻
 if(kbhit()) break; //判斷是否有按鍵輸入,有就進行蛇移動方向的改變
 }

 return p;


}

struct snake *left(struct snake *p) //向左移動
{
 int x;
 int y;
 x = p->pre->x;
 y = p->pre->y;
 while(p)
 {

 Sleep(SNAKE_SPEED);
 x--;
 gotoxy(p->x,p->y);
 printf(" ");
 gotoxy(x, y);
 printf("@");
 suicide(p,x,y);
 p = p->next;
 p->pre->x = x;
 p->pre->y = y;
 food();
 eat_food(p,x,y);
 hit_wall(x);
 if(kbhit()) break;
 }
 return p;
}

struct snake *down(struct snake *p) //向下移動
{
 int x;
 int y;
 x = p->pre->x;
 y = p->pre->y;
 while(p)
 {

 Sleep(SNAKE_SPEED);
 y++;
 gotoxy(p->x,p->y);
 printf(" ");
 gotoxy(x, y);
 printf("@");
 suicide(p,x,y);
 p = p->next;
 p->pre->x = x;
 p->pre->y = y;
 food();
 eat_food(p,x,y);
 hit_wall(y);
 if(kbhit()) break;
 }
 return p;
}

struct snake *right(struct snake *p) //向右移動
{
 int x;
 int y;
 x = p->pre->x;
 y = p->pre->y;
 while(p)
 {

 Sleep(SNAKE_SPEED);
 x++;
 gotoxy(p->x,p->y);
 printf(" ");
 gotoxy(x, y);
 printf("@");
 suicide(p,x,y);
 p = p->next;
 p->pre->x = x;
 p->pre->y = y;
 food();
 eat_food(p,x,y);
 hit_wall(x);
 if(kbhit()) break;
 }
 return p;


}
void move(struct snake *p) //蛇的移動函數(shù)
{
 while(1)
 {
 ch = getch();
 switch(ch)
 {
 case 'W':p = up(p);break;
 case 'A':p = left(p);break;
 case 'D':p = right(p);break;
 case 'S':p = down(p);break;
 }
 }
}
int main()
{
 struct snake *p;
 map(); //產(chǎn)生地圖
 p = createSnake(); // 初始化蛇
 printSnake(p); // 打印蛇
 move(p); //移動蛇

 return 0;
}

更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:

C++經(jīng)典小游戲匯總

python經(jīng)典小游戲匯總

python俄羅斯方塊游戲集合

JavaScript經(jīng)典游戲 玩不停

java經(jīng)典小游戲匯總

javascript經(jīng)典小游戲匯總

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • C++開發(fā)protobuf動態(tài)解析工具

    C++開發(fā)protobuf動態(tài)解析工具

    這篇文章主要為大家介紹了C++開發(fā)protobuf動態(tài)解析工具實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • C語言超詳細講解指針的使用

    C語言超詳細講解指針的使用

    C語言這門課程在計算機的基礎教學中一直占有比較重要的地位,然而要想突破C語言的學習,對指針的掌握是非常重要的,本文將具體針對指針的基礎做詳盡的介紹
    2022-05-05
  • C++ QT智能指針的使用詳解

    C++ QT智能指針的使用詳解

    這篇文章主要介紹了C++ QT智能指針的使用,Qt是一個跨平臺的C++框架,主要用來開發(fā)圖形用戶界面程序,也可以開發(fā)不帶界面的命令行程序,下面我們來了解QT智能指針是如何使用的
    2023-12-12
  • 適合初學者的C語言字符串講解

    適合初學者的C語言字符串講解

    字符串主要用于編程,概念說明、函數(shù)解釋、用法詳述見正文,這里補充一點:字符串在存儲上類似字符數(shù)組,所以它每一位的單個元素都是可以提取的
    2022-04-04
  • 使用C語言操作文件的基本函數(shù)整理

    使用C語言操作文件的基本函數(shù)整理

    這篇文章主要介紹了使用C語言操作文件的基本函數(shù)整理,包括創(chuàng)建和打開以及關閉文件的操作方法,需要的朋友可以參考下
    2015-08-08
  • Qt實現(xiàn)TCP網(wǎng)絡編程

    Qt實現(xiàn)TCP網(wǎng)絡編程

    這篇文章主要為大家詳細介紹了Qt實現(xiàn)TCP網(wǎng)絡編程,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 淺談C++基類的析構(gòu)函數(shù)為虛函數(shù)

    淺談C++基類的析構(gòu)函數(shù)為虛函數(shù)

    本文重點:應該為多態(tài)基類聲明虛析構(gòu)器。一旦一個類包含虛函數(shù),它就應該包含一個虛析構(gòu)器。如果一個類不用作基類或者不需具有多態(tài)性,便不應該為它聲明虛析構(gòu)器。
    2015-10-10
  • 詳解原碼、反碼與補碼存儲與大小

    詳解原碼、反碼與補碼存儲與大小

    這篇文章主要介紹了詳解原碼、反碼與補碼存儲與大小的相關資料,需要的朋友可以參考下
    2017-06-06
  • C語言與java語言中關于二維數(shù)組的區(qū)別

    C語言與java語言中關于二維數(shù)組的區(qū)別

    這篇文章主要介紹了C語言與java語言中關于二維數(shù)組的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vscode 配置 C/C++編譯環(huán)境(完整教程)

    vscode 配置 C/C++編譯環(huán)境(完整教程)

    這篇文章主要介紹了vscode 配置 C/C++編譯環(huán)境(完整教程),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09

最新評論

岱山县| 柳江县| 华蓥市| 梨树县| 镇赉县| 乌兰浩特市| 黔南| 五莲县| 郸城县| 天台县| 广南县| 磐安县| 绥宁县| 巫溪县| 邳州市| 苏州市| 舞钢市| 井研县| 玉树县| 安泽县| 两当县| 宝坻区| 金昌市| 常熟市| 泰顺县| 枞阳县| 黑龙江省| 双鸭山市| 南城县| 突泉县| 凤庆县| 甘孜县| 霍林郭勒市| 随州市| 海伦市| 恭城| 玉门市| 桃源县| 武强县| 玉溪市| 白城市|