C语言双人贪吃蛇

其实我写的博客,主要还是给自己看的吧,让自己随时随地可以查阅。不都说,这篇是贪吃蛇的。希望能给看到的萌新小伙伴一点启发吧,也欢迎大佬指点。
贪吃蛇主要有以下几个问题:
1.地图如何产生?
2.蛇如何画?蛇尾巴如何在每次吃到食物的时候自增一格?蛇的移动如何实现?
3.如何判定蛇的状态,即吃到食物还是撞到障碍物?

1.对于第一个问题,实际上比较容易解决,就是利用一个二维数组,通过不同的值来打印出不同的图案。比如一个3*2的二维数组,1 1 1
1 0 1
1 1 1 然后再值是1 的地方打印#,在值是0的地方打印空格。这就可以实现地图的绘制。利用不同的数字来代表不同的属性。
2.
蛇如何画?先来看一条蛇 @ 3,6
@ 3,7
@ 3,8
@ 从上到下,坐标分别是 3,9 我们发现,一个蛇也可以用数组来显示,数组定义二维的,存储横纵坐标。 但是,千万不要漏掉了蛇的长度。之后会讲到。
如何画蛇?通过上诉坐标,实际上只需要gotoxy(3,6);然后printf("@");其他的几个蛇身也是这样画出来。那么这里遇到一个问题,利用一个for循环就可以,但是循环多少次呢?这里就要用到一个变量来存储蛇的长度*****
会画蛇了以后还要会让蛇移动,这里举个例子向右移动,还是上例蛇
@@ 3,6 4,6
@ 3,7
@ 3,8 可以看到,原来第一个坐标3,6变成第二个的坐标,原来第二个坐标3,7变成第三个坐标。 把坐标往后移位就可以实现新的蛇坐标。 蛇头的坐标需要相应的改变,这个简单不多说
做到这一步,蛇移动已经差不多了,但是会发现,蛇的尾巴画出来的@还存在,为了消去这个蛇尾,可以在蛇的尾部打上空格来覆盖掉这个蛇尾。 但是,聪明的小伙伴已经想到了,如果吃了东西,其实会边长一格,那么这个变长的蛇格就是原来的蛇尾,那么这时候又要打印出蛇尾的@ 说了这么多,是不是已经知道需要把蛇尾坐标单独存储了呀

3.判定蛇的状态,这个就是利用蛇头坐标是不是在食物,比如蛇头转向以后坐标是4,6那么可以看看二维数组坐标对应的6行4列是不是金币属性还是障碍物属性等等。根据不同的就可以进行不同的操作。

然后,到这里基本上就没有什么问题了吧,下面附上源代码。是双人贪吃蛇,代码很杂乱,不适合阅读,而且因为是两只蛇,有的地方可以更简略一些我也懒得改了。还做了一点改变颜色的什么的,还有自己做了一点简略的菜单加上,emmmmm瞎搞的玩意。目前模式1还没有做,单人和双人的操作都可以。代码是真的很乱,自己都不怎么想去整改了,核心思想都写上面了,希望可以帮助到有需之人吧。

#include
#include
#include
#include
#include
#include
#include
#define H 20
#define L 80  //H high高度 L long长度
#define UP 0
#define DOWN 1
#define LEft 2
#define RIGHT 3
#define mmlong 3  //这是蛇长 
//蛇1 
int map[H][L] ={0};            //地图,H行,L列
int snake[1000][2] = {0};      //蛇,0列代表x坐标,1列代表y坐标 
int snake_long = mmlong;            //蛇初始长度4个
int direction = UP;            //蛇头方向,初始向上 
int tail[2]={0};               //寄存蛇尾
int speed = 300,game_in = 3;   //控制蛇速度
int score = 0;                 //蛇1分数 
//蛇2
int snake_2[1000][2] = {0};      //蛇,0列代表x坐标,1列代表y坐标 
int snake_long_2 = mmlong;            //蛇初始长度4个
int direction2 = UP;            //蛇头方向,初始向上 
int tail_2[2]={0};               //寄存蛇尾
int speed_2 = 300;               //控制蛇速度
int score_2 = 0;                 //蛇2分数
//通用
int target = 0,time_game = 0;    //time_game 游戏对于模式 
void gotoxy(int i,int j)       //移动光标
{
    COORD position={i,j};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),position);
}
void color(int x)	                       //改变输出颜色 
{
	if( x>= 0 && x<= 15)                   //参数在0-15的范围颜色
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);	//只有一个参数x,改变字体颜色
	}
	else//默认的颜色白色
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
	}	

}
void product_map() //地图数据初始化 
{
	int i,j,c = 0;
	snake_long = snake_long_2 = mmlong; //蛇初始4长度
	speed = speed_2 = 300;    //蛇速度初始300
	score = score_2 = 0;      //初始分数初始化0 
	emd:
	c++;
	srand(time(NULL)+c*100);
	direction = rand()%4;  //给蛇1一个随机方向,但不能向下 
	if(direction == 1)
	goto emd; 
	hmd:
	c++;
	srand(time(NULL)+c*100);
	direction2 = rand()%4;  //给蛇2一个随机方向,但不能向下 
	if(direction2 == 1)
	goto hmd;
	for(i = 0;i0;i--)  //后移赋值 把后一个等于前一个的坐标,实现移动 
	{
		snake[i][0] = snake[i-1][0];
		snake[i][1] = snake[i-1][1];
	}	
}
void move_snake2()  //蛇2身移动
{
	int i;
	tail_2[0] = snake_2[snake_long-1][0];
	tail_2[1] = snake_2[snake_long-1][1];  //寄存蛇尾 
	gotoxy(snake_2[snake_long_2-1][0],snake_2[snake_long_2-1][1]);
	printf(" ");       //把蛇尾画空格
	for(i = snake_long_2-1;i>0;i--)  //后移赋值 把后一个等于前一个的坐标,实现移动 
	{
		snake_2[i][0] = snake_2[i-1][0];
		snake_2[i][1] = snake_2[i-1][1];
	}	
}
void move_snake_head() //蛇1头移动
{
	switch(direction)
	{
		case 0:snake[0][1]--;break;//向上 
		case 1:snake[0][1]++;break;//向下 
		case 2:snake[0][0]--;break;//向左 
		case 3:snake[0][0]++;break;//向右 
	}
 }
 void move_snake_head2() //蛇2头移动
{
	switch(direction2)
	{
		case 0:snake_2[0][1]--;break;//向上 
		case 1:snake_2[0][1]++;break;//向下 
		case 2:snake_2[0][0]--;break;//向左 
		case 3:snake_2[0][0]++;break;//向右 
	}
 } 
void direction_snake() //蛇方向(蛇头)
{
	switch(getch())
	{
		case 0xE0:switch(getch())
				 {
				 	   case 72:if(direction2 != 1) //当前不是向下走就可以向上走 
									direction2 = 0;break;
					   case 80:if(direction2 != 0) //当前不是向下走就可以向上走 
									direction2 = 1;break;
					   case 75:if(direction2 != 3) //当前不是向下走就可以向上走 
									direction2 = 2;break;
					   case 77:if(direction2 != 2) //当前不是向下走就可以向上走 
									direction2 = 3;break;
				 }break; 
		case 'w':
		case 'W':if(direction != 1) //当前不是向下走就可以向上走 
					direction = 0;break; 
		
		case 's':
		case 'S':if(direction != 0) //当前不是向上走就可以向下走 
					direction = 1;break;
		case 'a':
		case 'A':if(direction != 3) //当前不是向右走就可以向左走 
					direction = 2;break;
		case 'd':
		case 'D':if(direction != 2) //当前不是向左走就可以向右走 
					direction = 3;break;
		default :break;
	}
}
void check_snake()  //检查蛇1状态 
{
	void message_snake();   //打印蛇1信息
	int i,j;
	color(8); 
	if(map[snake[0][1]][snake[0][0]] == 2) //蛇头的横坐标是行标,纵坐标是列标,吃到食物,蛇边长1格,吃到金钱后 
	{                                      //立马重新产生金钱 
		snake_long++;
		score += 100;
		snake[snake_long-1][0] = tail[0];
		snake[snake_long-1][1] = tail[1];
		speed -= 35;
		if(speed<100)
		speed = 100;
		for(i = 0;i= target)
	{
			Sleep(1500);
			system("cls");
			gotoxy(L/2,H/2);
			printf("蛇1率先达到目标分数,获得胜利\n");
			Sleep(1500);
			gotoxy(L/2-4,H/2+1);
			printf("再来一次?(Y/y)   退出(N/n)  按0返回功能菜单");
			shuru2:
			switch(getch())
			{
				case '0':game_in = 2;goto eee;break;
				case 'y':
				case 'Y':game_in = 1;goto eee;break;
				case 'n':
				case 'N':game_in = 0;goto eee;break;
				default:goto shuru2; 
			}
	 }
	if(map[snake[0][1]][snake[0][0]] == 1) //撞到边界或者障碍物,输了 
	{
			Sleep(1500);
			system("cls");
			gotoxy(L/2,H/2);
			printf("蛇1撞到障碍物,蛇2获胜\n");
			Sleep(1500);
			gotoxy(L/2-4,H/2+1);
			printf("再来一次?(Y/y)   退出(N/n)   按0返回功能菜单");
			shuru:
			switch(getch())
			{
				case '0':game_in = 2;break;
				case 'y':
				case 'Y':game_in = 1;break;
				case 'n':
				case 'N':game_in = 0;break;
				default:goto shuru; 
			}
	}
	eee:;	
} 
void check_snake2()  //检查蛇2状态 
{
	int i,j;
	void message_snake2();   //打印蛇2信息
	color(8);
	if(map[snake_2[0][1]][snake_2[0][0]] == 2) //蛇头的横坐标是行标,纵坐标是列标,吃到食物,蛇边长1格,吃到金钱后 
	{                                      //立马重新产生金钱 
		snake_long_2++;
		score_2 += 100;
		snake_2[snake_long_2-1][0] = tail_2[0];
		snake_2[snake_long_2-1][1] = tail_2[1];
		speed_2 -= 35;
		if(speed_2<100)
		speed_2 = 100;
		for(i = 0;i= target)
	{
			Sleep(1500);
			system("cls");
			gotoxy(L/2,H/2);
			printf("蛇2率先达到目标分数,获得胜利\n");
			Sleep(1500);
			gotoxy(L/2-4,H/2+1);
			printf("再来一次?(Y/y)   退出(N/n)   按0返回功能菜单");
			shuru:
			switch(getch())
			{
				case '0':game_in = 2;goto eee;break;
				case 'y':
				case 'Y':game_in = 1;goto eee;break;
				case 'n':
				case 'N':game_in = 0;goto eee;break;
				default:goto shuru; 
			}
	 }
	if(map[snake_2[0][1]][snake_2[0][0]] == 1) //撞到边界或者障碍物,输了 
	{
			Sleep(1500);
			system("cls");
			gotoxy(L/2,H/2);
			printf("蛇2撞到障碍物,蛇1获胜\n");
			Sleep(1500);
			gotoxy(L/2-4,H/2+1);
			printf("再来一次?(Y/y)   退出(N/n)   按0返回功能菜单");
			shuru2:
			switch(getch())
			{
				case '0':game_in = 2;break;
				case 'y':
				case 'Y':game_in = 1;break;
				case 'n':
				case 'N':game_in = 0;break;
				default:goto shuru2; 
			}
	}
	eee:;	
}
int menu()  //功能菜单
{
	CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);    //隐藏关标
	int i,m,c = 0;
	if(time_game == 2)
	goto moshi2;
	else if(time_game == 3)
	goto moshi3;
	else if(time_game == 4)
	goto kaishi;
	 
	color(12); 
	gotoxy(36,2);
	printf("小小贪吃蛇");
	gotoxy(6,5);
	color(8);
	printf("1.闯关模式");
	gotoxy(26,5);
	printf("2.单人游戏");
	gotoxy(46,5);
	printf("3.双人游戏");
	gotoxy(66,5);
	printf("4.结束游戏");
	gotoxy(1,13);
	printf("  Loading......\n");
	
	do
	{
		
		for(i = 10,m = 1;i<60;i++,m+=2)
		{
			color(8);
			gotoxy(75,13);
			printf("    ");
			gotoxy(75,13);
			printf("%-2d%%",m);
			gotoxy(75,13);
			printf("    ");
			gotoxy(75,13);
			printf("%-2d%%",m+1);
			gotoxy(i+5,14);
			color(3);
			printf("》");	
			Sleep(i+m);
			c++;
			if(c == 50)
			goto end;
			
		}
		gotoxy(1,14);
		for(i = 0;i<79;i++)
		{
			printf(" ");	
		}
		
	}while(1);
	end:
		kaishi:;
		color(12); 
		gotoxy(36,2);
		printf("小小贪吃蛇");
		gotoxy(6,5);
		color(8);
		printf("1.闯关模式");
		gotoxy(26,5);
		printf("2.单人游戏");
		gotoxy(46,5);
		printf("3.双人游戏");
		gotoxy(66,5);
		printf("4.结束游戏");
		color(3);		
		gotoxy(1,14);
		for(i = 0;i<79;i++)
		{
			printf(" ");	
		}
		gotoxy(1,13);
		printf("                 ");
		gotoxy(34,7);
		printf("请按相应序号进行选择");
		switch(getch())
		{
			case '1':system("cls");break;    //闯关 
			case '2':moshi2:;
					 system("cls");
					 gotoxy(36,7);printf("游戏说明");
					 gotoxy(32,8);printf("单人模式,设定一个目标分,达到即可胜利");
					 gotoxy(32,9);printf("每吃到一个金币,分数增加100分");
					 gotoxy(32,10);printf("撞到边界或障碍物,游戏失败");
					 gotoxy(32,11);printf("请输入目标分数:");color(8);fflush(stdin);scanf("%d",&target);
					 return 2; 
			case '3':moshi3:;
					 system("cls");
					 gotoxy(36,7);printf("游戏说明");
					 gotoxy(32,8);printf("双人对战,率先达到目标分数的一方获得胜利");
					 gotoxy(32,9);printf("每吃到一个金币,分数增加100分");
					 gotoxy(32,10);printf("撞到边界或障碍物,对方获胜");
					 gotoxy(32,11);printf("请输入目标分数:");color(8);fflush(stdin);scanf("%d",&target);
					 return 3; 
			case '4':return 4;
			default :break; 
			
		 } 
   }
   
void message_snake()  //打印蛇1信息
{
	gotoxy(5,H+1);
	color(11); 
	printf("玩家1--蛇1");
	gotoxy(5,H+2);
	printf("得分:%d",score);
	gotoxy(5,H+3);
	printf("上  下  左  右");
	gotoxy(5,H+4);
	printf("W/w S/s A/a D/d");
	gotoxy(27,H+1);
	printf("目标分数:%d",target);	
}

void message_snake2()  //打印蛇2信息
{
	gotoxy(50,H+1);
	color(11); 
	printf("玩家2--蛇2");
	gotoxy(50,H+2);
	printf("得分:%d",score_2);
	gotoxy(50,H+3);
	printf("上  下  左  右");
	gotoxy(50,H+4);
	printf(" ↑  ↓ ←   →");	
}   
int main()
{
	CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);    //隐藏关标
	int i;
	menu1:
	system("cls");
	i = menu();     //功能菜单
	if(i == 3)
		goto play3;
	else if(i == 2)
		goto play2;
	else if(i == 4)
		goto over_game; 
	play3: 
    game_in = 3;
	product_map(); //地图产生
	money_product();//产生金钱 
	draw_map();    //画地图
	draw_snake();  //画蛇1
	draw_snake2();
	message_snake();  //打印蛇1信息
	message_snake2();  //打印蛇2信息
	color(8);
	gotoxy(L/2-10,H/2);
	system("pause");
	gotoxy(L/2-10,H/2);
	printf("                                       "); 
	do //双人贪吃蛇 
	{
		CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);    //隐藏关标
		move_snake();  //蛇1身移动
		move_snake_head(); //蛇1头移动
		check_snake();     //检查蛇1状态
		move_snake2();  //蛇2身移动
		move_snake_head2(); //蛇2头移动
		check_snake2();     //检查蛇2状态
		draw_snake();
		draw_snake2();
		if(game_in == 0)    // game_in0 结束游戏,1这个模式重开,2返回功能菜单 
		goto over_game;
		else if(game_in == 1)
		{
			time_game = 3;
			goto menu1;
		}
		else if(game_in == 2)
		{
			time_game = 4;
			goto menu1;
		}
		draw_snake();
		draw_snake2();
		Sleep(speed

你可能感兴趣的:(C语言双人贪吃蛇)