贪吃蛇双人版

最近看到好多人会敲贪吃蛇,我也学起来了。
喝水不忘挖井人!
感谢:https://blog.csdn.net/qq_40694605/article/details/104537168?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
我这个是双人版贪吃蛇:控制键是wasd和1235.下面是代码。等有时间再写注释。
今天有一点时间,开始管管我的屎山 吧_

#include<cstdio>
#include<ctime>
#include<windows.h>
#include<conio.h>
#include<vector>
using namespace std;
//移动光标函数
void gotoxy(int x,int y)//老实说这个函数我也不知道是怎么实现的,反正我是参考大佬的,然后背下来。
{
    
    
	COORD pos = {
    
    x,y};//x,y表示坐标 // 横 : x // 竖 : y
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
//隐藏光标函数
void hidecursor()//这个我也。。。等我会了再说
{
    
    
	CONSOLE_CURSOR_INFO cursor_info = {
    
    1,0};
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
//食物类
class Food
{
    
    
private:
	int m_x,m_y;//食物的坐标
public:
	void srandfood()//产生随机的食物
	{
    
    
		srand((int)time(NULL));
		m_x = 1;//初始化
		while(m_x & 1)//因为实际上在DEVC++控制面板上:一个y == 两个x(为了美观)
//且后面蛇的横坐标初始化也是偶数,//所以要保证食物横坐标也为偶数(建议实践出真理)		
		{
    
    
			m_x = rand() % (85) + 2;//保证2 <= m_x <= 86;
			m_y = rand() % (25) + 2;//保证2 <= m_y <= 26;
		}
		gotoxy(m_x,m_y);//将食物显示在控制面板上
		printf("人"); //食物类型随意(吃人不好吧 *_* 可怕)
	}
	int get_food_x() {
    
    return m_x;}//返回食物的横坐标
	int get_food_y() {
    
    return m_y;}//返回食物的纵坐标
};
//蛇类
class Snake
{
    
    
private:
	struct Snakelocal{
    
    
		int x,y;//来个结构体表示横纵坐标
	};
	//下面我们来两个容器储存蛇的各个部位的坐标
	vector<Snakelocal> snakelocal1;//字母键位的蛇 :蛇一
	vector<Snakelocal> snakelocal2;//数字键位的蛇 :蛇二
	
	void judge_dir(Snakelocal& nexthead1,Snakelocal& nexthead2)
	{
    
    
		static char key1 = 'd';//静态变量是灵魂所在(保存最新的输入方向)
		static char key2 = '3'; //两者初始化不同(这里找了一个晚上加一个早上) bug是一生之敌 :哭哭
		
		if(_kbhit())//_kbhit():当有敲键盘这个操作时,返回值为真
		{
    
    
			char temp = _getch();//不用摁回车键,直接输入
			switch(temp)//判断原来蛇的方向有没有改变的必要
			{
    
    
				case 'w':
				case 's':
				case 'a':
				case 'd':
				//方向相反就不用改变了
					if((temp == 'w' && key1 != 's') || (temp == 's'&& key1 != 'w')\
					|| (temp == 'a' && key1 != 'd') || (temp == 'd' && key1 != 'a'))
					key1 = temp;
					break;
					
				case '1':
				case '2':
				case '3':
				case '5':
					if((temp == '1' && key2 != '3') || (temp == '3'&& key2 != '1')\
					|| (temp == '2' && key2 != '5') || (temp == '5' && key2 != '2'))
					key2 = temp;
					break;
			
				default : break;//使程序具有鲁棒性(开始用专业术语装逼,其实根本不懂^_^)
			}
		}
	//下面分别对两条蛇的蛇头坐标进行处理
	//如果方向不变也要运行下面两个switch(自行领会)
		switch(key1)
		{
    
    
			case 'w':nexthead1.x = snakelocal1[0].x;
					 nexthead1.y = snakelocal1[0].y - 1; break;
			case 's':nexthead1.x = snakelocal1[0].x;
					 nexthead1.y = snakelocal1[0].y + 1; break;
			case 'a':nexthead1.x = snakelocal1[0].x - 2;
					 nexthead1.y = snakelocal1[0].y ;    break;
			case 'd':nexthead1.x = snakelocal1[0].x + 2;
					 nexthead1.y = snakelocal1[0].y ;    break;	 
		}
	
		switch(key2)
		{
    
    
			case '1':nexthead2.x = snakelocal2[0].x - 2;
					 nexthead2.y = snakelocal2[0].y;     break;
			case '3':nexthead2.x = snakelocal2[0].x + 2;
					 nexthead2.y = snakelocal2[0].y;     break;
			case '5':nexthead2.x = snakelocal2[0].x ;
					 nexthead2.y = snakelocal2[0].y - 1; break;
			case '2':nexthead2.x = snakelocal2[0].x ;
					 nexthead2.y = snakelocal2[0].y + 1; break;	
		}
	}
 //终结程序:有人触犯了规则而死亡
	void finish_game(const int score1,const int score2,int flag)
	{
    
    
		system("cls");
		gotoxy(30,10);
		if(flag == 1)
		printf("胜利者为使用字母键位的选手!恭喜!"); 
		else 
		printf("胜利者为使用数字键位的选手!恭喜!");
		gotoxy(30,15);
		printf("字母选手得分为 :%d",score1);
		gotoxy(30,20);
		printf("数字选手得分为 :%d",score2);
		gotoxy(0,25);
		exit(0);//终结程序
	}
	
//判断有没有人犯规
	void judge_finish_game(const int score1,const int score2)
	{
    
    

		for(int i = 1;i < snakelocal1.size();i++)
		{
    
    //蛇一吃到自己的身体
			if(snakelocal1[0].x == snakelocal1[i].x && \
			snakelocal1[0].y == snakelocal1[i].y)
			finish_game(score1,score2,2);
		 //蛇二吃到蛇一的身体
		 	if(snakelocal2[0].x == snakelocal1[i].x && \
			snakelocal2[0].y == snakelocal1[i].y)
			finish_game(score1,score2,1);
		}
//下同
	 	for(int i = 1;i < snakelocal2.size();i++)
		 {
    
    
		 	if(snakelocal2[0].x == snakelocal2[i].x && \
			snakelocal2[0].y == snakelocal2[i].y)
			finish_game(score1,score2,1);
		  
		    if(snakelocal1[0].x == snakelocal2[i].x && \
			snakelocal1[0].y == snakelocal2[i].y)
			finish_game(score1,score2,2); 
		 }

//蛇一碰壁
		if(snakelocal1[0].x >= 88 || snakelocal1[0].x < 0 || \
		snakelocal1[0].y >= 28 || snakelocal1[0].y < 0)
		finish_game(score1,score2,2);
//下同
		if(snakelocal2[0].x >= 88 || snakelocal2[0].x < 0 || \
		snakelocal2[0].y >= 28 || snakelocal2[0].y < 0) 
		finish_game(score1,score2,1);
	} 
public:

	Snake()//应该是叫作构造函数:目的是为了两条蛇的初始化
	{
    
    
		Snakelocal temp1,temp2;
		for(int i = 4;i >= 0;i--)
		{
    
    
			temp1.x = 16 + (i << 1);//横坐标为偶数
			temp1.y = 8;
			
			temp2.x = 16 + (i << 1);
			temp2.y = 20;
			
			snakelocal1.push_back(temp1);//存入容器
			snakelocal2.push_back(temp2);
		}
	}

	void move(Food& food,int& score1,int& score2)
	{
    
    
		Snakelocal nexthead1,nexthead2;//设两个蛇头的坐标
		bool flag1 = true,flag2 = true;//自行体会这两个bool的作用
//经过judge_dir函数得到蛇的蛇头坐标
		judge_dir(nexthead1,nexthead2);
//将**新蛇头**的坐标插在**旧蛇头**的坐标的前面
//此时蛇的长度无条件加一(即使没有吃到食物也加一**是暂时性的,后面会减回来**)
		snakelocal1.insert(snakelocal1.begin(),nexthead1);
		snakelocal2.insert(snakelocal2.begin(),nexthead2); 
//判断规则有没有被破坏
		judge_finish_game(score1,score2); 
//下面让我们更新得分:(我玩自己编写的第一个程序居然连100分都到不了:我还是太菜了*_*)
		gotoxy(0,0);
		printf("让我们猎个痛快!"); 
		gotoxy(0,1); 
		printf("字母蛇得分为 :%d",score1);
		gotoxy(0,2); 
		printf("数字蛇得分为 :%d",score2);
//判断蛇一有没有吃到食物
		if(snakelocal1[0].x == food.get_food_x() && snakelocal1[0].y == \
		food.get_food_y())
		{
    
    
			score1++;
			flag1 = false;
		} 
//下同
		if(snakelocal2[0].x == food.get_food_x() && snakelocal2[0].y == \
		food.get_food_y() && flag1)
		{
    
    	
			score2++;
			flag2 = false;
		} 
//吃到食物就没有必要减少蛇的长度了,没吃到才有必要执行这个函数
		if(flag1)
		{
    
    
			gotoxy(snakelocal1.back().x,snakelocal1.back().y);
			printf("  ");
			snakelocal1.pop_back();
		}
//下同
		if(flag2)
		{
    
    	
			gotoxy(snakelocal2.back().x,snakelocal2.back().y);
			printf("  ");
			snakelocal2.pop_back(); 
		}		
//重新打印蛇的picture:图案
//蛇一
		for(int i = 0;i < snakelocal1.size();i++)
		{
    
    
			gotoxy(snakelocal1[i].x,snakelocal1[i].y);
			if(i == 0) printf("★");
			else printf("■");
		}
//蛇二
		for(int i = 0;i < snakelocal2.size();i++)
		{
    
    
			gotoxy(snakelocal2[i].x,snakelocal2[i].y);
			if(i == 0) printf("●");
			else printf("■");
		}
		//判断食物又没有被吃掉,吃掉就要重新打印新的食物
		if(flag1 == false || flag2 == false)
		{
    
    
			while(flag1 || flag2)
			{
    
    
				flag1 = false; flag2 = false;
				food.srandfood();
				//食物不可以跟两条蛇相重合
				for(int i = 0;i < snakelocal1.size();i++)
				{
    
    
					if(food.get_food_x() == snakelocal1[i].x && food.get_food_y() \
					== snakelocal1[i].y)
					flag1 = true;
				}
				for(int i = 0;i < snakelocal2.size();i++)
				{
    
    
					if(food.get_food_x() == snakelocal2[i].x && food.get_food_y() \
					== snakelocal2[i].y)
					flag2 = true;
				}
			}
		}
	} 
};

int main()
{
    
    
	system("mode con cols=88 lines=28");//规定游戏的界面大小
	system("title 双人小游戏之贪吃蛇");//显示标题
	hidecursor();//隐藏光标:为了游戏体验更佳
L2:
//下面是游戏介绍(请叫我整活的  坏guy  :求求了,别打我脸)
	printf("双人小游戏之贪吃蛇游戏介绍:\n");
	printf("注意这是一个推塔游戏。\n");
	printf("LOL玩多了???\n"); 
	printf("搞错了,再来!\n");
	printf("这其实是一个你死我活的游戏!\n"); 
	printf("1:请先摁shift键\n");
	printf("2: 有两条蛇,如果一条蛇触壁或碰到另一条蛇的蛇身,该蛇将会死亡!\n");
	printf("3: 下面有三个游戏的血腥程度:\n");
	printf("和平发育请摁 j\n");
	printf("有点上头请摁 k\n");
	printf("残忍嗜杀请摁 l\n");
	char op = _getch(); 
	int i = -1;
	switch(op)
	{
    
    
		case 'j':i = 2;break;
		case 'k':i = 1;break;
		case 'l':i = 0;break;
		default: system("cls");goto L2;break;
	} 
	system("cls");
	int score1 = 0,score2 = 0;//得分初始化
	int flag[3] = {
    
    100,200,300};//来个难度的selection 数组
	
	Snake snake;
	Food food;
	food.srandfood();
	
	while(true)
	{
    
    
		snake.move(food,score1,score2);

		Sleep(flag[i]);
	}
	return 0;
} //凑个整数吧!我想就到这里吧!See you again! 

希望大家没网的时候也有游戏玩。
上面的注释应该还有很多问题,
因为(我是在舍友玩CSGO,外放的情况下,敲的注释,人没了)
希望大家多提意见,我会及时改正error的。
希望大家有一个舒适的游戏体验^ _ ^,See you again !
对了,我这个代码其他编译器还没有试过:只知道DEVC++可以。

猜你喜欢

转载自blog.csdn.net/qq_51401486/article/details/115027854