C语言实现贪吃蛇

  • C语言实现贪吃蛇代码

#include<stdio.h>
#include<string.h>
#include<time.h>
#include<conio.h>
#include<Windows.h>
#define up ‘w’
#define down ‘s’
#define left ‘a’
#define right ‘d’
#define quit ‘q’
//函数声明
void welcome(); //开始界面
void chose(); //选择难度
void creatmap(); //建造地图
void creatbar(); //创建障碍物
void gotoxy(int x, int y); //移动光标
void creatsnake(); //创建蛇的身体
void creatfood(); //随机产生食物
void creatpoint(); //随机创建奖励性食物
int keyboard(); //从键盘获得输入信号
void move_snake(); //蛇的移动
void eatfood(); //蛇吃到食物后身长
void snakebody(int a,int b); //蛇在移动中的坐标的变换
int endgame(); //判断游戏是否违反规则来结束游戏
void End(); //结束界面
//结构体
typedef struct snakes //蛇身结构体
{
int x;
int y;
struct snakes *next;
}snake;
struct foods //食物结构体
{
int x;
int y;
}food;
struct POINTS //奖励性食物结构体
{
int x;
int y;
}point;
struct bars //障碍物结构体
{
int x;
int y;
}bar;
//全局变量
snake *head,*tail;
int score = 0;
char key = 1; //key用来接收用户按下的按键
int speed=200,count=0; //speed为蛇的速度,count用来计算奖励性食物出现的次数
//主函数
int main()
{
welcome();
return 0;
}
//开始界面
void welcome()
{
system(“cls”); //清屏
int n;
gotoxy(43,10);
printf(“贪 吃 蛇”);
gotoxy(25, 22);
printf(“1.开始游戏”);
gotoxy(45, 22);
printf(“2.选择难度”);
gotoxy(65, 22);
printf(“3.退出游戏”);
gotoxy(40,27);
printf(“请选择 1 2 3:”);
scanf("%d", &n);
system(“cls”);
switch (n)
{
case 1:
creatmap();
creatsnake();
creatfood();
creatpoint();
creatbar();
if(keyboard()0)
exit(0);
break;
case 2:
chose();
break;
case 3:
exit(0);
}
}
//难度选择,通过改变蛇的移动速度改变难度
void chose()
{
system(“cls”);
int n;
gotoxy(43,10);
printf(“请选择难度”);
gotoxy(25, 22);
printf(“1.简单难度”);
gotoxy(45, 22);
printf(“2.普通难度”);
gotoxy(65, 22);
printf(“3.困难难度”);
gotoxy(40,27);
printf(“请选择 1 2 3:”);
scanf("%d",&n);
switch(n)
{
case 1:speed=200;break;
case 2:speed=150;break;
case 3:speed=100;break;
}
welcome();
}
//坐标改变
void gotoxy(int x,int y)
{
COORD c;
c.X=x;
c.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
//地图创建
void creatmap()
{
int i;
for(i=0;i<58;i+=2)
{
gotoxy(i,0);
printf(“■”);
gotoxy(i,26);
printf(“■”);
}
for(i=1;i<26;i++)
{
gotoxy(0,i);
printf(“■”);
gotoxy(56,i);
printf(“■”);
}
}
//蛇身创建
void creatsnake()
{
head = (snake )malloc(sizeof(snake)); //初始蛇的坐标,蛇的长度为3
head->x=16;
head->y=15;
tail = (snake
)malloc(sizeof(snake));
snake snake_1 = (snake)malloc(sizeof(snake));
snake snake_2 = (snake)malloc(sizeof(snake));
snake_1->x = 16;
snake_1->y = 16;
snake_2->x = 16;
snake_2->y = 17;
head->next = snake_1;
snake_1->next = snake_2;
snake_2->next = tail;
tail->next = NULL;
}
//食物创建
void creatfood()
{
snake *p = head; //由于head为全局变量,故使用p代替head,下面同理
srand((unsigned int)time(NULL));
lable: //设置标签,当随机生成的食物和蛇重合时重新生成食物
food.x = rand() % 53 + 2;
food.y = rand() % 25+ 1;
if(food.x%2!=0) //确保x坐标为偶数
{
food.x = food.x+1;
}
while(1) //确保食物不会与蛇身重合
{
if(p->next == NULL)
break;
if(food.x == p->x&&food.y == p->y)
goto lable;
p = p->next;
}
if(food.x
bar.x&&food.ybar.y) //确保食物不会与障碍物重合
goto lable;
if(point.x
food.x&&point.yfood.y) //确保食物不会与奖励性食物重合
goto lable;
gotoxy(food.x,food.y);
printf(“●”);
}
//创建奖励性食物
void creatpoint()
{
snake *p = head;
srand((unsigned int)time(NULL));
lable1:
point.x = rand() % 53 + 2;
point.y = rand() % 25+ 1;
if(point.x%2!=0)
{
point.x = point.x+1;
}
while(1) //确保奖励性食物不会与蛇身重合
{
if(p->next == NULL)
break;
if(point.x == p->x&&point.y == p->y)
goto lable1;
p = p->next;
}
if(point.x
bar.x&&point.ybar.y) //确保奖励性食物不会与障碍物重合
goto lable1;
if(point.x
food.x&&point.yfood.y) //确保奖励性食物不会与食物重合
goto lable1;
gotoxy(point.x,point.y);
printf(“★”);
}
//创建障碍物
void creatbar()
{
snake *p = head;
srand((unsigned int)time(NULL));
lable2:
bar.x = rand() % 53 + 2;
bar.y = rand() % 25+ 1;
if(bar.x%2!=0)
{
bar.x = bar.x+1;
}
while(1) //确保障碍物不会与蛇身重合
{
if(p->next == NULL)
break;
if(bar.x == p->x&&bar.y == p->y)
goto lable2;
p = p->next;
}
if(bar.x == food.x&&bar.y food.y) //确保障碍物不会与食物重合
goto lable2;
if(bar.x
point.x&&bar.y
point.y) //确保障碍物不会与奖励性食物重合
goto lable2;
gotoxy(bar.x,bar.y);
printf("##");
}
//从键盘接收按键,接收到按键则返回1
int keyboard()
{
while(1)
{
if(endgame()0) //先判断游戏是否结束,结束则返回0
return 0;
if(key
1)
{
if(_kbhit()) //_kbhit判断是否按下键盘,若按下则读取按下的字符
{
key=_getch();
}
move_snake();
eatfood();
}
switch(key)
{
case up:
if(_kbhit())
{
key=_getch();
}
if(key==‘s’)
key=‘w’;
break;
case down:
if(_kbhit())
{
key=_getch();
}
if(key==‘w’)
key=‘s’;
break;
case left:
if(_kbhit())
{
key=_getch();
}
if(key==‘d’)
key=‘a’;
break;
case right:
if(_kbhit())
{
key=_getch();
}
if(key==‘a’)
key=‘d’;
break;
case quit:
key=‘q’;
break;
}
move_snake();
eatfood();
}
return 1;
}
//蛇的移动
void move_snake()
{
snake *p=head;
int a = head->x,b=head->y; //a,b代替头部坐标
while(1) //清空蛇身,以便于打印新的蛇身
{
if(p->next == NULL)
break;
gotoxy(p->x,p->y);
printf(" ");
p=p->next;
}
switch(key) //通过从键盘接收的按键改变蛇的移动方向
{
case up:
head->y-=1;
snakebody(a,b);
break;
case down:
head->y+=1;
snakebody(a,b);
break;
case left:
head->x-=2;
snakebody(a,b);
break;
case right:
head->x+=2;
snakebody(a,b);
break;
case quit:
gotoxy(2,29);
system(“pause”);
exit(0);
}
p = head;
while(1) //打印蛇身,同时打印右边的提示
{
if (p->next == NULL)
break;
gotoxy(p->x, p->y);
printf(“■”);
p = p->next;
gotoxy(64,8);
printf("得分:%d ",score);
gotoxy(64,10);
printf(“●是食物,##为障碍物”);
gotoxy(64,12);
printf(“★为奖励性食物,最多出现五次”);
gotoxy(64,14);
printf(“不能穿墙,不能咬到自己,不能撞到障碍物”);
gotoxy(64,16);
printf(“用w s a d分别控制蛇的移动”);
gotoxy(64,18);
printf(“按q键退出游戏”);
}
Sleep(speed); //Sleep函数设置蛇的移动速度
}
//吃了食物后的变化
void eatfood()
{
if(head->xpoint.x&&head->ypoint.y) //判断是否吃到了奖励性食物,奖励性食物只会增加分数
{
if(count<6) //奖励性食物最多出现5次
{
creatpoint();
score+=10;
count++;
}
}
if (head->x == food.x&&head->y == food.y) //判断蛇头是否吃到了食物,吃到了则伸长
{
creatfood();
snake add = (snake)malloc(sizeof(snake)); //add为新增的蛇的节点
snake *p;
p = head;
while(1) //遍历蛇身,直到p指向倒数第二个节点为止
{
if(p->next->next == NULL)
break;
p = p->next;
}
p->next = add; //在蛇身末尾加一个节点
add->next = tail;
score+=10; //每吃到一个食物加10分
}
}
//若蛇改变移动方向的坐标改变
void snakebody(int a,int b)
{
snake *p=head->next;
int s1_x,s1_y,s2_x,s2_y;
s1_x = p->x;
s1_y = p->y;
while(1) //前一个节点覆盖后一个节点
{
if(p->next->next == NULL)
break;
s2_x=p->next->x;
s2_y=p->next->y;
p->next->x = s1_x;
p->next->y = s1_y;
s1_x=s2_x;
s1_y=s2_y;
p=p->next;
}
p = head->next;
p->x=a;
p->y=b;
}
//游戏结束的条件,返回0则表示游戏结束
int endgame()
{
if (head->x == 0|| head->x == 56 || head->y == 0 || head->y == 26) //判断是否碰墙
{
End();
return 0;
}
if(head->xbar.x&&head->ybar.y) //判断是否撞到障碍物
{
End();
return 0;
}
snake *p = head->next;
while(1)
{
if (p->next == NULL)
break;
if (head->x == p->x&&head->y == p->y) //判断是否咬到自己
{
End();
return 0;
}
p = p->next;
}
return 1;
}
//游戏结束界面
void End()
{
system(“cls”);
gotoxy(18, 14);
printf(“GAME OVER”);
gotoxy(20, 16);
printf(“你的分数为 %d”, score);
gotoxy(0, 27);
system(“pause”);
}
求一下积分

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值