C语言实现链表贪吃蛇

用C语言链表写的贪吃蛇(程序设计时做的,做的不好大佬勿喷)

借助游戏内容分析贪吃蛇所需的功能主要包括这几块:

1.移动光标模块

2.打印地图模块和基本规则信息

读取最高分文件

3.打印初始蛇模块

打印时给予蛇的初始移动方向

4.产生食物模块

1)、保证食物在地图内产生

2)、保证食物不能出现在蛇体

5.蛇的生命状态判断模块

1)、撞墙导致死亡

2)、头撞身体部位死亡

6.运行模块

1)、让蛇移动

2)、根据按键来改变蛇的移动方向

3)、对待分数的增加游戏难度的增加

4)、蛇在吃食物后分数的增加

7.结束模块

在遇到撞墙或者撞自己部位死亡时结束程序,并进行分数与历史最高分作比较,最终达到最高分的更新

以下为代码

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>//控制台输入和输出
#include <windows.h>//窗口函数
#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
/*
函数声明
*/
void gotoxy(int x,int y);//定位光标
void map_creat();//运用定位函数打印地图
void ini_snack();//随机产生蛇
void cre_food();//随机产生食物
void live_jud_1();//判断自己是否撞墙死亡
void live_jud_2();//判断自己是否撞到自己
void move();//蛇的移动
void rungame();//游戏运行
void gameover();//游戏结束界面
void changch();//改变方向
int color(int c);//改颜色函数
/*
构建定位函数
*/
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()//运用定位函数打印地图
{
 FILE *fp;//创建一个记录最高分的文件
 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("游戏规则:");
 gotoxy(54,12);
 printf("向上移动:↑\n");
 gotoxy(54,14);
 printf("向下移动:↓\n");
 gotoxy(54,16);
 printf("向左移动:←\n");
 gotoxy(54,18);
 printf("向右移动:→\n");
 gotoxy(54,20);
 printf("吃一个食物分数加10");
 gotoxy(54,22);
 printf("按空格键暂停游戏");
 gotoxy(54,24);
 printf("按ESC直接结束游戏");
}
/*
构建初始蛇
*/
void ini_snack()//产生蛇
{
 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;//蛇的初始方向
}
/*
随机产生食物
*/
void cre_food()//随机产生食物
{
 srand((unsigned)time(NULL));//为了防止每次产生的随机数相同,种子设置为time
 /*
 随机产生食物
 */
 food.x=rand()%(48-2)+1;
 food.y=rand()%(26-2)+1;
 while(p!=NULL)
 {
 /*
 判断食物是否与蛇重合,如果重合重新产生
 */
 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));
 /*
 构建一个新的节点通,过新节点来表示下一次头节点所在的位置
 将新节点当作移动后的头节点
 如果新头节点的坐标等于食物的坐标得分加10,食物的标志变为1
 因为蛇的链表长度加了一,如果是移动的话找出尾节点并打印出 然后删掉该尾节点
 如果吃到了食物就直接将蛇打印出来
 */
 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;
 /*
 根据分数和Sleep函数来确定游戏难度
 */
 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);//打印出得到的分数
 if(score>bestscore)//如果此次游戏分数大于以前最高分
 {
 fp=fopen("score.1","w");
 fprintf(fp,"%d",score);//将此次分数保存在最高分文件里
 fclose(fp);
 }
 system("pause");
 exit(0);
}
/*
主函数
*/
int main()
{
 system("color 9");
 map_creat();
 ini_snack();
 cre_food();
 rungame();
 return 0;
}

更多有趣的经典小游戏实现专题,分享给大家:

C++经典小游戏汇总

python经典小游戏汇总

python俄罗斯方块游戏集合

JavaScript经典游戏 玩不停

javascript经典小游戏汇总

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 贪吃蛇C语言代码实现(难度可选)

    本文实例为大家分享了C语言实现贪吃蛇的具体代码,供大家参考,具体内容如下 /********************************************************* ********************贪吃蛇(难度可选)******************** **************制作者:Xu Lizi 日期:2012/12/31******** ********************部分函数有借鉴************************ ****

  • C语言链表实现贪吃蛇游戏

    阅读学习了源代码,并做了简单的注释和修改,里面只用了链表数据结构,非常适合C语言入门者学习阅读. 程序可在VS2013下编译运行. #include<stdio.h> #include<time.h> #include<windows.h> #include<stdlib.h> #define U 1 #define D 2 #define L 3 #define R 4 //蛇的状态,U:上 :D:下:L:左 R:右 typedef struct SNAK

  • C语言实现贪吃蛇小游戏

    本文实例为大家分享了C语言实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 一.程序实现的原理: 1.构造蛇身:定义一个坐标数组,存放的是蛇的每一节蛇身所在的坐标位置.这样就将移动蛇身的操作转换为移动数组的操作,将吃食物增加蛇身体长度的操作转换为在数组后面追加元素的操作. 2.移动效果:每次移动时,将每一节蛇身(蛇头除外)依次往前移动一节,然后擦去蛇的最后一节,最后确定蛇头的方向,再绘制一个蛇头.这样就会显示一个移动效果. 3.身体增加效果:每次移动时候,判断蛇头是否碰到了食物,如果碰到了食

  • C语言手把手教你实现贪吃蛇AI(下)

    本文实例为大家分享了C语言实现贪吃蛇AI的具体代码,供大家参考,具体内容如下 1. 目标 这一部分的目标是把之前写的贪吃蛇加入AI功能,即自动的去寻找食物并吃掉. 2. 控制策略 为了保证蛇不会走入"死地",所以蛇每前进一步都需要检查,移动到新的位置后,能否找到走到蛇尾的路径,如果可以,才可以走到新的位置:否则在当前的位置寻找走到蛇尾的路径,并按照路径向前走一步,开始循环之前的操作,如下图所示.这个策略可以工作,但是并不高效,也可以尝试其他的控制策略,比如易水寒的贪吃蛇AI 运行效果如

  • DOS简易版C语言贪吃蛇

    本文实例为大家分享了C语言实现贪吃蛇的具体代码,供大家参考,具体内容如下 #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <time.h> #include <windows.h> #define WALL_LENGTH 22 #define LEFT 0x4b #define RIGHT 0x4d #define DOWN 0x50 #define UP 0x

  • C语言贪吃蛇经典小游戏

    一.贪吃蛇小游戏简介: 用上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,也不能咬到自己的身体,等到了一定的分数,就能过关. 二.函数框架 三.数据结构 typedef struct Snake { size_t x; //行 size_t y; //列 struct Snake* next; }Snake, *pSnake; 定义蛇的结构体,利用单链表来表示蛇,每个结点为蛇身体的一部分. 四.代码实现(vs2010  c

  • C语言手把手教你实现贪吃蛇AI(中)

    手把手教你实现贪吃蛇AI,具体内容如下 1. 目标 这一部分主要是讲解编写贪吃蛇AI所需要用到的算法基础. 2. 问题分析 贪吃蛇AI说白了就是寻找一条从蛇头到食物的一条最短路径,同时这条路径需要避开障碍物,这里仅有的障碍就是蛇身.而A star 算法就是专门针对这一个问题的.在A star 算法中需要用到排序算法,这里采用堆排序(当然其他排序也可以),如果对堆排序不熟悉的朋友,请移步到这里--堆排序,先看看堆排序的内容. 3. A*算法 A star(也称A*)搜寻算法俗称A星算法.这是一种在

  • 70行C语言代码实现贪吃蛇

    本文实例为大家分享了C语言实现贪吃蛇的具体代码,供大家参考,具体内容如下 #include <stdio.h> #include <Windows.h> #include <conio.h> #include <time.h> #define MAX_WIDE 50 #define MAX_HIGH 16 short dx = 1, dy = 0, randxy, score = 0; COORD coord; struct Snake{ short len

  • 基于C语言实现的贪吃蛇游戏完整实例代码

    本文以实例的形式讲述了基于C语言实现的贪吃蛇游戏代码,这是一个比较常见的游戏,代码备有比较详细的注释,对于读者理解有一定的帮助. 贪吃蛇完整实现代码如下: #include <graphics.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #define NULL 0 #define UP 18432 #define DOWN 20480 #define LEFT 19200 #defi

  • C语言实现贪吃蛇游戏

    最近整理下电脑,看到了自己在上个学期打的贪吃蛇游戏的c代码,觉得真的是略微有点冗长,但是实现起来应该也算是比较好理解,于是把自己的代码搬上来,网络上写贪吃蛇的c语言的文章很多,我这篇也仅是给大家作为一个参考而已. 我的代码是在Windows下运行的,因为需要用到windows.h这个库. 然后也做了一个简单的ai模式,这在没有障碍物的情况下前期还是蛮不错的,但是到了后期蛇变长了之后就会有bug了. 好了,直接上代码吧: 1)头文件和宏定义 #include<stdio.h> #include&

  • C语言手把手教你实现贪吃蛇AI(上)

    本文实例为大家分享了手把手教你实现贪吃蛇AI的具体步骤,供大家参考,具体内容如下 1. 目标 编写一个贪吃蛇AI,也就是自动绕过障碍,去寻找最优路径吃食物. 2. 问题分析 为了达到这一目的,其实很容易,总共只需要两步,第一步抓一条蛇,第二步给蛇装一个脑子.具体来说就是,首先我们需要有一条普通的贪吃蛇,也就是我们常玩儿的,手动控制去吃食物的贪吃蛇:然后给这条蛇加入AI,也就是通过算法控制,告诉蛇怎么最方便的绕开障碍去吃食物.为了讲清楚这个问题,文章将分为三部分:上,写一个贪吃蛇程序:中,算法基础

  • C语言单链表贪吃蛇小游戏

    C语言实现单链表控制台贪吃蛇小游戏 编译环境:vs2019 需求: 统计游戏开始后的时间,控制贪吃蛇:吃到食物蛇身加长,得分加一:碰墙或蛇头碰到身体减一条生命:生命消耗完则结束游戏. 思路: 使用wasd键控制蛇的移动方向,蛇头碰到食物得分加一,并在地图上随机产生一个食物,累加得分,碰墙或碰自己减一条生命,并初始化整条蛇,生命值为0时结束游戏. 做法: 使用单链表控制贪吃蛇移动的核心思想就是:链表存储贪吃蛇所有坐标,每次循环贪吃蛇不断向一个方向插入一个新的结点作为新的蛇头,按下按键控制新蛇头产生

  • C语言结构数组实现贪吃蛇小游戏

    一.设计思路 蛇身本质上就是个结构数组,数组里存储了坐标x.y的值,再通过一个循环把它打印出来,蛇的移动则是不断地刷新重新打印.所以撞墙.咬到自己只是数组x.y值的简单比较. 二.用上的知识点 结构数组Windows API函数 三.具体实现 先来实现静态页面,把地图.初始蛇身.食物搞定. 这里需要用到Windows API的知识,也就是对控制台上坐标的修改 //这段代码来自参考1 void Pos(int x, int y) { COORD pos; HANDLE hOutput; pos.X

随机推荐