贪吃蛇 队列 c语言代码,用队列写贪吃蛇(C语言版)

原理分析: 队列的特点就是先进先出(FIFO),我们就是利用他的这个特点来模拟一条贪吃蛇。我们首先考虑一下这个游戏需要哪些元素,然后怎么用终端模拟这些元素。

蛇:蛇在终端上的表示就是很多个字符连在一起就是蛇,比如: @@@@ 或者 2222222 都是一条蛇。然而,队列是有队头和队尾之分,那么用它表示的蛇也必须有蛇头和蛇尾。这个点很重要,就是需要用队尾表示蛇头,因为队列是先进先出的数据结构,蛇在移动的时候,他的尾巴要消失,然后需要在移动的方向上加上一段蛇,这样就能使蛇移动。在数据结构上来说就是队列的一个元素先出队列,然后再将一个元素人队。如图:

蛇的移动:

蛇一:

0818b9ca8b590ca3270a3433284dd417.png

蛇二: 蛇一向下移动

尾巴消失

0818b9ca8b590ca3270a3433284dd417.png

然后在下方添加一段蛇,这样蛇就向下移动了

0818b9ca8b590ca3270a3433284dd417.png

蛇吃到食物:

看了蛇的移动,那么蛇吃到食物比移动更容易,直接将一段蛇添加到原来的蛇上面就好了,在数据结构上就是表现为一个元素进入队列的操作。如图:

蛇向下走一步就可以吃到食物了。

0818b9ca8b590ca3270a3433284dd417.png

蛇吃到食物,变成三个节点。

0818b9ca8b590ca3270a3433284dd417.png

以上是蛇正常游戏,那么接下来就是游戏结束的条件。

撞到边框: 边框就用坐标表示,然后在对应的坐标上输出字符。

撞到自己: 每走一步,就判断头的坐标是否与原来蛇的节点坐标重复,若重复则游戏结束。

以下是参考代码:

#include

#include

#include

#include

#include

#include //引用头文件

enum Diriction{

UP,DOWN,LEFT,RIG};

struct Snake{ //定义蛇的节点

int x;

int y;

struct Snake *next;

};

struct Serpent{

enum Diriction dir; //定义蛇的方向

int lenght; //定义蛇的长度

};

struct Food{

int a;

int b;

}; //定义食物的坐标

//全局变量,在全体函数都可以用的到的变量,在这只声明一次就可以了

struct Snake *head,*tail; //定义蛇头和蛇尾的指针,就相当于队列的头和尾,head是队头,tail是队尾

struct Food *food; //定义食物

struct Serpent *serpent; //定义蛇的方向和长度

int getit=0; //判断是否得分,若是则可投放食物

//声明以下可用到的函数

void Gotoxy(); //定位光标

void Initsnake(); //初始化蛇

void Home(); //绘制边框

void Initfood(); //投放食物

void Keyhit(); //键盘控制

void Move(); //蛇身的移动

void Addtail(int x, int y); //增加队尾长度

void clearhead(); //清除上次的队头

void Print(); //打印画面

int main()

{

Initsnake(); //初始化蛇

while(1)

{

Keyhit(); //键盘输入

Move(); //移动

system("cls");

Print(); //打印

Sleep(100); //每隔100毫秒刷新游戏界面

};

return 0;

}

void Gotoxy(int x, int y) //定位光标,网上搜的

{

COORD pos;

pos.X = x - 1;

pos.Y = y - 1;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);

}

void Initsnake()

{

int i;

head=tail=(struct Snake*)malloc(sizeof(struct Snake)); //初始化队列

food=(struct Food*)malloc(sizeof(struct Food));

serpent=(struct Serpent*)malloc(sizeof(struct Snake)); //为全局变量开辟内存

head->next=NULL;

serpent->dir=RIG;

serpent->lenght=4;

for(i=0;ilenght;i++)

Addtail(10+i,10);

Initfood(); //初始化食物

}

void Home()

{

int a;

for(a=0;a<31;a++) //30*16

printf("%c", 3);

printf("\n");

for(a=0;a<16;a++)

printf("%c %c\n",3,3);

for(a=0;a<31;a++)

printf("%c", 3); //直接打印边框

}

void Initfood() //投放食物

{

int m=1;

getit=0;

struct Snake *q=head; //将蛇头附给指针q

srand((unsigned)time(NULL)); //以时间为种子产生随机数

food->a=rand()%(30-2)+2; //这是随机数,并限制了食物的出现范围

food->b=rand()%(15-2)+2;

while(q!=tail) //遍历蛇,判断是否食物是否在蛇身上??

{

if(q->x==food->a &&q->y==food->b) //蛇身上rice=0,食物无效

{

m=0;

break;}

q=q->next;

}

if(m==0)

Initfood(); //食物无效,隐含rice==0,又调用一次

}

void Keyhit()

{

char n;

if(_kbhit()) //无阻隔输入

{

n=_getch(); //警告 1 warning C4996: 'getch': The POSIX name for this item is deprecated.

switch(n)

{

case 'w':

{

if(serpent->dir==DOWN) //判断输入方向与蛇的方向是否相同,是则输入无效

break;

else

serpent->dir=UP;break;

}

case 's':

{

if(serpent->dir==UP)

break;

else

serpent->dir=DOWN;break;

}

case 'a':

{

if(serpent->dir==RIG)

break;

else

serpent->dir=LEFT;break;

}

case 'd':

{

if(serpent->dir==LEFT)

break;

else

serpent->dir=RIG;break;

}

}

}

}

void Move()

{

int a=0;

struct Snake *p;

struct Snake *q;

p=tail; //将队尾附给p

switch(serpent->dir)

{

case UP:

Addtail(p->x,p->y-1);break;

//添加队尾

case DOWN:

Addtail(p->x,p->y+1);break;

case LEFT:

Addtail(p->x-1,p->y);break;

case RIG:

Addtail(p->x+1,p->y);break;

}

if(tail->x==food->a &&tail->y==food->b) //吃到食物

{

serpent->lenght++; //记分

getit=1;

}

if(getit!=1) //如果没吃到食物清除队尾

clearhead();

p=tail;

q=head;

while(q!=tail) //判断是否撞到自己

{

if(q->x==p->x &&q->y==p->y)

exit(0);

q=q->next;

}

if(tail->x>30 || tail->y>17||tail->x<=1 ||tail->y<=1) //超边框退出

exit(0);

}

void Addtail(int x,int y) //压入队

{

struct Snake *newnode=(struct Snake*)malloc(sizeof(struct Snake));

newnode->x=x;

newnode->y=y;

newnode->next=NULL;

tail->next=newnode;

tail=newnode; //将新的节点附给队尾

}

void clearhead() //这是清除队尾

{

struct Snake *p;

p=head;

p=p->next;

head=p;

}

void Print() //打印画面

{

Home();

Gotoxy(food->a,food->b); //打印食物

printf("%c", 4);

struct Snake *q;

q=head;

Gotoxy(tail->x,tail->y);

printf("%c",5);

while(q!=tail) //打印蛇

{

Gotoxy(q->x,q->y);

printf("%c",2);

q=q->next;

}

if(getit==1) //判断食物是否被吃

Initfood();

Gotoxy(30,20);

printf("score :%d", serpent->lenght-4); //分数

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的贪吃蛇游戏的C语言代码示例: ``` #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> #define MAX_X 20 #define MAX_Y 20 int x, y, foodX, foodY, score; int gameOver; int tailX[100], tailY[100]; int nTail; enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN }; enum eDirection dir; void Setup() { gameOver = 0; dir = STOP; x = MAX_X / 2; y = MAX_Y / 2; foodX = rand() % MAX_X; foodY = rand() % MAX_Y; score = 0; } void Draw() { system("cls"); for (int i = 0; i < MAX_X + 2; i++) printf("#"); printf("\n"); for (int i = 0; i < MAX_Y; i++) { for (int j = 0; j < MAX_X; j++) { if (j == 0) printf("#"); if (i == y && j == x) printf("O"); else if (i == foodY && j == foodX) printf("F"); else { int printTail = 0; for (int k = 0; k < nTail; k++) { if (tailX[k] == j && tailY[k] == i) { printf("o"); printTail = 1; } } if (!printTail) printf(" "); } if (j == MAX_X - 1) printf("#"); } printf("\n"); } for (int i = 0; i < MAX_X + 2; i++) printf("#"); printf("\n"); printf("Score: %d\n", score); } void Input() { if (_kbhit()) { switch (_getch()) { case 'a': dir = LEFT; break; case 'd': dir = RIGHT; break; case 'w': dir = UP; break; case 's': dir = DOWN; break; case 'x': gameOver = 1; break; } } } void Logic() { int prevX = tailX[0]; int prevY = tailY[0]; int prev2X, prev2Y; tailX[0] = x; tailY[0] = y; for (int i = 1; i < nTail; i++) { prev2X = tailX[i]; prev2Y = tailY[i]; tailX[i] = prevX; tailY[i] = prevY; prevX = prev2X; prevY = prev2Y; } switch (dir) { case LEFT: x--; break; case RIGHT: x++; break; case UP: y--; break; case DOWN: y++; break; default: break; } if (x > MAX_X || x < 0 || y > MAX_Y || y < 0) gameOver = 1; for (int i = 0; i < nTail; i++) { if (tailX[i] == x && tailY[i] == y) gameOver = 1; } if (x == foodX && y == foodY) { score += 10; foodX = rand() % MAX_X; foodY = rand() % MAX_Y; nTail++; } } int main() { srand(time(NULL)); Setup(); while (!gameOver) { Draw(); Input(); Logic(); _sleep(100); } return 0; } ``` 代码中使用了 `conio.h` 库中的 `_kbhit()` 和 `_getch()` 函数来实现键盘输入的检测和读取,可以使用其他库或者 API 来完成相同的功能。此外,代码中使用了数组来保存蛇的身体坐标,以及一个枚举类型来表示蛇的运动方向。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值