C语言终极贪吃蛇代码,直接COPY上手。

先上效果图,COPY到VS上,运行不起直播吃

封面图

记得COPY的时候要注意,先创一个头文件叫snake.h的头文件,因为我这里的头文件就叫snake.h,然后把相关头文件放在你创建的这个头文件里面。第二步创建一个任意名称的源文件,把源代码放在源文件里,直接F5运行。

C语言终极贪吃蛇代码,直接COPY上手。_第1张图片

单人模式

C语言终极贪吃蛇代码,直接COPY上手。_第2张图片

双人模式C语言终极贪吃蛇代码,直接COPY上手。_第3张图片

废话不多说直接上代码

记得COPY的时候要注意,先创一个头文件叫snake.h的头文件,因为我这里的头文件就叫snake.h,然后把相关头文件放在你创建的这个头文件里面。第二步创建一个任意名称的源文件,把源代码放在源文件里,直接F5运行。

先是相关头文件

#pragma once


#pragma warning(disable : 4996)



#include
#include
#include
#include
#include
#include //导入声音头文件
#pragma comment(lib,"Winmm.lib")


/*******宏定义*******/
#define snake 64 //标题的snake的横坐标 
#define inity 4 //初始时蛇头的y坐标
#define initx 20 //初始时蛇头的x坐标
#define inity2 20  //初始时蛇头2的y坐标
#define initx2 4 //初始时蛇头的x坐标

/*贪吃蛇的各种参数*/
typedef struct Snake
{
	int x; //列坐标 
	int y; //行坐标 
	struct Snake* Next; //指向下一个身体节点的指针 
}SNAKE, * PSNAKE;//别名
int sta = 0; //用于检测按键状态
int sta2 = 0;//用于检测按键状态
int score = 0; //得分(每吃一个食物得5分) 
PSNAKE pHead; //蛇链表的头指针
PSNAKE pHead2; //蛇2链表的头指针
PSNAKE food; //食物的指针 
int flag = 0; //用于指示是否撞墙或撞到自己
int HighScore = 0; //存储最高分

/******函数声明******/
void HideCursor();//隐藏光标
void ShowCursor();//显示光标
void gotoxy(int x, int y);//光标位置
int changecolor(int a);//修改文字颜色
void ZHTsnake();
void startmenu_options();//游戏界面的选择性

void instruction();//介绍功能
void startmenu();//主菜单函数的合体
void createmap();//地图绘制
void initsnake();//初始化第一条蛇
void initsnakePT();//初始化普通模式的蛇
void initsnake2();//初始化第二条蛇
void createfood();//产生食物
void createfood2();
void keystatus();//检测用户按键按键
void keystatus2();
void keystatusjs();
bool movesnake();//蛇的移动
bool movesnakejs();
bool movesnake2();
void startgame();//普通模式开始游戏
void shuangren();//双人模式开始游戏
void jisumosi();//急速模式开始游戏
int cannotcrossthewall();//不能撞墙
int cannotcrossthewall2();
int cannotbiteyourself();//不能撞到自己
int cannotbiteyourself2();
int cannotbitethenselves();
void gameover();//游戏结束
void write_file();//文件写入分数
void read_file();//文件读取分数
void highestscore();//最高分的记录
void ConsoleTitle();//修改控制台的名字,如赵海涛
void youximoshi();//游戏模式选择界面
void choices_1(int a);//通过判断光标位置来进入选项
void choices_2(int a);
void laotie();//666的设计
void menu_word1();//目录文字设计
void menu_word2();//目录文字设计
void yinyue();//音乐的设计

接着是源代码

#include "snake.h"
int main()
{




	startmenu();

	return 0;
}

/*隐藏光标函数*/
void HideCursor()
{
	CONSOLE_CURSOR_INFO cursor;
	cursor.bVisible = FALSE;
	cursor.dwSize = sizeof(cursor);
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorInfo(handle, &cursor);
}

/*显示光标函数*/
void ShowCursor()
{
	CONSOLE_CURSOR_INFO cursor;
	cursor.bVisible = TRUE;
	cursor.dwSize = 100;
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorInfo(handle, &cursor);
}

/*控制光标位置(方便指定打印位置)*/
void gotoxy(int x, int y)
{
	COORD c;
	c.X = x;
	c.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

/*改变字体颜色(具体颜色请参照十进制颜色对照表)*/
int changecolor(int a)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
	return 0;
}

/*主界面上检测按键状态以进入不同的选项中*/
void choices_1(int a) //a为行坐标(15,17,19,21),注意开始时光标本来就是在startgame前面的 
{

	int ch = getch();
	//控制光标的移动
	while (ch != 0x0d || ch == 0xE0) //如果按下回车,则跳出循环 
	//0x0d表示回车,0XE0表示上下左右等键的键码 
	{
		//再判断是哪个键
		ch = getch();
		if (ch == 0x48 && a > 20)
		{
			a -= 2;
			gotoxy(6, a);
		}
		if (ch == 0x50 && a < 26)
		{
			a += 2;
			gotoxy(6, a);
		}
	}
	switch (a)
	{
	case 20: youximoshi(); break;
	case 22: instruction(); break;
	case 24: highestscore(); break;
	case 26: gotoxy(2, 30);  exit(0); break;
	}
}void choices_2(int a) //a为行坐标(15,17,19,21),注意开始时光标本来就是在startgame前面的 
{
	ShowCursor();
	int ch = getch();
	//控制光标的移动
	while (ch != 0x0d || ch == 0xE0) //如果按下回车,则跳出循环 
	//0x0d表示回车,0XE0表示上下左右等键的键码 
	{
	
		ch = getch(); 
		if (ch == 0x48 && a > 20)
		{
			a -= 2;
			gotoxy(5, a);
		}
		if (ch == 0x50 && a < 26)
		{
			a += 2;
			gotoxy(5, a);
		}
	}
	
	switch (a)
	{
	case 20: startgame(); break;
	case 22: jisumosi(); break;
	case 24: shuangren();  break;
	case 26: startmenu(); break;
	}
}
void youximoshi()
{

	system("cls");
	char chCmd[34];   //这三行用于控制 主菜单 窗口大小 
	sprintf_s(chCmd, "mode con cols=%d lines=%d", 117, 34);
	system(chCmd);
	ShowCursor();

	ZHTsnake();
	menu_word1();
	laotie();
	changecolor(9);
	gotoxy(6, 20);
	printf("◆普通模式◆\n");
	gotoxy(6, 22);
	printf("◆急速模式◆\n");
	gotoxy(6, 24);
	printf("◆双人模式◆\n");
	gotoxy(6, 26);
	printf("◆返回上一级◆\n");
	gotoxy(5, 20); //光标起始位置
	choices_2(20);

}
/*游戏标题(开始界面)*/
void laotie()
{
	gotoxy(25, 15);
	changecolor(15);
	printf("      ●●●●●●●●●●●●●●●                     \n");
	gotoxy(25, 16);
	printf("      ●●●●●●●●●●●●●●●                       \n");
	gotoxy(25, 17);
	printf("      ●●           \n");
	gotoxy(25, 18);
	printf("      ●●     \n");
	gotoxy(25, 19);
	printf("      ●●                                  ●●●●●●●●●●●●●   \n");
	gotoxy(25, 20);
	printf("      ●●                                  ●\n");
	gotoxy(25, 21);
	printf("      ●●                                  ●  \n");
	gotoxy(25, 22);
	printf("      ●●                                  ●                           ●●●●●●●●   \n");
	gotoxy(25, 23);
	printf("      ●●●●●●●●●●●●●●●●      ●                           ●\n");
	gotoxy(25, 24);
	printf("      ●●●●●●●●●●●●●●●●      ●●●●●●●●●●●●●   ●  \n");
	gotoxy(25, 25);
	printf("      ●●                        ●●      ●                      ●   ● \n");
	gotoxy(25, 26);
	printf("      ●●                        ●●      ●                      ●   ●\n");
	gotoxy(25, 27);
	printf("      ●●                        ●●      ●                      ●   ●●●●●●●● \n");
	gotoxy(25, 28);
	printf("      ●●                        ●●      ●                      ●   ●            ●\n");
	gotoxy(25, 29);
	printf("      ●●                        ●●      ●                      ●   ●            ●\n");
	gotoxy(25, 30);
	printf("      ●●                        ●●      ●                      ●   ●            ●\n");
	gotoxy(25, 31);
	printf("      ●●●●●●●●●●●●●●●●      ●                      ●   ●            ●\n");
	gotoxy(25, 32);
	printf("      ●●●●●●●●●●●●●●●●      ●●●●●●●●●●●●●   ●●●●●●●●\n");


}
void ZHTsnake()
{
	changecolor(11);
	printf("                                                                        \n");
	printf("    @@@         @@        @            @        ●         ●           \n");
	printf(" @@@@@@@@@@@@@@@@@@@     @@     ◆      @@   @@@@@@@@@@@@@@@@@@@@       \n");
	printf("            @  @@      @@    &     &   @@            @@                 \n");
	printf("   ~    ~    @@        @@    #    #     @@            @@                \n");
	printf("   #    #  @@          @@             @@            @@                  \n");
	printf("         @@ @           @@@@@@@@@@@@@@@@@            @@                 \n");
	printf("    @  @@              @@   @     @    @@           @@                  \n");
	printf("     @@ @               @@              @@            @@                \n");
	printf("   @@                  @@              @@            @@                 \n");
	printf(" @@@@@@@@@@@@@@@@@@@     @@             @@            @@                \n");
	printf("      @@     @@           @              @                              \n");
	printf("                                                                        \n");
	gotoxy(snake, 2);
	changecolor(5);
	printf("               @ @@@@@@                           \n");
	gotoxy(snake, 3);
	printf("             @          @                         \n");
	gotoxy(snake, 4);
	printf("            @            @                        \n");
	gotoxy(snake, 5);
	printf("           @     @@@@  ## @                       \n");
	gotoxy(snake, 6);
	printf("           @    @@   @    @                       \n");
	gotoxy(snake, 7);
	printf("           @     @@   @@@@                        \n");
	gotoxy(snake, 8);
	printf("            @      @@                             \n");
	gotoxy(snake, 9);
	printf("              @      @@                           \n");
	gotoxy(snake, 10);
	printf("               @      @@                          \n");
	gotoxy(snake, 11);
	printf("  @@@@@@       @     @@                           \n");
	gotoxy(snake, 12);
	printf(" @      @@@     @     @@                          \n");
	gotoxy(snake, 13);
	printf("@     @@       @      @ @@@@@@    @    @   @ @@@@@\n");
	gotoxy(snake, 14);
	printf("@      @@@@@ @       @  @    @   @ @   @  @  @    \n");
	gotoxy(snake, 15);
	printf(" @                 @@   @    @  @@@@@  @@    @@@@ \n");
	gotoxy(snake, 16);
	printf("  @              @@     @    @ @     @ @  @  @    \n");
	gotoxy(snake, 17);
	printf("     @ @@@@@@@@@        @    @@       @@   @ @@@@@\n");
}

/*开始界面图画和其他文字的部分*/
void menu_word1()
{
	gotoxy(3, 18);
	changecolor(6);
	printf("  请开始你的表演!");

}
void menu_word2()
{
	gotoxy(3, 18);
	changecolor(14);
	printf("  请做出你的选择!");

}

/*菜单选择项*/
void startmenu_options()
{
	changecolor(9);
	gotoxy(6, 20);
	printf("◆游戏模式◆\n");
	gotoxy(6, 22);
	printf("◆游戏介绍◆\n");
	gotoxy(6, 24);
	printf("◆得分记录◆\n");
	gotoxy(6, 26);
	printf("◆退出游戏◆\n");
	gotoxy(6, 20); //光标起始位置 
	choices_1(20);
}

/*主菜单函数的合体*/
void startmenu()
{
	//	mciSendString("close ./a.mp3 alias bgm", 0, 0, 0);//关闭音乐
	mciSendString("open a.mp3 ", 0, 0, 0);//打开音乐
	mciSendString("play a.mp3 repeat", 0, 0, 0);//播放音乐
	ConsoleTitle();
	ShowCursor();
	flag = 0;
	char chCmd[32];   //这三行用于控制 主菜单 窗口大小 
	sprintf_s(chCmd, "mode con cols=%d lines=%d", 117, 34);
	system(chCmd);
	read_file(); //读取最高分
	ZHTsnake();
	menu_word2();
	laotie();
	startmenu_options();

}

/*游戏说明及规则*/
void instruction()
{
	system("cls");
	changecolor(3);
	printf("----------------------Hi,Snake!~o(*= ▽=*)ブ----------------------\n"); //上边框
	gotoxy(0, 17);
	changecolor(3);
	printf("------------------------------------------------------------------\n"); //下边框 
	gotoxy(2, 2);
	changecolor(14);
	printf("◇ 操作说明 ◇\n");
	gotoxy(2, 4);
	changecolor(3);
	printf("※按↑↓←→键分别控制贪吃蛇向上、下、左、右移动\n");
	gotoxy(2, 6);
	printf("※按空格键暂停游戏\n");
	gotoxy(2, 8);
	printf("※按ESC键于游戏中途退出游戏\n");
	changecolor(14);
	gotoxy(2, 10);
	printf("◇ 游戏规则 ◇\n");
	gotoxy(2, 12);
	changecolor(3);
	printf("※肥肠简单,只要不撞到自己或撞到墙就行了(笑)\n");
	//增加一个按回车键返回主菜单
	gotoxy(1, 16);
	printf("Press space back to the menu......");
	gotoxy(35, 16);
	int cha = getch();
	while (cha == 0x0d)
	{
		system("cls");
		startmenu();
	}
}

/*游戏主体部分整合*/
void startgame()
{

	createmap();
	initsnakePT();
	Sleep(100);
	createfood();
	keystatus();
	write_file();
	score = 0;
}
void jisumosi()
{

	createmap();
	initsnake();
	Sleep(100);
	createfood();
	keystatusjs();
	write_file();
	score = 0;
}

/*加载地图*/
void createmap()
{
	HideCursor();
	system("cls");
	char chCmd[32];
	sprintf_s(chCmd, "mode con cols=%d lines=%d", 51, 26);
	system(chCmd);
	int i, j;
	changecolor(5);
	for (i = 0; i < 49; i += 2)  //上下两个边框 
	{
		gotoxy(i, 0);
		printf("〓");
		gotoxy(i, 24);
		printf("〓");
	}
	for (i = 1; i < 25; i++) //左右边框 
	{
		gotoxy(0, i);
		printf("〓");
		gotoxy(48, i);
		printf("〓");/*〓*/
	}
	changecolor(11);
	for (i = 1; i < 24; i++) //控制行数 
	{
		for (j = 2; j < 48; j += 2)
		{
			gotoxy(j, i);
			printf("■");
		}
		printf("\n");
	}
	printf("\n");
}

/*初始化蛇身*/
void initsnake()
{
	pHead = (PSNAKE)malloc(sizeof(SNAKE)); //附加头节点
	PSNAKE pTail = (PSNAKE)malloc(sizeof(SNAKE)); //用于指向尾巴地址

	pTail = pHead;
	if (pTail != NULL && pHead != NULL)
	{
		pHead->Next = NULL;
		int i, val = initx;
		for (i = 0; i < 4; i++)
		{
			PSNAKE isnake = (PSNAKE)malloc(sizeof(SNAKE));
			if (isnake != NULL)
			{
				isnake->x = val;  //横向摆放初始状态的蛇 
				isnake->y = inity;
				val -= 2;
				pTail->Next = isnake;
				isnake->Next = NULL;
				pTail = isnake;
			}
		}


		PSNAKE p = pHead->Next;//遍历打印蛇身体
		gotoxy(p->x, p->y);
		changecolor(6);
		printf("●");
		p = p->Next;

		while (p != NULL) //在地图的初始位置输出初始化的蛇 
		{
			changecolor(6);
			gotoxy(p->x, p->y);
			printf("◆");
			p = p->Next;
		}
	}
}
void initsnakePT()
{
	pHead = (PSNAKE)malloc(sizeof(SNAKE)); //附加头节点
	PSNAKE pTail = (PSNAKE)malloc(sizeof(SNAKE)); //用于指向尾巴地址

	pTail = pHead;
	if (pTail != NULL && pHead != NULL)
	{
		pHead->Next = NULL;
		int i, val = initx;
		for (i = 0; i < 4; i++)
		{
			PSNAKE isnake = (PSNAKE)malloc(sizeof(SNAKE));
			if (isnake != NULL)
			{
				isnake->x = val;  //横向摆放初始状态的蛇 
				isnake->y = inity;
				val -= 2;
				pTail->Next = isnake;
				isnake->Next = NULL;
				pTail = isnake;
			}
		}


		PSNAKE p = pHead->Next;//遍历打印蛇身体
		gotoxy(p->x, p->y);
		changecolor(8);
		printf("●");
		p = p->Next;

		while (p != NULL) //在地图的初始位置输出初始化的蛇 
		{
			changecolor(8);
			gotoxy(p->x, p->y);
			printf("◆");
			p = p->Next;
		}
	}
}


void createfood2()
{
	srand((unsigned)time(NULL));

	PSNAKE ffood = (PSNAKE)malloc(sizeof(SNAKE));
	food = (PSNAKE)malloc(sizeof(SNAKE));
	//ffood->Next = NULL;
	int we = rand() % 42 + 2;
	while (we % 2 == 1) //横坐标必须是偶数
		we = rand() % 42 + 2;
	ffood->x = we;
	ffood->y = rand() % 19 + 1; //1<= y <=23
	PSNAKE p = (PSNAKE)malloc(sizeof(SNAKE));
	PSNAKE remhead = (PSNAKE)malloc(sizeof(SNAKE));

	p = pHead->Next;
	//remhead = p;
	if (ffood != NULL && food != NULL)
	{
		//在随机出现食物的时候,食物不能与蛇的身体重合 
		while (p != NULL)
		{
			if (p->x == ffood->x && p->y == ffood->y) //若重合,则释放该食物空间并重新生成一个食物 
			{
				srand((unsigned)time(NULL));

				//PSNAKE ffood = (PSNAKE)malloc(sizeof(SNAKE));
				//ffood->Next = NULL;
				int we = rand() % 42 + 2;
				while (we % 2 == 1) //2<= x <=46,且列坐标必须为偶数(食物和格子都占两个字符)
					we = rand() % 42 + 2;
				ffood->x = we;
				ffood->y = rand() % 19 + 1; //1<= y <=23
				ffood->Next = NULL;
				//p = remhead;
			}
			else
				p = p->Next;
		}
		PSNAKE q = (PSNAKE)malloc(sizeof(SNAKE));
		q = pHead2->Next;
		while (q != NULL)
		{
			if (q->x == ffood->x && q->y == ffood->y) //若重合,则释放该食物空间并重新生成一个食物 
			{
				int we = rand() % 42 + 2;
				while (we % 2 == 1) //2<= x <=46,且列坐标必须为偶数(食物和格子都占两个字符)
					we = rand() % 42 + 2;
				ffood->x = we;
				ffood->y = rand() % 19 + 1; //1<= y <=23
				ffood->Next = NULL;
				//p = remhead;
			}
			q = q->Next;
		}

		// 如果未重合,则说明该食物生成成功,并将食物打印在地图上
		food = ffood;
		changecolor(4);
		gotoxy(food->x, food->y);
		printf("●");
		changecolor(5);

	}
}


void createfood()
{
	srand((unsigned)time(NULL));

	PSNAKE ffood = (PSNAKE)malloc(sizeof(SNAKE));
	food = (PSNAKE)malloc(sizeof(SNAKE));
	//ffood->Next = NULL;
	int we = rand() % 42 + 2;
	while (we % 2 == 1) //横坐标必须是偶数
		we = rand() % 42 + 2;
	ffood->x = we;
	ffood->y = rand() % 19 + 1; //1<= y <=23
	PSNAKE p = (PSNAKE)malloc(sizeof(SNAKE));
	PSNAKE remhead = (PSNAKE)malloc(sizeof(SNAKE));

	p = pHead->Next;
	//remhead = p;
	if (ffood != NULL && food != NULL)
	{
		//在随机出现食物的时候,食物不能与蛇的身体重合 
		while (p != NULL)
		{
			if (p->x == ffood->x && p->y == ffood->y) //若重合,则释放该食物空间并重新生成一个食物 
			{
				srand((unsigned)time(NULL));

				//PSNAKE ffood = (PSNAKE)malloc(sizeof(SNAKE));
				//ffood->Next = NULL;
				int we = rand() % 42 + 2;
				while (we % 2 == 1) //2<= x <=46,且列坐标必须为偶数(食物和格子都占两个字符)
					we = rand() % 42 + 2;
				ffood->x = we;
				ffood->y = rand() % 19 + 1; //1<= y <=23
				ffood->Next = NULL;
				//p = remhead;
			}
			else
				p = p->Next;
		}
		// 如果未重合,则说明该食物生成成功,并将食物打印在地图上
		food = ffood;
		changecolor(4);
		gotoxy(food->x, food->y);
		printf("●");
		changecolor(5);

	}
}


//检测游戏过程中各个键的状态
void keystatus()
{
	sta = 4; //初始蛇向右走
	while (1) //死循环,能保证按键按下的时候进行判断并进入movesnake函数
	{
		if (GetAsyncKeyState(VK_UP) && sta != 2)
			sta = 1;
		else
		{
			if (GetAsyncKeyState(VK_DOWN) && sta != 1)
				sta = 2;
			else
			{
				if (GetAsyncKeyState(VK_LEFT) && sta != 4)
					sta = 3;
				else
				{
					if ((GetAsyncKeyState(VK_RIGHT) && sta != 3))
						sta = 4;
				}
			}
		}
		if (GetAsyncKeyState(VK_SPACE)) //按空格键暂停
		{
			while (1)
			{
				Sleep(300);
				if (GetAsyncKeyState(VK_SPACE)) //再次检测到空格键的时候就恢复原游戏状态
					break;
			}
		}
		if (GetAsyncKeyState(VK_ESCAPE)) //按esc键直接从游戏时的状态退回到主菜单界面
		{
			system("cls");
			startmenu();
			break; //检测到退出->退出该死循环 
		}
		if (movesnake() == false)
		{
			gameover();
			break;
		}
	}
}
void keystatusjs()
{
	sta = 4; //初始蛇向右走
	while (1) //死循环,能保证按键按下的时候进行判断并进入movesnake函数
	{
		if (GetAsyncKeyState(VK_UP) && sta != 2)
			sta = 1;
		else
		{
			if (GetAsyncKeyState(VK_DOWN) && sta != 1)
				sta = 2;
			else
			{
				if (GetAsyncKeyState(VK_LEFT) && sta != 4)
					sta = 3;
				else
				{
					if ((GetAsyncKeyState(VK_RIGHT) && sta != 3))
						sta = 4;
				}
			}
		}
		if (GetAsyncKeyState(VK_SPACE)) //按空格键暂停
		{
			while (1)
			{
				Sleep(300);
				if (GetAsyncKeyState(VK_SPACE)) //再次检测到空格键的时候就恢复原游戏状态
					break;
			}
		}
		if (GetAsyncKeyState(VK_ESCAPE)) //按esc键直接从游戏时的状态退回到主菜单界面
		{
			system("cls");
			startmenu();
			break; //检测到退出->退出该死循环 
		}
		if (movesnakejs() == false)
		{
			gameover();
			break;
		}
	}
}



bool movesnake()//qq是头
{
	HideCursor();
	changecolor(8);

	PSNAKE qq = (PSNAKE)malloc(sizeof(SNAKE));        //移动过程就是产生一个新节点(坐标在原来蛇头坐标基础上变化) 
	PSNAKE pp = (PSNAKE)malloc(sizeof(SNAKE));         //并同时去掉尾节点(新节点使用头插法)
	pp = pHead->Next; //pp暂存蛇头的地址 

	if (sta == 1) //向上走                       
	{
		qq->x = pp->x;
		qq->y = pp->y - 1; //行坐标减一 
		qq->Next = pp; //原来的蛇头成为第二个节点 
		pHead->Next = qq; //头节点存这个新开节点的地址,新节点成为蛇头 
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next; //a为蛇头
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1) //如果撞到墙或撞到自己
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)//如果蛇向上走了一步,且这一步遇到了食物
			{
				//尾节点仍然是 ◆
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(200);   //减慢打印时间用的(同时也是减慢蛇的速度用的)
				createfood();
				score += 5;
			}
			else //如果没有碰到食物,打印尾节点时变成 ■
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{ //最后那a是倒数第二个节点的地址
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;         //b存最后一个节点的地址
				a->Next = NULL;      //a的指针域为空,倒数第二个节点成为尾节点
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				changecolor(5);
				Sleep(200);
			}
			return true;
		}
	}
	if (sta == 2) //向下走
	{
		qq->x = pp->x;
		qq->y = pp->y + 1;
		qq->Next = pp;
		pHead->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next;
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(200);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(200);
				changecolor(5);
			}
			return true;
		}
	}
	if (sta == 3) //向左走
	{
		qq->x = pp->x - 2;
		qq->y = pp->y;
		qq->Next = pp;
		pHead->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next;
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(200);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(200);
				changecolor(5);
			}
			return true;
		}
	}
	if (sta == 4) //向右 
	{
		qq->x = pp->x + 2;
		qq->y = pp->y;
		qq->Next = pp;
		pHead->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next;
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(200);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(200);
				changecolor(5);
			}
			return true;
		}
	}
}
bool movesnakejs()
{
	HideCursor();
	changecolor(6);
	PSNAKE qq = (PSNAKE)malloc(sizeof(SNAKE));        //移动过程等效于产生一个新节点(坐标在原来蛇头坐标基础上变化) 
	PSNAKE pp = (PSNAKE)malloc(sizeof(SNAKE));         //并同时去掉尾节点(新节点使用头插法)
	pp = pHead->Next; //pp暂存蛇头的地址 
	if (sta == 1) //向上走                       
	{
		qq->x = pp->x;
		qq->y = pp->y - 1; //行坐标减一 
		qq->Next = pp; //原来的蛇头成为第二个节点 
		pHead->Next = qq; //头节点存这个新开节点的地址,新节点成为蛇头 
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next; //a为蛇头
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1) //如果撞到墙或撞到自己
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)//如果蛇向上走了一步,且这一步遇到了食物
			{
				//尾节点仍然是 ◆
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);   //减慢打印时间用的(同时也是减慢蛇的速度用的)
				createfood();
				score += 5;
			}
			else //如果没有碰到食物,打印尾节点时变成 ■
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{ //最后那a是倒数第二个节点的地址
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;         //b存最后一个节点的地址
				a->Next = NULL;      //a的指针域为空,倒数第二个节点成为尾节点
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				changecolor(5);
				Sleep(50);
			}
			return true;
		}
	}
	if (sta == 2) //向下走
	{
		qq->x = pp->x;
		qq->y = pp->y + 1;
		qq->Next = pp;
		pHead->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next;
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(50);
				changecolor(5);
			}
			return true;
		}
	}
	if (sta == 3) //向左走
	{
		qq->x = pp->x - 2;
		qq->y = pp->y;
		qq->Next = pp;
		pHead->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next;
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(50);
				changecolor(5);
			}
			return true;
		}
	}
	if (sta == 4) //向右 
	{
		qq->x = pp->x + 2;
		qq->y = pp->y;
		qq->Next = pp;
		pHead->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead->Next;
		if (cannotbiteyourself() == 1 || cannotcrossthewall() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(50);
				changecolor(5);
			}
			return true;
		}
	}
}
/*不能撞墙*/
int cannotcrossthewall()
{
	if (pHead->Next->x == 0 || pHead->Next->x == 48 || pHead->Next->y == 0 || pHead->Next->y == 24)
		flag = 1;
	return flag;
}
int cannotcrossthewall2()
{
	if (pHead2->Next->x == 0 || pHead2->Next->x == 48 || pHead2->Next->y == 0 || pHead2->Next->y == 24)
		flag = 1;
	return flag;
}

/*不能撞到自己*/
int cannotbiteyourself()
{
	PSNAKE bite = (PSNAKE)malloc(sizeof(SNAKE));
	bite = pHead->Next->Next;    //bite从第二个节点开始判断
	while (bite != NULL)
	{
		if (bite->x == pHead->Next->x && bite->y == pHead->Next->y)
			flag = 1;
		bite = bite->Next;
	}
	return flag;
}

int cannotbitethenselves()
{
	PSNAKE bite = (PSNAKE)malloc(sizeof(SNAKE));
	PSNAKE bite2 = (PSNAKE)malloc(sizeof(SNAKE));
	bite = pHead->Next;  //bite从第一个节点开始判断
	bite2 = pHead2->Next; 
	while (bite != NULL)
	{
		while (bite2)
		{
		if (bite->x == bite2->x && bite->y == bite2->y)
				flag = 1;
		bite2 = bite2->Next;
		}
		
		bite = bite->Next;
	}
	return flag;
}

/*游戏结束画面*/
void gameover()
{
	if (score > HighScore)
		write_file();
	system("cls");
	changecolor(11);
	char chCmd[32];
	sprintf_s(chCmd, "mode con cols=%d lines=%d", 60, 25);
	system(chCmd);
	gotoxy(5, 5);
	printf("  /\\________/\\\n");
	gotoxy(5, 6);
	printf(" |   Q    Q   |\n");
	gotoxy(5, 7);
	printf(" |     ⌒     |   ---你死的好惨啊呜呜呜(;′⌒`)    \n");
	gotoxy(5, 8);
	printf(" |            |\n");
	gotoxy(5, 9);
	printf(" \\____________/              \n");
	gotoxy(5, 10);
	printf("                                        \n");
	gotoxy(5, 11);
	changecolor(9);
	printf("  Your score is %d      \n", score);
	gotoxy(5, 12);
	printf("Highest score : %d    \n", HighScore);
	gotoxy(1, 15);
	printf("Press space back to the menu......");
	gotoxy(35, 15);
	int ch = getchar();
	while (ch == 0x0d)
		exit(0);
	system("cls");
	startmenu();
}

/*读取最高分*/
void read_file()
{
	FILE* fp;
	fp = fopen("Desktop.txt", "a+");       //打开文件Desktop.txt
	fscanf_s(fp, "%d", &HighScore);       //把文件中的最高分读出来
	fclose(fp);                         //关闭文件
}

/*记录最高分*/
void write_file()
{
	FILE* fp;
	fp = fopen("Desktop.txt", "w+");       //以读写的方式建立一个名为Desktop.txt的文件
	fprintf(fp, "%d", score);           //把分数写进文件中
	fclose(fp);
}

/*查看最高分*/
void highestscore()
{
	system("cls");
	char chCmd[32];
	sprintf_s(chCmd, "mode con cols=%d lines=%d", 50, 25);
	system(chCmd);
	changecolor(14);
	gotoxy(5, 5);
	printf("Your highest score is %d.\n\n", HighScore);
	gotoxy(1, 9);
	printf("Press space back to the menu......");
	gotoxy(35, 9);
	int cha = getch();
	while (cha == 0x0d)
	{
		system("cls");
		startmenu();
	}
}
void ConsoleTitle()
{
	char Title[200];

	SetConsoleTitleA("                                                           赵海涛的贪吃蛇");
	GetConsoleTitleA(Title, 200);

}

void shuangren()
{
	createmap();
	initsnake();
	initsnake2();
	Sleep(100);
	createfood2();


	keystatus2();
	write_file();
	score = 0;
}
void initsnake2()
{
	pHead2 = (PSNAKE)malloc(sizeof(SNAKE)); //附加头节点
	PSNAKE pTail = (PSNAKE)malloc(sizeof(SNAKE)); //用于指向尾巴地址 

	pTail = pHead2;
	if (pTail != NULL && pHead2 != NULL)//判断
	{
		pHead2->Next = NULL;
		int i, val = initx2;
		for (i = 0; i < 2; i++)
		{
			PSNAKE isnake = (PSNAKE)malloc(sizeof(SNAKE));
			//if (isnake != NULL)
			{
				isnake->x = val;  //横向摆放初始状态的蛇 
				isnake->y = inity2;
				val -= 2;
				pTail->Next = isnake;
				isnake->Next = NULL;
				pTail = isnake;
			}
		}


		PSNAKE p = pHead2->Next;
		gotoxy(p->x, p->y);
		changecolor(5);
		printf("●");
		p = p->Next;

		while (p != NULL) //在地图的初始位置输出初始化的蛇 
		{
			changecolor(5);
			gotoxy(p->x, p->y);
			printf("◆");
			p = p->Next;
		}
	}
}
void keystatus2()
{
	sta = 3;
	sta2 = 4; //初始蛇向右走
	while (1) //死循环,能保证按键按下的时候进行判断并进入movesnake函数
	{
		if (GetAsyncKeyState(0x57) && sta2 != 2)
			sta2 = 1;
		else
		{
			if (GetAsyncKeyState(0x53) && sta2 != 1)
				sta2 = 2;
			else
			{
				if (GetAsyncKeyState(0x41) && sta2 != 4)
					sta2 = 3;
				else
				{
					if ((GetAsyncKeyState(0x44) && sta2 != 3))
						sta2 = 4;
					else {
						if (GetAsyncKeyState(VK_UP) && sta != 2)
							sta = 1;
						else
						{
							if (GetAsyncKeyState(VK_DOWN) && sta != 1)
								sta = 2;
							else
							{
								if (GetAsyncKeyState(VK_LEFT) && sta != 4)
									sta = 3;
								else
								{
									if ((GetAsyncKeyState(VK_RIGHT) && sta != 3))
										sta = 4;
								}
							}
						}
					}
				}
			}
		}
		if (GetAsyncKeyState(VK_SPACE)) //按空格键暂停
		{
			while (1)
			{
				Sleep(300);
				if (GetAsyncKeyState(VK_SPACE)) //再次检测到空格键的时候就恢复原游戏状态
					break;
			}
		}
		if (GetAsyncKeyState(VK_ESCAPE)) //按esc键直接从游戏时的状态退回到主菜单界面
		{
			system("cls");
			startmenu();
			break; //检测到退出->退出该死循环 
		}
		if (movesnakejs() == false || movesnake2() == false)
		{
			gameover();
			break;
		}
	}
}
bool movesnake2()
{
	HideCursor();
	changecolor(5);
	PSNAKE qq = (PSNAKE)malloc(sizeof(SNAKE));        //移动过程等效于产生一个新节点(坐标在原来蛇头坐标基础上变化) 
	PSNAKE pp = (PSNAKE)malloc(sizeof(SNAKE));         //并同时去掉尾节点(新节点使用头插法)
	pp = pHead2->Next; //pp暂存蛇头的地址 
	if (sta2 == 1) //向上走                       
	{
		qq->x = pp->x;
		qq->y = pp->y - 1; //行坐标减一 
		qq->Next = pp; //原来的蛇头成为第二个节点 
		pHead2->Next = qq; //头节点存这个新开节点的地址,新节点成为蛇头 
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead2->Next; //a为蛇头
		if (cannotbiteyourself2() == 1 || cannotcrossthewall2() == 1 || cannotbitethenselves() == 1) //如果撞到墙或撞到自己
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)//如果蛇向上走了一步,且这一步遇到了食物
			{
				//尾节点仍然是 ◆
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);   //减慢打印时间用的(同时也是减慢蛇的速度用的)
				createfood();
				score += 5;
			}
			else //如果没有碰到食物,打印尾节点时变成 ■
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{ //最后那a是倒数第二个节点的地址
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;         //b存最后一个节点的地址
				a->Next = NULL;      //a的指针域为空,倒数第二个节点成为尾节点
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				changecolor(5);
				Sleep(50);
			}
			return true;
		}
	}
	if (sta2 == 2) //向下走
	{
		qq->x = pp->x;
		qq->y = pp->y + 1;
		qq->Next = pp;
		pHead2->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead2->Next;
		if (cannotbiteyourself2() == 1 || cannotcrossthewall2() == 1 || cannotbitethenselves() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(50);
				changecolor(5);
			}
			return true;
		}
	}
	if (sta2 == 3) //向左走
	{
		qq->x = pp->x - 2;
		qq->y = pp->y;
		qq->Next = pp;
		pHead2->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead2->Next;
		if (cannotbiteyourself2() == 1 || cannotcrossthewall2() == 1 || cannotbitethenselves() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(50);
				changecolor(5);
			}
			return true;
		}
	}
	if (sta2 == 4) //向右 
	{
		qq->x = pp->x + 2;
		qq->y = pp->y;
		qq->Next = pp;
		pHead2->Next = qq;
		PSNAKE a = (PSNAKE)malloc(sizeof(SNAKE));
		a = pHead2->Next;
		if (cannotbiteyourself2() == 1 || cannotcrossthewall2() == 1 || cannotbitethenselves() == 1)
			return false;
		else
		{
			if (a->x == food->x && a->y == food->y)
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				Sleep(50);
				createfood();
				score += 5;
			}
			else
			{
				gotoxy(a->x, a->y);
				printf("●");
				a = a->Next;
				while (a->Next->Next != NULL)
				{
					gotoxy(a->x, a->y);
					printf("◆");
					a = a->Next;
				}
				gotoxy(a->x, a->y);
				printf("◆");
				PSNAKE b = (PSNAKE)malloc(sizeof(SNAKE));
				b = a->Next;
				a->Next = NULL;
				changecolor(11);
				gotoxy(b->x, b->y);
				printf("■");
				free(b);
				b = NULL;
				Sleep(50);
				changecolor(5);
			}
			return true;
		}
	}
}
int cannotbiteyourself2()
{
	PSNAKE bite = (PSNAKE)malloc(sizeof(SNAKE));
	bite = pHead2->Next->Next;    //bite从第二个节点开始判断
	while (bite != NULL)
	{
		if (bite->x == pHead2->Next->x && bite->y == pHead2->Next->y)
			flag = 1;
		bite = bite->Next;
	}
	return flag;
}


















你可能感兴趣的:(C语言游戏类,c语言)