C语言贪吃蛇(bug蛇 (已修改

哈哈哈,写的过程出现一堆bug,可以扭头的贪吃蛇,等过几天在改进改进,加判断条件!(看视频的时候觉得简单,自己一写就不行了,还是要敲代码的!

参考代码地址:snake贪吃蛇: C语言实现小游戏 (gitee.com)

一开始的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windows.h>
#include <locale.h>
#include <time.h>
//判断键盘是否被按过
#define PRESS(key) ((GetAsyncKeyState(key)&0x1)?1:0)
//蛇结构体
typedef struct snake{
	short x;
	short y;
	struct snake* next;
}snake;
void setpos(short,short);
snake* printfood(snake *);
//初始化蛇
snake* initsnake(){
	//蛇头
	snake* head=(snake*)malloc(sizeof(snake));
	head->x=20;     
	head->y=10;
	head->next=NULL;
	snake* tem=NULL;
	int a=19;
	for(int i=0;i<4;i++){
		snake* newbody=(snake*)malloc(sizeof(snake));
		if(head->next==NULL){
			newbody->x=a;
			newbody->y=10;
			a--;
		   head->next=newbody;
			tem=newbody;
			continue;
		}
		newbody->x=a;
		newbody->y=10;
		newbody->next=NULL;
		tem->next=newbody;
		tem=newbody;
		a--;
	}
	return head;
}
//打印蛇身
void printsnake(snake *head){
	snake* tem=head;
	while(tem){
		setpos(tem->x,tem->y);
		printf("O");
		tem=tem->next;
	}
}
//打印食物
snake* printfood(snake *head){
again: snake* food=(snake*)malloc(sizeof(snake));
	food->x=rand()%58+1;
	food->y=rand()%26+1;
	food->next=NULL;
	snake* tem=head;
	while(tem){
		if(tem->x==food->x&&tem->y==food->y){
			free(food);
			goto again;
		}
		tem=tem->next;
	}
	setpos(food->x,food->y);
	printf("F");
	return food;
}
//吃食物
snake* eatfood(snake **head,snake *food,int num){
		if(PRESS(VK_UP)==1){
			num=1;}
		else if(PRESS(VK_DOWN)==1){
			num=2;
		}
		else if(PRESS(VK_LEFT)==1){
			num=3;
		}
		else if(PRESS(VK_RIGHT)==1){
			num=4;
		}
		switch(num){
		case 1:
			if((*head)->x==food->x&&((*head)->y-1)==food->y){
				food->next=*head;
				*head=food;
				printsnake(*head);
			return	printfood(*head);
			}
			break;
		case 2:
			if((*head)->x==food->x&&((*head)->y+1)==food->y){
				food->next=*head;
				*head=food;
				printsnake(*head);
			return	printfood(*head);
			}
			break;
		case 3:
			if(((*head)->x-1)==food->x&&(*head)->y==food->y){
				food->next=*head;
				*head=food;
				printsnake(*head);
			return printfood(*head);
			}
			break;
		case 4:
			if(((*head)->x+1)==food->x&&(*head)->y==food->y){
				food->next=*head;
				*head=food;
				printsnake(*head);
				return printfood(*head);
			}
			break;}
	return food;
}
//结束游戏
void endgame(snake *head){
     if(head->x==0||head->y==25||head->x==58||head->y==0){
			system("cls");
			setpos(36,10);
			printf("游戏结束!");
		    setpos(36,40);
			exit(1);
		}
}
//移动蛇 吃食物 结束游戏 等等
void movesnake(snake **head,snake* food){
	int num=1;
	while(1){
		
		if(PRESS(VK_UP)==1){
			num=1;}
		else if(PRESS(VK_DOWN)==1){
			num=2;
			}
		else if(PRESS(VK_LEFT)==1){
			num=3;
			}
		else if(PRESS(VK_RIGHT)==1){
			num=4;
				}
		food=eatfood(head,food,num);
		switch(num){
		case 1:
			snake* another=(snake*)malloc(sizeof(snake));
			another->y=(*head)->y-1;
			another->x=(*head)->x;
			another->next=*head;
			*head=another;
			snake *tem1=*head;
			while(tem1->next->next){
				tem1=tem1->next;
			}
			setpos(tem1->next->x,tem1->next->y);
			printf(" ");
			free(tem1->next);
			tem1->next=NULL;
			printsnake(*head);
		  break;
        case 2:
			snake* another2=(snake*)malloc(sizeof(snake));
			another2->y=(*head)->y+1;
			another2->x=(*head)->x;
			another2->next=*head;
			*head=another2;
			snake *tem2=(*head);
			while(tem2->next->next){
				tem2=tem2->next;
			}
			setpos(tem2->next->x,tem2->next->y);
			printf(" ");
			free(tem2->next);
			tem2->next=NULL;
			printsnake(*head);
			break;
		case 3:
			snake* another3=(snake*)malloc(sizeof(snake));
			another3->y=(*head)->y;
			another3->x=(*head)->x-1;
			another3->next=*head;
			*head=another3;
			snake *tem3=(*head);
			while(tem3->next->next){
				tem3=tem3->next;
			}
			setpos(tem3->next->x,tem3->next->y);
			printf(" ");
			free(tem3->next);
			tem3->next=NULL;
			printsnake(*head);
			break;
	  case 4:
			snake* another4=(snake*)malloc(sizeof(snake));
			another4->y=(*head)->y;
			another4->x=(*head)->x+1;
			another4->next=*head;
			*head=another4;
			snake *tem4=(*head);
			while(tem4->next->next){
				tem4=tem4->next;
			}
			setpos(tem4->next->x,tem4->next->y);
			printf(" ");
			free(tem4->next);
			tem4->next=NULL;
			printsnake(*head);
	       break;}
        Sleep(200);	
		endgame(*head);
		
	}
}

//隐藏鼠标函数
void hidemouse(){
	HANDLE output=NULL;
	output=GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO info;
	GetConsoleCursorInfo(output,&info);
	info.bVisible=false;
	SetConsoleCursorInfo(output,&info);
}
//设置光标位置
void setpos(short x,short y){
	COORD pos={x,y};
	HANDLE output=NULL;
	output=GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(output,pos);
}
void gametable(){
	//隐藏鼠标
	hidemouse();
	//打印欢迎界面
	setpos(36,10);
	printf("欢迎来到贪吃蛇小游戏!");
	setpos(38,20);
	system("pause");
	system("cls");
	//打印提示界面
	setpos(36,10);
	printf("提示:↑ ↓ ← →移动");
	setpos(38,20);
	system("pause");
	system("cls");
	//打印地图
	for(int i=0;i<=58;i++){
		setpos(i,0);
		printf("@");
	}
	for(int i=0;i<=58;i++){
		setpos(i,26);
		printf("@");
	}
	for(int i=1;i<=25;i++){
		setpos(0,i);
		printf("@");
	}
	for(int i=1;i<=25;i++){
		setpos(58,i);
		printf("@");
	}
	setpos(66,8);
	printf("提示:↑ ↓ ← →移动");
	
}
int main(){
	//设置随机种子
	srand(time(0));
	//设置命令行界面
	system("mode con cols=100 lines=30");
	system("title 贪吃蛇");
	gametable();
	snake* head=initsnake();
	printsnake(head);
	snake* food=printfood(head);
	movesnake(&head,food);
}

修改后的代码:

修复了可以直接回头的bug,增加了分数,按F键加速,按S减速,按空格键暂停,可以重新游戏,并销毁了内存(应该销毁干净了),并且做了意义不明的分离。

snake.h 

头文件

#ifndef SNAKE_H
#define SNAKE_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <windows.h>
#include <locale.h>
#include <time.h>
typedef struct snake snake;
//设置打印光标位置
void setpos(short,short);
//打印食物
snake* printfood(snake *);
//初始化蛇
snake* initsnake();
//打印蛇身
void printsnake(snake*);
//吃食物
snake* eatfood(snake **,snake *,int);
//结束游戏
char endgame(snake *,snake *);
//销毁内存
void destorysnake(snake *,snake *);
//移动蛇
char movesnake(snake **,snake* );
//隐藏光标
void hidemouse();
//打印开始界面
void gametable();

#endif
snake.c

实现函数文件

#include "snake.h"
//判断键盘是否被按过
#define PRESS(key) ((GetAsyncKeyState(key)&0x1)?1:0)
int score=0;
//蛇结构体
typedef struct snake{
	short x;
	short y;
	struct snake* next;
}snake;
//初始化蛇
snake* initsnake(){
	//蛇头
	snake* head=(snake*)malloc(sizeof(snake));
	head->x=20;     
	head->y=10;
	head->next=NULL;
	snake* tem=NULL;
	int a=19;
	for(int i=0;i<4;i++){
		snake* newbody=(snake*)malloc(sizeof(snake));
		if(head->next==NULL){
			newbody->x=a;
			newbody->y=10;
			a--;
			head->next=newbody;
			tem=newbody;
			continue;
		}
		newbody->x=a;
		newbody->y=10;
		newbody->next=NULL;
		tem->next=newbody;
		tem=newbody;
		a--;
	}
	return head;
}
//打印蛇身
void printsnake(snake *head){
	snake* tem=head;
	while(tem){
		setpos(tem->x,tem->y);
		printf("O");
		tem=tem->next;
	}
}

//打印食物
snake* printfood(snake *head){
	again: snake* food=(snake*)malloc(sizeof(snake));
	food->x=rand()%56+1;
	food->y=rand()%25+1;
	food->next=NULL;
	snake* tem=head;
	while(tem){
		if(tem->x==food->x&&tem->y==food->y){
			free(food);
			goto again;
		}
		tem=tem->next;
	}
	setpos(food->x,food->y);
	printf("F");
	return food;
}

//吃食物
snake* eatfood(snake **head,snake *food,int num){
	if(PRESS(VK_UP)==1){
		num=1;}
	else if(PRESS(VK_DOWN)==1){
		num=2;
	}
	else if(PRESS(VK_LEFT)==1){
		num=3;
	}
	else if(PRESS(VK_RIGHT)==1){
		num=4;
	}
	switch(num){
	case 1:
		if((*head)->x==food->x&&((*head)->y-1)==food->y){
			food->next=*head;
			*head=food;
			printsnake(*head);
			score+=10;
			return	printfood(*head);
		}
		break;
	case 2:
		if((*head)->x==food->x&&((*head)->y+1)==food->y){
			food->next=*head;
			*head=food;
			printsnake(*head);
			score+=10;
			return	printfood(*head);
		}
		break;
	case 3:
		if(((*head)->x-1)==food->x&&(*head)->y==food->y){
			food->next=*head;
			*head=food;
			printsnake(*head);
			score+=10;
			return printfood(*head);
		}
		break;
	case 4:
		if(((*head)->x+1)==food->x&&(*head)->y==food->y){
			food->next=*head;
			*head=food;
			printsnake(*head);
			score+=10;
			return printfood(*head);
		}
		break;}
	return food;
}
//毁尸灭迹!
void destorysnake(snake *head,snake *food){
	snake* tem=head;
	while(tem){
		tem=head->next;
		head=head->next;
		free(tem);
	}
	free(food);
	score=0;
}
//结束游戏
char endgame(snake*head,snake*food){
	//判断是否撞墙了
	if(head->x==0||head->y==25||head->x==58||head->y==0){
		system("cls");
		setpos(36,10);
		printf("你撞到墙啦!游戏结束!");
		setpos(36,15);
		system("pause");
		setpos(36,40);
		destorysnake(head,food);
		system("cls");
		setpos(36,10);
		printf("你想要重新开始游戏吗?");
		setpos(38,11);
		printf("    Y or N:");
		char choice=0;
		scanf("%c",&choice);
		while(choice!='Y'&&choice!='y'&&choice!='N'&&choice!='n'){
			system("cls");
			setpos(36,10);
			printf("请重新输入!");
			setpos(38,11);
			printf("Y or N:");
			scanf("%c",&choice);
		}
		system("cls");
		return choice;		
	}
	//判断是否撞到自己
	snake* tem=head->next;
	while(tem){
		if(head->x==tem->x&&head->y==tem->y){
			system("cls");
			setpos(36,10);
			printf("你撞到自己啦!游戏结束!");
			setpos(36,15);
			system("pause");
			setpos(36,40);
			destorysnake(head,food);
			system("cls");
			setpos(36,10);
			printf("你想要重新开始游戏吗?");
			setpos(38,11);
			printf("    Y or N:");
			char choice=0;
			scanf("%c",&choice);
			while(choice!='Y'&&choice!='y'&&choice!='N'&&choice!='n'){
			    system("cls");
				setpos(36,10);
				printf("请重新输入!");
				setpos(38,11);
				printf("Y or N:");
				scanf("%c",&choice);
			}
			system("cls");
			return choice;
		}
		tem=tem->next;
	}
	return 'C';
}
//移动蛇 吃食物 结束游戏 等等
char movesnake(snake **head,snake* food){
	int num=1;
	while(1){
		
		if(num!=2&&PRESS(VK_UP)==1){
			num=1;}
		else if(num!=1&&PRESS(VK_DOWN)==1){
			num=2;
		}
		else if(num!=4&&PRESS(VK_LEFT)==1){
			num=3;
		}
		else if(num!=3&&PRESS(VK_RIGHT)==1){
			num=4;
		}
		food=eatfood(head,food,num);
		switch(num){
		case 1:
			snake* another=(snake*)malloc(sizeof(snake));
			another->y=(*head)->y-1;
			another->x=(*head)->x;
			another->next=*head;
			*head=another;
			snake *tem1=*head;
			while(tem1->next->next){
				tem1=tem1->next;
			}
			setpos(tem1->next->x,tem1->next->y);
			printf(" ");
			free(tem1->next);
			tem1->next=NULL;
			printsnake(*head);
			break;
		case 2:
			snake* another2=(snake*)malloc(sizeof(snake));
			another2->y=(*head)->y+1;
			another2->x=(*head)->x;
			another2->next=*head;
			*head=another2;
			snake *tem2=(*head);
			while(tem2->next->next){
				tem2=tem2->next;
			}
			setpos(tem2->next->x,tem2->next->y);
			printf(" ");
			free(tem2->next);
			tem2->next=NULL;
			printsnake(*head);
			break;
		case 3:
			snake* another3=(snake*)malloc(sizeof(snake));
			another3->y=(*head)->y;
			another3->x=(*head)->x-1;
			another3->next=*head;
			*head=another3;
			snake *tem3=(*head);
			while(tem3->next->next){
				tem3=tem3->next;
			}
			setpos(tem3->next->x,tem3->next->y);
			printf(" ");
			free(tem3->next);
			tem3->next=NULL;
			printsnake(*head);
			break;
		case 4:
			snake* another4=(snake*)malloc(sizeof(snake));
			another4->y=(*head)->y;
			another4->x=(*head)->x+1;
			another4->next=*head;
			*head=another4;
			snake *tem4=(*head);
			while(tem4->next->next){
				tem4=tem4->next;
			}
			setpos(tem4->next->x,tem4->next->y);
			printf(" ");
			free(tem4->next);
			tem4->next=NULL;
			printsnake(*head);
			break;}
		//控制移动速度
		if(((GetAsyncKeyState(0x46)&0x8000)?1:0)){
			Sleep(100);
		}
		else if(((GetAsyncKeyState(0x53)&0x8000)?1:0)){
			Sleep(300);
		}
		else{
		Sleep(200);
		}
		//结束游戏
		char a=endgame(*head,food);
		if(a=='Y'||a=='y'){
			return 'Y';
		}
		else if(a=='N'||a=='n'){
			return 'N';
		};
		//显示分数
		setpos(66,5);
		printf("你的分数为:%5d",score);
		//暂停游戏
		if(PRESS(VK_SPACE)){
			while(1){
				Sleep(300);
				if(PRESS(VK_SPACE)){
					break;
				}
			}
		}
		
	}
}
//隐藏鼠标函数
void hidemouse(){
	HANDLE output=NULL;
	output=GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO info;
	GetConsoleCursorInfo(output,&info);
	info.bVisible=false;
	SetConsoleCursorInfo(output,&info);
}
//设置光标位置
void setpos(short x,short y){
	COORD pos={x,y};
	HANDLE output=NULL;
	output=GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(output,pos);
}
void gametable(){
	//隐藏鼠标
	hidemouse();
	//打印欢迎界面
	setpos(36,10);
	printf("欢迎来到贪吃蛇小游戏!");
	setpos(38,20);
	system("pause");
	system("cls");
	//打印提示界面
	setpos(36,10);
	printf("提示:↑ ↓ ← →移动");
	setpos(38,20);
	system("pause");
	system("cls");
	//打印地图
	for(int i=0;i<=58;i++){
		setpos(i,0);
		printf("@");
	}
	for(int i=0;i<=58;i++){
		setpos(i,26);
		printf("@");
	}
	for(int i=1;i<=25;i++){
		setpos(0,i);
		printf("@");
	}
	for(int i=1;i<=25;i++){
		setpos(58,i);
		printf("@");
	}
	setpos(66,8);
	printf("提示:↑ ↓ ← →移动");
	setpos(66,10);
	printf("提示:一直按F键可以加速");
	setpos(66,11);
	printf("      一直按S键可以减速");
	setpos(66,12);
	printf("      按空格键可以暂停开始游戏");
	
}
game.c

主函数文件

#include "snake.h"
typedef struct snake snake;
int main(){
	//设置随机种子
	srand(time(0));
	//设置命令行界面
	system("mode con cols=100 lines=30");
	system("title 贪吃蛇");
	char choice='Y';
	while(choice=='Y'){
	gametable();
	snake* head=initsnake();
	printsnake(head);
	snake* food=printfood(head); 
	choice=movesnake(&head,food);
	}
	system("cls");
	setpos(40,10);
	printf("游戏结束啦!");
	setpos(38,20);
	system("pause");
	
}

总结:

咳咳,偷懒了,在原有函数上疯狂加功能,并没有把其他功能封装为函数,估计几天后我就看不懂自己写的贪吃蛇了,希望没有什么其他的bug。

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值