贪吃蛇源码

//贪吃蛇大作战 
#include <stdio.h>
#include <time.h> 
#include <windows.h> //控制界面 
#include <stdlib.h>  //宏和通用工具函数 
#include <conio.h>   //接收键盘输入/输出
#include <unistd.h>  //sleep函数
//宏定义 
#define U 1
#define D 2
#define L 3
#define R 4

//定义蛇节点 
typedef struct snake {
	int x;
	int y;
	struct snake *next;
}snake;
int score = 0,add = 10,highscore = 0;
int status,sleeptime = 200; //status 定义蛇的状态 
snake *head,*food,*q; 
int endgamestatus = 0; //游戏结束时蛇的状态

HANDLE hOut;
void gotoxy(int x,int y);//设置光标位置 
int color(int c);        //更改文字颜色 
void printsnake();       //字符画  蛇 
void welcometogame();    //开始界面 
void createmap();        //绘制地图 
void score_and_tips();   //右侧的得分和小提示 
void init_snake();       //初始化蛇身 画蛇身 
void createfood();       //创建并随机出现食物 
int biteself();          //判断是否咬到自己 
void crosswall();        //设置蛇撞墙的情况 
void speedup();          //加速 
void speeddown();        //减速 
void snakemove();        //控制蛇的移动方向 
void keyboardControl();  //控制键盘按键 
void lostdraw();         //游戏结束画面 
void endgame();          //游戏结束 
void choose();           //结束后的选择 
void File_out();         //文件读取最高分 
void File_in();          //储存最高分 
void explation();        //游戏说明 

//主函数
int main (){
	system("mode con cols=100 lines=43");//43行100列 
	printsnake();                        //字符蛇 
	welcometogame();                       
	keyboardControl();  
	endgame(); 
	return 0;
} 

//设置文字颜色 
int color(int c){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
	//以上设置控制台窗口字体颜色和背景色的函数 
	return 0;
}	
//获得控制台的坐标位置 
void gotoxy(int x,int y){
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
	//以上函数是控制光标位置的函数 
} 
//字符蛇 
void printsnake(){
	color(2);
	gotoxy(20,1);
	printf("                   $$$$$$");
	gotoxy(20,2);
	printf("                $$__$$_$$$");
	gotoxy(20,3);
	printf("           Y   $____ff___$$§§");
	gotoxy(20,4);
	printf("           ┕---ffff________$§§§");
	gotoxy(20,5);
	printf("                $$$$$$___$__$§§§");
	gotoxy(20,6);
	printf("                  §§§$$___$ $§§§§");
	gotoxy(20,7);
	printf("                 §§§§§$___$_$§§§§§");
	gotoxy(20,8);
	printf("                 §§§§§$___$$$§§§§§");
	gotoxy(20,9);
	printf("                 §§§§$$_$___$§§§§§");
	gotoxy(20,10);
	printf("                §§§§§§$__$_$$§§§§§");
	gotoxy(20,11);
	printf("                §§§§§$$___$$§§§§§§");
	gotoxy(20,12);
	printf("               §§§§§§$__$_$$§§§§§");
	gotoxy(20,13);
	printf("               §§§§$$___$_$§§§§§");
	gotoxy(20,14);
	printf("               §§§$$___$_$$§§§§");
	gotoxy(20,15);
	printf("                §$$____$_$§§§§");
	gotoxy(20,16);
	printf("                 $____$_$$§§");
	gotoxy(20,17);
	printf("                $$___$__$$");
	gotoxy(20,18);
	printf("               $$______$$");
	gotoxy(20,19);
	printf("               $______$$_$");
	gotoxy(20,20);
	printf("              $$_____$$_$$$______$$$$$$$$$$$");
	gotoxy(20,21);
	printf("              $______$___$$$$$$$$___________$");
	gotoxy(20,22);
	printf("       $$$$$_$$___$_$$____$$$$$$____$$$______$");
	gotoxy(20,23);
	printf("   $$$$____$$$$_$_$_$$$$$$$$____$$$$$$$$$$$__$");
	gotoxy(20,24);
	printf("  $$____$____$$___$_$$______$$$$__________$$$$$");
	gotoxy(20,25);
	printf(" $_____$______$_$___$$_$$$$$____________$_____$$$");
	gotoxy(20,26);
	printf("$______$$$$$$$$____$_$$$_________________$$_____$$");
	gotoxy(20,27);
	printf("$______$$_____$_$____$$__________$$$$$$$$$$______$");
	gotoxy(20,28);
	printf("$$_______$$$$_$$_$$_$_$$_____$$$$$$_______$______$");
	gotoxy(20,29);
	printf(" $$____________$$____$_$$$$$$$__________$$_______$");
	gotoxy(20,30);
	printf("   $$___________$_____$__$$$_______$$$$$$_______$$");
	gotoxy(20,31);
	printf("    $$$$$_ ___$$$________$$$$$$$$$___________$$");
	gotoxy(20,32);
	printf("       $$$$$$$$$$_$$$________________________$$$");
	gotoxy(20,33);
	printf("                    $$$$__________________$$$$");
	gotoxy(20,34);
	printf("                        $$$$$$$$$$$$$$$$$$$");
}
//欢迎界面
void welcometogame(){
	int n,i,j=1; 
	color(11);
	gotoxy(40,35);
	printf("贪 吃 蛇 大 作 战");
	color(14);
	for(i=36;i<=41;i++){ //i是行 j是列 
		for(j=23;j<=73;j++){
			gotoxy(j,i);
			if(i == 36 || i == 41){
				printf("-");
			}else if(j == 23 ||j == 73){
				printf("|");
			}
		}
	}
	color(12);
	gotoxy(32,38);
	printf("1.开始游戏"); 
	gotoxy(43,38);
	printf("2.游戏说明");
	gotoxy(54,38);
	printf("3.退出游戏");
	color(3);
	gotoxy(39,40);
	printf("请选择[1 2 3]: [ ]\b\b");
	color(14);
	scanf("%d",&n);
	switch(n){
		case 1:
			system("cls");
			createmap(); //打印地图 
			init_snake(); //初始化蛇身 
			createfood(); //创造食物 
			break;
		case 2:
			explation();  //说明 
			break;
		case 3:
			exit(0);
			break;
	}
	while ((getchar())!='\n');
}
//创建地图
void createmap(){
	int x,y; //8 <= x <=90 //1<= y <= 25
	for (x=8;x<=90;x+=2){ //上下边框
		gotoxy(x,1);//一个方框左右是占两个字符的
		color(7);
		printf("■");
		gotoxy(x,25);
		printf("■");
	}
	for (y=2;y<=24;y++){ //左右边框 
		gotoxy(8,y);
		printf("■");
		gotoxy(90,y);
		printf("■");
	}
	for(x=10;x<=88;x+=2){ //内部填充 
		for(y=2;y<=24;y++){
			gotoxy(x,y);
			color(8);
			printf("□");
		}
	}
} 
//游戏界面下侧信息
void score_and_tips(){
	File_out();
	color(14);
	gotoxy(12,31);
	printf("☆现在得分:%d",score);
	color(11);
	gotoxy(35,31);
	printf("☆最高记录:%d",highscore);
	color(13);
	gotoxy(67,27);
	printf("小 提 示"); 
	color(6);
	gotoxy(60,28);
	printf("═══════════════════════════════");
	gotoxy(60,35);
	printf("═══════════════════════════════");
	color(3);
	gotoxy(61,29);
	printf("1.每个食物得分:%d分",add);
	gotoxy(61,30);
	printf("2.不能穿墙,不能咬到自己");
	gotoxy(61,31);
	printf("3.用↑↓←→分别控制移动方向");
	gotoxy(61,32);
	printf("4.F1为加速,F2为减速");
	gotoxy(61,33);
	printf("5.space :暂停游戏");
	gotoxy(61,34);
	printf("6.Esc :退出游戏\n");
}
//在文件中读取最高分
void File_out(){
	FILE  *fp;
	fp = fopen("save.txt","a+");
	fscanf(fp,"%d",&highscore);
	fclose(fp);
}
//绘制蛇身
void init_snake(){
	snake *tail;
	int i;
	tail = (snake*)malloc(sizeof(snake)); 
	tail->x = 30;
	tail->y = 20;
	tail->next = NULL;
	for (i=1;i<=4;i++){
		head = (snake*)malloc(sizeof(snake));
		head->next = tail;
		head->x = 30+2*i;
		head->y = 20;
		tail = head; //从尾部开始能更好的保留head的值为头部 
	}
	while(tail != NULL){
		gotoxy(tail->x,tail->y);
		color(14);
		printf("◆");
		tail = tail->next;
	}
}
//创建并随机出现食物 
void createfood(){
	snake *food_1;
	food_1 = (snake*)malloc(sizeof(snake));
	srand(time(NULL));
	
	do{
		food_1->x = rand()%79+9;
		
	}while((food_1->x % 2) != 0);
	food_1->y = rand()%22+3;
	q = head;
	while(q->next != NULL){
		if(q->x == food_1->x && q->y == food_1->y){
			free(food_1);
			createfood();
		}
		q=q->next;
	} 
	gotoxy(food_1->x,food_1->y);
	food = food_1;
	color(rand()%14+1);
	printf("※");
	gotoxy(0,30);
} 
//判断是否咬到自己
int biteself(){
	snake *self;
	self = head->next;
	while(self != NULL){
		if(self->x == head->x && self->y == head->y){
			return 1;
		}
		self = self->next;
	}
	return 0;
}
//判断蛇是否撞墙
void crosswall(){
	if(head->x == 8 || head->x == 90|| head->y == 1|| head->y == 25){
		endgamestatus = 1;
		endgame();
	}
} 
//加速
void speedup(){
	if(sleeptime > 100){
		sleeptime = sleeptime - 20;
		add += 2;
	}
} 
//减速
void speeddown(){
	if(sleeptime < 300){
		sleeptime = sleeptime + 20;
		add -= 2;
		if(sleeptime == 300){
			add = 1;
		}
	}
} 
//控制方向移动 
void snakemove(){
	snake *nexthead;
	nexthead = (snake*)malloc(sizeof(snake)); 
	crosswall();//判断蛇是否撞墙
	if(status == U) {
		nexthead->x = head->x;
		nexthead->y = head->y-1;
	}
	else if(status == D) {
		nexthead->x = head->x;
		nexthead->y = head->y+1;
	}
	else if(status == L) {
		nexthead->x = head->x-2;
		nexthead->y = head->y;
	}
	else if(status == R) {
		nexthead->x = head->x+2;
		nexthead->y = head->y;
		}
	nexthead->next = head;
	head = nexthead;
	q = head; //q用来遍历蛇身且保留head值
	srand(time(NULL));
	if(nexthead->x == food->x && nexthead->y == food->y){
		//有食物 
		while(q != NULL){
			gotoxy(q->x,q->y);
			color(14);
			printf("◆");
			q = q->next;
		}
		score += add;
		speedup();
		createfood();  
	}
	else{
		//没有食物 
		while(q->next->next != NULL){ 
		      //新头增加了一格所以遍历到新蛇尾 
			gotoxy(q->x,q->y);
			color(14);
			printf("◆");
			q = q->next;
		}
		//q已经遍历到新的蛇尾 
		//但原来的蛇尾并没有消失
		gotoxy(q->next->x,q->next->y);
		color(8);
		printf("□"); //打印地图方块
		free(q->next);
		q->next = NULL;
	}
	if (biteself() == 1){
		endgamestatus = 2;
		endgame();
	}
} 
//控制键盘按键
void keyboardControl(){
	status=R;
	while(1){
		score_and_tips();
		if(GetAsyncKeyState(VK_UP) && status != D){
			//GetAsyncKeyState函数用来判断键盘状态 
			status = U;
		}
		else if(GetAsyncKeyState(VK_DOWN) && status != U){
			//GetAsyncKeyState函数用来判断键盘状态 
			status = D;
		}
		else if(GetAsyncKeyState(VK_LEFT) && status != R){
			//GetAsyncKeyState函数用来判断键盘状态 
			status = L;
		}
		else if(GetAsyncKeyState(VK_RIGHT) && status != L){
			//GetAsyncKeyState函数用来判断键盘状态 
			status = R;
		}
		if(GetAsyncKeyState(VK_SPACE)){
			while(1){
				Sleep(300);
				if(GetAsyncKeyState(VK_SPACE)) {
					break; //再次按空格键继续 
				}
			}
		}
		else if(GetAsyncKeyState(VK_ESCAPE)){
			endgamestatus = 3;
			break;
		}
		else if(GetAsyncKeyState(VK_F1)){
			speedup();
		}
		else if(GetAsyncKeyState(VK_F2)){
			speeddown();
		}
		Sleep(sleeptime);//刷新时间间隔 
		snakemove();     //不按键时保持前进 
	}
}
//失败界面图案 
void lostdraw(){
	
	color(2);
	gotoxy(10,1);
	printf("                   $$$$$$");
	gotoxy(10,2);
	printf("                $$__$$_$$$");
	gotoxy(10,3);
	printf("           Y   $____ff___$$§§");
	gotoxy(10,4);
	printf("           ┕---ffff________$§§§");
	gotoxy(10,5);
	printf("                $$$$$$___$__$§§§");
	gotoxy(10,6);
	printf("                  §§§$$___$ $§§§§");
	gotoxy(10,7);
	printf("                 §§§§§$___$_$§§§§§");
	gotoxy(10,8);
	printf("                 §§§§§$___$$$§§§§§");
	gotoxy(10,9);
	printf("                 §§§§$$_$___$§§§§§");
	gotoxy(10,10);
	printf("                §§§§§§$__$_$$§§§§§");
	gotoxy(10,11);
	printf("                §§§§§$$___$$§§§§§§");
	gotoxy(10,12);
	printf("               §§§§§§$__$_$$§§§§§");
	gotoxy(10,13);
	printf("               §§§§$$___$_$§§§§§");
	gotoxy(10,14);
	printf("               §§§$$___$_$$§§§§");
	gotoxy(20,15);
	printf("                §$$____$_$§§§§");
	gotoxy(10,16);
	printf("                 $____$_$$§§");
	gotoxy(10,17);
	printf("                $$___$__$$");
	gotoxy(10,18);
	printf("               $$______$$");
	gotoxy(10,19);
	printf("               $______$$_$");
	gotoxy(10,20);
	printf("              $$_____$$_$$$______$$$$$$$$$$$");
	gotoxy(10,21);
	printf("              $______$___$$$$$$$$___________$");
	gotoxy(10,22);
	printf("       $$$$$_$$___$_$$____$$$$$$____$$$______$");
	gotoxy(10,23);
	printf("   $$$$____$$$$_$_$_$$$$$$$$____$$$$$$$$$$$__$");
	gotoxy(10,24);
	printf("  $$____$____$$___$_$$______$$$$__________$$$$$");
	gotoxy(10,25);
	printf(" $_____$______$_$___$$_$$$$$____________$_____$$$");
	gotoxy(10,26);
	printf("$______$$$$$$$$____$_$$$_________________$$_____$$");
	gotoxy(10,27);
	printf("$______$$_____$_$____$$__________$$$$$$$$$$______$");
	gotoxy(10,28);
	printf("$$_______$$$$_$$_$$_$_$$_____$$$$$$_______$______$");
	gotoxy(10,29);
	printf(" $$____________$$____$_$$$$$$$__________$$_______$");
	gotoxy(10,30);
	printf("   $$___________$_____$__$$$_______$$$$$$_______$$");
	gotoxy(10,31);
	printf("    $$$$$_ ___$$$________$$$$$$$$$___________$$");
	gotoxy(10,32);
	printf("       $$$$$$$$$$_$$$________________________$$$");
	gotoxy(10,33);
	printf("                    $$$$__________________$$$$");
	gotoxy(10,34);
	printf("                        $$$$$$$$$$$$$$$$$$$");
}
//结束游戏界面 
void endgame(){
	system("cls");
	gotoxy(62,6);
	color(3);
	printf("┍┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┑");
	gotoxy(62,20);
	printf("┕┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┉┙");
	if(endgamestatus == 1){
		lostdraw();
		gotoxy(65,8);
		color(12);
		printf("小蛇撞墙了,gameover!"); 
	}
	else if(endgamestatus == 2){
		lostdraw();
		gotoxy(65,8);
		color(12);
		printf("小蛇咬到自己了,gameover!"); 
	}
	else if(endgamestatus == 3){
		lostdraw();
		gotoxy(65,8);
		color(12);
		printf("你结束了游戏。"); 
	}
	gotoxy(65,13);
	color(13);
	printf("你的得分是:%d",score);
	if(score > highscore){
		color(10);
		gotoxy(65,18);
		printf("创造新纪录!刷新了最高记录");
		File_in(); 
	}
	else{
		color(10);
		gotoxy(65,18);
		printf("继续努力,你离最高分还差:%d",highscore-score);
	}
	choose();
}
//文件写入最高分 
void File_in(){
	FILE *fp;
	fp = fopen("save.txt","w+");
	fprintf(fp,"%d",score);
	fclose(fp);
} 
//最后游戏结束的选框 
void choose(){
	int n,i;
	gotoxy(71,24);
	color(5);
	printf("----------------");
	gotoxy(71,30);
	printf("----------------");
	for(i=0;i<5;i++){
		gotoxy(71,25+i);
		printf("|");
		gotoxy(86,25+i);
		printf("|");
	}
	gotoxy(73,26);
	color(12);
	printf("重新开始(1)");
	gotoxy(73,28);
	printf("退出游戏(2)");
	gotoxy(80,35);
	color(12);
	printf("选择: "); 
	scanf("%d",&n);
	switch (n){
		case 1:
			system("cls");
			score=0;
			sleeptime=200;
			add=10;
			printsnake();  //字符蛇 
			welcometogame(); //欢迎界面 
			keyboardControl();  //游戏运行循环里面有endgame出口 
			endgame();
			break;
		case 2:
			exit(0);
			break;
		default:
			gotoxy(65,37);
			color(12);
			printf("你的输入错误请重新输入"); 
		 	system("pause >nul");
			endgame();
			break;
	} 
}
//游戏说明
void explation(){
	int i,j=1;
	system("cls");
	color(14);
	gotoxy(40,5);
	printf("游  戏  说  明"); 
	for(i=10;i<=90;i++){
		for(j=8;j<=35;j++){
			color(7);
			gotoxy(i,j);
			if(i == 10 ||i == 90){
				printf("|");
			}
			else if(j == 8 || j == 35){
				color(6);
				printf("=");
			}
		}
	}
	color(10);
	gotoxy(28,10);
	printf("tip1: 每 吃 一 个 果 子 速 度 就 会 增 加"); 
	gotoxy(28,13);
	printf("tip2: 用 ↑↓←→分 别 控 制 方 向");
	gotoxy(28,16);
	printf("tip3: F1 为 加 速,F2 为 减 速");
	gotoxy(28,19);
	printf("tip4: 速 度 增 加 后 每 个 果 实 的 分 数 也 会 增 加");
	gotoxy(28,22);
	printf("tip5: 按 空 格 键 暂 停,再 次 按 继 续");
	gotoxy(28,25);
	printf("tip6: Esc:退出游戏,space:暂停游戏");
	gotoxy(28,28);
	printf("tip6: 有 些 果 子 颜 色 比 较 隐 蔽,一定仔细");
	gotoxy(28,31);
	printf("tip6: 按 任 意 键 返 回");
	getch();
	system("cls");
	printsnake();
	welcometogame();
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值