C语言基于链表实现贪吃蛇
来源:互联网 发布:Linux复杂源码 看懂 编辑:程序博客网 时间:2024/05/09 15:25
一 引言
数组实现的贪吃蛇代码比较复杂,换成链表逻辑更加清晰。每一个节点对应蛇的一节。
二 基本原理
对于贪吃蛇怎么在屏幕上移动,一种方法是移动蛇头,坐标依次传递,还有一种添头去尾。本文采用链表实现,移动采用添头去尾。
三 代码
/**************************************************************************
**文件:snake.c
**功能:贪吃蛇
**编写者:Nightmare
**编写日期:2017-01-28
**简要说明:链表实现;可加速
**修改者:
**修改日期:
**注:在VC 6.0下编写完成
**************************************************************************/
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#define FrameX 4 //游戏地图位置
#define FrameY 4
#define FrameHeight 20
#define FrameWidth 40
int i;
char ch=72; //初始移动方向
int len=3; //初始蛇长
int speed=200; //初始速度
COORD cor; //临时坐标变量
int grow=0; //蛇是否变长
typedef struct Snake{ //蛇的结构体
COORD cor;
struct Snake* next;
}snake, *psnake;
psnake head; //蛇头
psnake p; //临时结点
struct Food{ //食物的结构体
COORD cor;
}food;
void initial(void); //初始化地图
void make_food(void); //产生食物
void get_speed(void); //获取速度
void move_snake(void); //蛇的移动
int is_alive(void); //蛇的死活
void free_snake(void); //释放内存
void gotoxy(COORD cor); //光标定位
int cor_com(COORD cor1, COORD cor2); //坐标比较
int main()
{
initial();
while(1)
{
make_food();
get_speed();
move_snake();
if(!is_alive())
break;
}
printf("Game Over!\n");
free_snake();
getch();
return 0;
}
/***********************光标移动***********************************************/
void gotoxy(COORD cor)
{
HANDLE hout;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout,cor);
}
/************************ 坐标是否相等 ********************************************/
int cor_com(COORD cor1, COORD cor2)
{
return cor1.X==cor2.X && cor1.Y==cor2.Y;
}
/*************************** 初始化 ***********************************************/
void initial(void)
{
psnake p1,p2;
head=(psnake)malloc(sizeof(snake));//初始化蛇头位置
head->cor.X=FrameX+4;
head->cor.Y=FrameY+FrameHeight-6;
head->next=NULL;//定义一个新指针的同时指向空
gotoxy(head->cor);
printf("@");
p1=head;
for(i=1;i<len;i++)//初始化蛇身
{
p2=(psnake)malloc(sizeof(snake));
p2->cor.X=p1->cor.X;
p2->cor.Y=p1->cor.Y+1;
p2->next=NULL;
gotoxy(p2->cor);
printf("@");
p1->next=p2;
p1=p2;
}
srand((unsigned int)time(NULL));//初始化食物
food.cor.X=rand()%(FrameWidth-2)+1+FrameX;
food.cor.Y=rand()%(FrameHeight-2)+1+FrameY;
gotoxy(food.cor);
printf("!");
for(i=FrameY;i<FrameY+FrameHeight;i++)//初始化围墙
{
cor.X=FrameX; cor.Y=i;
gotoxy(cor);
printf("#");
cor.X=FrameX+FrameWidth-1;cor.Y=i;
gotoxy(cor);
printf("#");
}
for(i=FrameX+1;i<FrameX+FrameWidth-1;i++)
{
cor.X=i; cor.Y=FrameY;
gotoxy(cor);
printf("#");
cor.X=i; cor.Y=FrameY+FrameHeight-1;
gotoxy(cor);
printf("#");
}
}
/*************************************** 产生食物 ********************************/
void make_food(void)
{
if(cor_com(head->cor,food.cor))//是否吃到食物
{
srand((unsigned int)time(NULL));
food.cor.X=rand()%(FrameWidth-2)+1+FrameX;
food.cor.Y=rand()%(FrameHeight-2)+1+FrameY;
gotoxy(food.cor);
printf("!");
grow=1;
}
}
/*************************************** 得到速度 ***********************************/
void get_speed(void)
{
if(len%5==0)
speed-=50; //变速
}
/*************************************** 蛇的移动 *************************************/
void move_snake(void)
{
if(kbhit())
{
getch();
ch=getch();
}
if(!grow) //若蛇没有变长,去尾; 变长则不去尾
{
for(p=head;p->next->next!=NULL;p=p->next);
gotoxy(p->next->cor);
printf(" ");
free(p->next);
p->next=NULL;
}
p=(psnake)malloc(sizeof(snake));//添头(新的蛇头)
p->cor=head->cor;
p->next=head;
head=p;
switch(ch)
{
case 72: p->cor.Y--;break;
case 80: p->cor.Y++;break;
case 75: p->cor.X--;break;
case 77: p->cor.X++;break;
default: break;
}
gotoxy(p->cor);
printf("@");
grow=0;
Sleep(speed); //控制蛇的移动速度
}
/*************************************** 蛇的死活 *************************************/
int is_alive(void)
{
cor.X=FrameX;
cor.Y=FrameY+FrameHeight;
gotoxy(cor);
for(p=head->next;p!=NULL;p=p->next)//是否自食
{
if(cor_com(p->cor,head->cor))
break;
}
if(p!=NULL)
return 0;
else //是否撞墙
{
for(i=FrameY;i<FrameY+FrameHeight;i++)
{
cor.X=FrameX; cor.Y=i;
if(cor_com(cor,head->cor))
return 0;
cor.X=FrameX+FrameWidth-1;cor.Y=i;
if(cor_com(cor,head->cor))
return 0;
}
for(i=FrameX+1;i<FrameX+FrameWidth-1;i++)
{
cor.X=i; cor.Y=FrameY;
if(cor_com(cor,head->cor))
return 0;
cor.X=i; cor.Y=FrameY+FrameHeight-1;
if(cor_com(cor,head->cor))
return 0;
}
}
return 1;
}
/******************************** 释放内存 ****************************************/
void free_snake()
{
p=head;
while(head!=NULL)
{
head=head->next;
free(p);
p=head;
}
}
**文件:snake.c
**功能:贪吃蛇
**编写者:Nightmare
**编写日期:2017-01-28
**简要说明:链表实现;可加速
**修改者:
**修改日期:
**注:在VC 6.0下编写完成
**************************************************************************/
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#define FrameX 4 //游戏地图位置
#define FrameY 4
#define FrameHeight 20
#define FrameWidth 40
int i;
char ch=72; //初始移动方向
int len=3; //初始蛇长
int speed=200; //初始速度
COORD cor; //临时坐标变量
int grow=0; //蛇是否变长
typedef struct Snake{ //蛇的结构体
COORD cor;
struct Snake* next;
}snake, *psnake;
psnake head; //蛇头
psnake p; //临时结点
struct Food{ //食物的结构体
COORD cor;
}food;
void initial(void); //初始化地图
void make_food(void); //产生食物
void get_speed(void); //获取速度
void move_snake(void); //蛇的移动
int is_alive(void); //蛇的死活
void free_snake(void); //释放内存
void gotoxy(COORD cor); //光标定位
int cor_com(COORD cor1, COORD cor2); //坐标比较
int main()
{
initial();
while(1)
{
make_food();
get_speed();
move_snake();
if(!is_alive())
break;
}
printf("Game Over!\n");
free_snake();
getch();
return 0;
}
/***********************光标移动***********************************************/
void gotoxy(COORD cor)
{
HANDLE hout;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout,cor);
}
/************************ 坐标是否相等 ********************************************/
int cor_com(COORD cor1, COORD cor2)
{
return cor1.X==cor2.X && cor1.Y==cor2.Y;
}
/*************************** 初始化 ***********************************************/
void initial(void)
{
psnake p1,p2;
head=(psnake)malloc(sizeof(snake));//初始化蛇头位置
head->cor.X=FrameX+4;
head->cor.Y=FrameY+FrameHeight-6;
head->next=NULL;//定义一个新指针的同时指向空
gotoxy(head->cor);
printf("@");
p1=head;
for(i=1;i<len;i++)//初始化蛇身
{
p2=(psnake)malloc(sizeof(snake));
p2->cor.X=p1->cor.X;
p2->cor.Y=p1->cor.Y+1;
p2->next=NULL;
gotoxy(p2->cor);
printf("@");
p1->next=p2;
p1=p2;
}
srand((unsigned int)time(NULL));//初始化食物
food.cor.X=rand()%(FrameWidth-2)+1+FrameX;
food.cor.Y=rand()%(FrameHeight-2)+1+FrameY;
gotoxy(food.cor);
printf("!");
for(i=FrameY;i<FrameY+FrameHeight;i++)//初始化围墙
{
cor.X=FrameX; cor.Y=i;
gotoxy(cor);
printf("#");
cor.X=FrameX+FrameWidth-1;cor.Y=i;
gotoxy(cor);
printf("#");
}
for(i=FrameX+1;i<FrameX+FrameWidth-1;i++)
{
cor.X=i; cor.Y=FrameY;
gotoxy(cor);
printf("#");
cor.X=i; cor.Y=FrameY+FrameHeight-1;
gotoxy(cor);
printf("#");
}
}
/*************************************** 产生食物 ********************************/
void make_food(void)
{
if(cor_com(head->cor,food.cor))//是否吃到食物
{
srand((unsigned int)time(NULL));
food.cor.X=rand()%(FrameWidth-2)+1+FrameX;
food.cor.Y=rand()%(FrameHeight-2)+1+FrameY;
gotoxy(food.cor);
printf("!");
grow=1;
}
}
/*************************************** 得到速度 ***********************************/
void get_speed(void)
{
if(len%5==0)
speed-=50; //变速
}
/*************************************** 蛇的移动 *************************************/
void move_snake(void)
{
if(kbhit())
{
getch();
ch=getch();
}
if(!grow) //若蛇没有变长,去尾; 变长则不去尾
{
for(p=head;p->next->next!=NULL;p=p->next);
gotoxy(p->next->cor);
printf(" ");
free(p->next);
p->next=NULL;
}
p=(psnake)malloc(sizeof(snake));//添头(新的蛇头)
p->cor=head->cor;
p->next=head;
head=p;
switch(ch)
{
case 72: p->cor.Y--;break;
case 80: p->cor.Y++;break;
case 75: p->cor.X--;break;
case 77: p->cor.X++;break;
default: break;
}
gotoxy(p->cor);
printf("@");
grow=0;
Sleep(speed); //控制蛇的移动速度
}
/*************************************** 蛇的死活 *************************************/
int is_alive(void)
{
cor.X=FrameX;
cor.Y=FrameY+FrameHeight;
gotoxy(cor);
for(p=head->next;p!=NULL;p=p->next)//是否自食
{
if(cor_com(p->cor,head->cor))
break;
}
if(p!=NULL)
return 0;
else //是否撞墙
{
for(i=FrameY;i<FrameY+FrameHeight;i++)
{
cor.X=FrameX; cor.Y=i;
if(cor_com(cor,head->cor))
return 0;
cor.X=FrameX+FrameWidth-1;cor.Y=i;
if(cor_com(cor,head->cor))
return 0;
}
for(i=FrameX+1;i<FrameX+FrameWidth-1;i++)
{
cor.X=i; cor.Y=FrameY;
if(cor_com(cor,head->cor))
return 0;
cor.X=i; cor.Y=FrameY+FrameHeight-1;
if(cor_com(cor,head->cor))
return 0;
}
}
return 1;
}
/******************************** 释放内存 ****************************************/
void free_snake()
{
p=head;
while(head!=NULL)
{
head=head->next;
free(p);
p=head;
}
}
补充:由于一些原因,没有写食物不能出现在蛇身上的判定,可自行补充。
0 0
- C语言基于链表实现贪吃蛇
- 用c语言+单向链表实现一个贪吃蛇
- 贪吃蛇----C语言实现
- C语言实现贪吃蛇
- 基于c语言的贪吃蛇游戏
- 【LB】C语言实现贪吃蛇
- c语言实现,图形化贪吃蛇
- 贪吃蛇游戏的C语言实现
- c语言实现贪吃蛇小游戏
- C语言之实现贪吃蛇
- 贪吃蛇C语言实现(简易版)
- C语言用数组实现贪吃蛇
- C语言 贪吃蛇实现(不闪屏)
- 用C语言实现贪吃蛇
- 贪吃蛇——C语言实现
- C语言-贪吃蛇具体实现
- C语言贪吃蛇
- c语言“贪吃蛇”
- 全球化流程中原型设计的加分项
- NFS及pNFS简介
- Java及eclipse操作技巧
- JDBC基础-元数据
- 利用享元模式来解决DOM元素过多导致的网页解析慢、卡死的问题
- C语言基于链表实现贪吃蛇
- JDBC工具-DBUtils
- 共同学习Java源代码-数据结构-AbstractMap抽象类(二)
- DOM
- linux减少服务器带宽的方法
- 2017年1月29日 iOS开发技巧 - Size Class与iOS 8多屏幕适配(一)
- ableau破解安装及长期试用
- 制作一个功能丰富的Android天气App
- Python:os模块中的walk()函数