c语言 链表贪吃蛇(BUG版本)
·
c语言链表贪吃蛇(BUG版本)
前言:贪吃蛇是第一个大作业,给自己学完c语言程序设计来练练手,在此分享思路,也请求大佬能帮忙找出BUG。 使用工具DEVEc++
bug为 蛇有一定几率吃不到果实。
一 所需要的函数(除程序设计基础外的)
①
while(kbhit()) //判断键盘有输入
{
ch=getch();}//使得持续等于上一个
②
#include <windows.h>
void gotoxy(int x,int y){//设置 windows函数,使得蛇可以光标移动
COORD pos={x,y};
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut ,pos);
}
③
#include <time.h>
srand(time(NULL));
while(foodx<6)foodx=rand()%(115);
while(foody<8)foody=rand()%(36);
④
Sleep(100); //设置刷新率即蛇的移动速度
⑤
system("pause");//暂停
system("cls"); //清屏


二 思路
①先设置界面
void Start(){
system("mode con cols=150 Lines=50");//设置界面大小
int i; //输出初始界面
for(i=1;i<=20;i++) printf("\n");
printf("%*sWell com Snake game%*s",60," ",60," ");
for(i=1;i<=20;i++) printf("\n");
system("pause");
system("cls");
}
②初始化地图
void Map(){ //创建地图
int i;
gotoxy(125,5) ;printf("制作人:最爱舔雪糕") ;
gotoxy(125,6) ; printf("操作 w 上") ;
gotoxy(125,7) ;printf("操作 s 下") ;
gotoxy(125,8) ; printf("操作 a 左") ;
gotoxy(125,9) ;printf("操作 d 右") ;
for(i=1;i<=120;i++) { gotoxy(i,5) ;printf("%s","█");} //上界
for(i=5;i<=40;i++) { gotoxy(0,i) ;printf("%s","█");}//左界
for(i=5;i<=40;i++) { gotoxy(120,i) ;printf("%s","█");}//右界
for(i=1;i<=120;i++) { gotoxy(i,40) ;printf("%s","█");}//下界
}
③初始化蛇
typedef struct Snake{
int x;
int y;
struct Snake* next;
}snake;
void newsnake(){
int i;
snake *temp=(snake*)malloc(sizeof(snake));
temp->x=20;
temp->y=30;
temp->next=NULL;
head=temp;//用临时变量保存头,使得头永远第一个
for(i=1;i<=3;i++){
snake *p=(snake*)malloc(sizeof(snake));
p->x=20+2*i;
p->y=30;
p->next=NULL;
temp->next=p;
temp=p;
}
temp=head;
while(temp!=NULL){ //遍历输出蛇身体
gotoxy(temp->x,temp->y); printf("%s","●");
temp=temp->next;
}
}
//链表头是蛇的尾巴,蛇的尾巴是链表头
//使用尾插队列法
④蛇的移动
void movesnake( ){
while(kbhit())//键盘有输入
{
ch=getch();
fflush(stdin); //避免其他键扰乱蛇的移动
if (ch != 'w' && ch != 's' && ch != 'a' && ch != 'd' )
ch = direction;
else { //避免蛇直接就自己吃自己
if (direction == 'w'&& ch == 's' )
ch = direction;
if (direction == 's'&&ch == 'w' )
ch = direction;
if (direction == 'a'&& ch == 'd')
ch = direction;
if ( direction == 'd'&&ch == 'a')
ch = direction;
direction = ch;
}
}
snake *k=NULL;
snake *temp=(snake*)malloc(sizeof(snake));
temp->next=NULL;
k=head->next;
if(grow==0){
gotoxy(head->x,head->y);//没有长大就把尾巴清除
printf(" ");
free(head);
head=NULL;
head=k; //保证链表的头是蛇的尾巴
}
snake *p= head;//加一个节点 ,贪吃蛇的头==链表尾巴
while(p!=NULL&&p->next!=NULL){
p=p->next;
}
switch(direction){//变化蛇头的位置
case 'w':
temp->x=p->x;
temp->y=p->y-1;
break;
case 's':
temp->x=p->x;
temp->y=p->y+1;
break;
case 'd':
temp->x=p->x+2;
temp->y=p->y;
break;
case 'a':
temp->x=p->x-2;
temp->y=p->y;
break;
}
p->next=temp;
gotoxy(temp->x,temp->y);//输出蛇头
printf("%s","●") ;
grow=0;//成长归零,否则无限成长
}
⑤设置食物
typedef struct Foot{
int x;
int y;
}foot;
void updatefood(){
int foody,foodx;
snake *cry=head;
food = (snake*)malloc(sizeof(snake));
srand(time(NULL));
int flagh=0;//可以使用goto或设置while循环,避免成的新食物点和蛇的位置一样
do{
while(foodx<6)foodx=rand()%(115);
while(foody<8)foody=rand()%(36);
food->x=foodx;
food->y=foody;
while(cry->next!=NULL){
if(cry->x==food->x&&cry->y==food->y){
flagh=1;
}
cry=cry->next;
}
}while(flagh);
gotoxy(food->x,food->y);
printf("%s","●");
grow=1; //当grow==1时候
}
⑥蛇吃食物的时候刷新食物
void eatfood(){
snake *cry=head;
while(cry->next!=NULL)
cry=cry->next;
if(cry->x==food->x&&cry->y==food->y){ //如果头碰到食物就再生成一个食物
free(food);
updatefood();}
}
⑦判断蛇的存活
int alive(){ //判断蛇是否活着
snake *cry=head;
snake *p=head;//如果碰到墙直接结束返回0
if(cry->x<=2||cry->y<=5||cry->y>=40||cry->x>=120) return 0;
while(cry->next!=NULL){
cry=cry->next; //遍历到蛇的头
}
while(p->next!=NULL){ //如果蛇的头碰到身体就 直接结束返回0
if(p->x==cry->x&&p->y==cry->y) return 0;
p=p->next;
}
return 1;// 如果都没碰到,证明或者返回1
}
以下为源代码
#include<stdio.h>
#include<stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
void Start();
void Map();
void gotoxy(int x,int y);
void newsnake();
void run();
void eatfood();
void movesnake();
void updatefood();
char direction='d';
char ch='d';
int grow=0;
int alive();
typedef struct Snake{
int x;
int y;
struct Snake* next;
}snake;
snake *head=NULL;
snake *food=NULL;//头
//enum {UP=72,DOWN=80,LEFT=75,RIGHT=77};
typedef struct Foot{
int x;
int y;
}foot;
int main(){
Start();//初始化界面
Map();//打印地图
newsnake();
updatefood();
while(1){
eatfood();
movesnake();
Sleep(100);
if(!alive()) break;//判断蛇的存活
}
printf("别玩了太菜了\n");
system("pause");
return 0;
}
void Start(){
system("mode con cols=150 Lines=50");//设置界面大小
int i; //输出初始界面
for(i=1;i<=20;i++) printf("\n");
printf("%*sWell com Snake game%*s",60," ",60," ");
for(i=1;i<=20;i++) printf("\n");
system("pause");
system("cls");
}
void Map(){ //创建地图
int i;
gotoxy(125,5) ;printf("制作人:最爱舔雪糕") ;
gotoxy(125,6) ; printf("操作 w 上") ;
gotoxy(125,7) ;printf("操作 s 下") ;
gotoxy(125,8) ; printf("操作 a 左") ;
gotoxy(125,9) ;printf("操作 d 右") ;
for(i=1;i<=120;i++) { gotoxy(i,5) ;printf("%s","█");} //上界
for(i=5;i<=40;i++) { gotoxy(0,i) ;printf("%s","█");}//左界
for(i=5;i<=40;i++) { gotoxy(120,i) ;printf("%s","█");}//右界
for(i=1;i<=120;i++) { gotoxy(i,40) ;printf("%s","█");}//下界
}
void gotoxy(int x,int y){//设置 windows函数,使得蛇可以光标移动
COORD pos={x,y};
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut ,pos);
}
void newsnake(){
int i;
snake *temp=(snake*)malloc(sizeof(snake));
temp->x=20;
temp->y=30;
temp->next=NULL;
head=temp;//用临时变量保存头,使得头永远第一个
for(i=1;i<=3;i++){
snake *p=(snake*)malloc(sizeof(snake));
p->x=20+2*i;
p->y=30;
p->next=NULL;
temp->next=p;
temp=p;
}
temp=head;
while(temp!=NULL){ //遍历输出蛇身体
gotoxy(temp->x,temp->y);
printf("%s","●");
temp=temp->next;
}
}
//链表头是蛇的尾巴,蛇的尾巴是链表头
//使用尾插队列法
void movesnake( ){
while(kbhit())//键盘有输入
{
ch=getch();
fflush(stdin); //避免其他键扰乱蛇的移动
if (ch != 'w' && ch != 's' && ch != 'a' && ch != 'd' )
ch = direction;
else { //避免蛇直接就自己吃自己
if (direction == 'w'&& ch == 's' )
ch = direction;
if (direction == 's'&&ch == 'w' )
ch = direction;
if (direction == 'a'&& ch == 'd')
ch = direction;
if ( direction == 'd'&&ch == 'a')
ch = direction;
direction = ch;
}
}
snake *k=NULL;
snake *temp=(snake*)malloc(sizeof(snake));
temp->next=NULL;
k=head->next;
if(grow==0){
gotoxy(head->x,head->y);//没有长大就把尾巴清除
printf(" ");
free(head);
head=NULL;
head=k; //保证链表的头是蛇的尾巴
}
snake *p= head;//加一个节点 ,贪吃蛇的头==链表尾巴
while(p!=NULL&&p->next!=NULL){
p=p->next;
}
switch(direction){//变化蛇头的位置
case 'w':
temp->x=p->x;
temp->y=p->y-1;
break;
case 's':
temp->x=p->x;
temp->y=p->y+1;
break;
case 'd':
temp->x=p->x+2;
temp->y=p->y;
break;
case 'a':
temp->x=p->x-2;
temp->y=p->y;
break;
}
p->next=temp;
gotoxy(temp->x,temp->y);//输出蛇头
printf("%s","●") ;
grow=0;//成长归零,否则无限成长
}
void updatefood(){
int foody,foodx;
snake *cry=head;
food = (snake*)malloc(sizeof(snake));
srand(time(NULL));
int flagh=0;//可以使用goto或设置while循环,避免成的新食物点和蛇的位置一样
do{
while(foodx<6)foodx=rand()%(115);
while(foody<8)foody=rand()%(36);
food->x=foodx;
food->y=foody;
while(cry->next!=NULL){
if(cry->x==food->x&&cry->y==food->y){
flagh=1;
}
cry=cry->next;
}
}while(flagh);
gotoxy(food->x,food->y);
printf("%s","●");
grow=1; //当grow==1时候
}
void eatfood(){
snake *cry=head;
while(cry->next!=NULL)
cry=cry->next;
if(cry->x==food->x&&cry->y==food->y){ //如果头碰到食物就再生成一个食物
free(food);
updatefood();}
}
int alive(){ //判断蛇是否活着
snake *cry=head;
snake *p=head;//如果碰到墙直接结束返回0
if(cry->x<=2||cry->y<=5||cry->y>=40||cry->x>=120) return 0;
while(cry->next!=NULL){
cry=cry->next; //遍历到蛇的头
}
while(p->next!=NULL){ //如果蛇的头碰到身体就 直接结束返回0
if(p->x==cry->x&&p->y==cry->y) return 0;
p=p->next;
}
return 1;// 如果都没碰到,证明或者返回1
}
更多推荐



所有评论(0)