C实战——高配版贪吃蛇游戏设计

↘话不多说,先上图为敬(●´∀`●)ノ

主界面游戏截图
与君の勉:贪吃蛇Demo作为一个C语言的经典开发项目,比较适合初学者练习。透过程序看本质,该项目有种许多可供我们学习、提高的知识点:数组、指针、循环链表、多文件操作、三大结构运用……等等。“理论+实践”,相信入门的你通过该Demo会对C有更尽一层的理解。
由于最近其他事情耽搁,完整的设计流程笔记小编还未完成,不过我会尽快补更,就先把源码分享给大家,期待共同学习交流。


✅单独提出一些有趣且值得参考部分,完整源码及编译运行使用详见文末附件

1.绘制字符画–蛇

//绘制字符画--蛇
int printSnake(void){
	//清屏
	system("cls");

	gotoXY(35, 1);
	setColor(6);
	printf("/^\\/^\\");      //蛇眼

	gotoXY(34, 2);
	printf("|__|  0");      //蛇眼

	gotoXY(33, 2);
	setColor(2);
	printf("_");

	gotoXY(25, 3);
	setColor(12);
	printf("\\/");        //蛇信

	gotoXY(31, 3);
	setColor(2);
	printf("/");

	gotoXY(37, 3);
	setColor(6);
	printf("\\_/");       //蛇眼

	gotoXY(41, 3);
	setColor(10);
	printf("\\");

	gotoXY(26, 4);
	setColor(12);
	printf("\\____");     //舌头

	gotoXY(32, 4);
	printf("_________/");

	gotoXY(31, 4);
	setColor(2);
	printf("|");

	gotoXY(42, 4);
	setColor(10);
	printf("\\");

	gotoXY(31, 5);
	setColor(2);
	printf("\\_______");     //蛇嘴

	gotoXY(43, 5);
	setColor(10);
	printf("\\");

	gotoXY(38, 6);
	printf(" |    |                               \\");
	//下面都是画蛇身

	gotoXY(38, 7);
	printf(" /    /                               \\ \\");

	gotoXY(37, 8);
	printf(" /    /                                \\  \\");

	gotoXY(36, 9);
	printf(" /    /                                  \\  \\");

	gotoXY(35, 10);
	printf(" /    /                                    \\  \\");

	gotoXY(34, 11);
	printf(" /    /                _----_                \\  \\");

	gotoXY(33, 12);
	printf(" /    /             _--~       --_            |   |");

	gotoXY(33, 13);
	printf("(    (        _----~     _--_      --_      _/    |");

	gotoXY(34, 14);
	printf("\\    ~-——-~     --~---    ~--      ~-_-~       /");

	gotoXY(35, 15);
	printf("\\           -—~              ~—-         -—~");

	gotoXY(36, 16);
	printf("~—-----—~                      ~—---—~        ");

	return 0;

}

2.欢迎界面

int i, j;

	int n;

	//显示字符画
	printSnake();

	//输出标题
	setColor(11);
	//移动光标
	gotoXY(49, 18);
	printf("贪吃蛇游戏\n");

	//设置文本颜色
	setColor(14);

	//打印游戏边框
	for (i = 20; i <= 26; i++){              //控制行
		for (j = 27; j <= 74; j++)           //控制列
		{
			//定位光标
			gotoXY(j, i);
			if (i == 20 || i == 26){
				printf("-");
			}
			else if (j == 27 || j == 74){
				printf("|");
			}
			else{
				printf(" ");
			}

		}
	}

	//输出菜单
	//设置文本颜色
	setColor(12);
	gotoXY(35, 22);
	printf("1. 开始游戏");

	gotoXY(55, 22);
	printf("2. 游戏说明");

	gotoXY(35, 24);
	printf("3. 退出游戏");

	gotoXY(35, 24);
	printf("3. 退出游戏");

	//输出用户选择提示
	gotoXY(27, 27);
	printf("请选择[1 2 3]:");

	//等待用户输入一个数字
	scanf("%d", &n);

	//读取回车字符
	getchar();
	return n;
}

3.初始化蛇

//初始化蛇
int initSnake(void)
{
	int i = 0;
	snake_t  *new = NULL;
	snake_t  *tmp = NULL;

	//循环创建4各结点
	for (i = 0; i < 4; i++){
		//分配空间
		new = malloc(sizeof(snake_t));
		if (NULL == new)
		{
			printf("malloc failed…\n");
			break;
		}
		memset(new, 0, sizeof(snake_t));

		//初始化列 是个偶数
		new->x = 24 + i * 2;
		//初始化行
		new->y = 5;

		//头插法
		new->next = head;
		head = new;
	}

	//绘制蛇
	tmp = head;
	while (NULL != tmp)
	{
		//设置蛇的颜色为黄色
		setColor(14);
		gotoXY(tmp->x, tmp->y);

		//如果是第一个节点  输出圆形符号
		if (head == tmp)
		{
			printf("●");
		}
		else
		{
			printf("★");
		}

		//指向下一个节点
		tmp = tmp->next;
	}
	return 0;
}

4.随机食物

//随机食物
//随机食物
int randFood(void)
{
	snake_t *new = NULL;
	snake_t *tmp = NULL;

	//分配空间
	new = malloc(sizeof(snake_t));
	if (NULL == new)
	{
		printf("malloc failed…\n");
		return -1;
	}

	//循环随机食物  保证食物没有在蛇身
	while (1)
	{
		//清零
		memset(new, 0, sizeof(snake_t));
		//随机x值
		while (1)
		{
			//随机x值    是一个偶数(2,54)
			//rand() %53 -->(0,  52)      -->+2   -->(2,54)
			new->x = rand() % 53 + 2;
			if (new->x % 2 == 0)
			{
				break;
			}
		}

		//rand()产生一个随机数
		//(1,25)
		//rand( ) % 25 --> (0,24)     -->+1   -->(1,25)
		new->y = rand() % 25 + 1;

		//判断食物不能在蛇身上
		tmp = head;
		while (NULL != tmp)
		{
			if ((tmp->x == new->x) && (tmp->y == new->y))
			{
				break;
			}
			tmp = tmp->next;
		}

		//食物不在蛇身上
		if (NULL == tmp)
		{
			gotoXY(new->x, new->y);
			setColor(12);
			printf("●");

			//食物指针
			food = new;
			break;
		}
		else
		{
			continue;
		}
	}
	return 0;
}

5.蛇的移动

int moveSnake(void)
{
	snake_t *new = NULL;
	snake_t *tmp = NULL;
	snake_t *save = NULL;

	//分配空间
	new = malloc(sizeof(snake_t));
	if (NULL == new)
	{
		printf("malloc failed…\n");
		return -1;
	}
	memset(new, 0, sizeof(snake_t));

	//向上
	if (direction == UP)
	{
		new->x = head->x;
		new->y = head->y - 1;
	}

	//向下
	if (direction == DOWN)
	{
		new->x = head->x;
		new->y = head->y + 1;
	}

	//向左
	if (direction == LEFT)
	{
		new->x = head->x - 2;
		new->y = head->y;
	}

	//向右
	if (direction == RIGHT)
	{
		new->x = head->x + 2;
		new->y = head->y;
	}

	//头插法
	new->next = head;
	head = new;

	//使用临时节点指向链表第一个节点
	tmp = head;
	//前面是否为食物
	if ((head->x == food->x) && (head->y == food->y))
	{
		while (NULL != tmp)
		{
			//设置蛇的颜色为黄色
			setColor(14);
			gotoXY(tmp->x, tmp->y);

			//如果是第一个节点  输出圆形符号
			if (head == tmp)
			{
				printf("●");
			}
			else
			{
				printf("★");
			}

			//指向下一个节点
			tmp = tmp->next;
		}

		//吃掉食物后分数增加
		score = score + add;

		//随机食物
		randFood();
	}
	else
	{
		//删除最后一个节点
		while (NULL != tmp->next)
		{
			//设置蛇的颜色为黄色
			setColor(14);
			gotoXY(tmp->x, tmp->y);

			//如果是第一个节点  输出圆形符号
			if (head == tmp)
			{
				printf("●");
			}
			else
			{
				printf("★");
			}

			//保存tmp节点
			save = tmp;
			//指向下一个节点
			tmp = tmp->next;
		}

		gotoXY(tmp->x, tmp->y);
		setColor(3);
		printf("■");

		save->next = NULL;
		free(tmp);
		tmp = NULL;
	}

	return 0;
}

6.写文件

//写文件
int writeFile(void)
{
	FILE *fp = NULL;
	//打开文件
	fp = fopen("data.txt", "w");
	if (NULL == fp)
	{
		printf("打开文件失败..\n");
		return -1;
	}

	//写文件
	fprintf(fp, "%d", score);

	//关闭文件
	fclose(fp);

	return 0;

}

工程源码:

1.snake.c     //蛇身绘制及运动控制实现(封装)
#define _CRT_SECURE_NO_WARNINGS 
#include"snake.h"

//得分
int score = 0;

//每次增加得分
int add = 1;

//蛇的移动方向
int direction = RIGHT;

//游戏退出状态
int endStatus = 0;

//睡眠时间
int sleepTime = 250;

//蛇头结点指针  永远指向蛇头
snake_t  *head = NULL;

//食物结点指针
snake_t  *food = NULL;


//设置终端字体颜色
int setColor(int c){
	//设置文本颜色
	//第一个参数:标准输出句柄
	//第二个参数:颜色的值
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);

	return 0;
}

//设置光标位置
int gotoXY(int x, int y){
	COORD c;
	//横坐标
	c.X = x;
	//纵坐标
	c.Y = y;

	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
	return 0;
}

//绘制字符画--蛇
int printSnake(void){
	//清屏
	system("cls");

	gotoXY(35, 1);
	setColor(6);
	printf("/^\\/^\\");      //蛇眼

	gotoXY(34, 2);
	printf("|__|  0");      //蛇眼

	gotoXY(33, 2);
	setColor(2);
	printf("_");

	gotoXY(25, 3);
	setColor(12);
	printf("\\/");        //蛇信

	gotoXY(31, 3);
	setColor(2);
	printf("/");

	gotoXY(37, 3);
	setColor(6);
	printf("\\_/");       //蛇眼

	gotoXY(41, 3);
	setColor(10);
	printf("\\");

	gotoXY(26, 4);
	setColor(12);
	printf("\\____");     //舌头

	gotoXY(32, 4);
	printf("_________/");

	gotoXY(31, 4);
	setColor(2);
	printf("|");

	gotoXY(42, 4);
	setColor(10);
	printf("\\");

	gotoXY(31, 5);
	setColor(2);
	printf("\\_______");     //蛇嘴

	gotoXY(43, 5);
	setColor(10);
	printf("\\");

	gotoXY(38, 6);
	printf(" |    |                               \\");
	//下面都是画蛇身

	gotoXY(38, 7);
	printf(" /    /                               \\ \\");

	gotoXY(37, 8);
	printf(" /    /                                \\  \\");

	gotoXY(36, 9);
	printf(" /    /                                  \\  \\");

	gotoXY(35, 10);
	printf(" /    /                                    \\  \\");

	gotoXY(34, 11);
	printf(" /    /                _----_                \\  \\");

	gotoXY(33, 12);
	printf(" /    /             _--~       --_            |   |");

	gotoXY(33, 13);
	printf("(    (        _----~     _--_      --_      _/    |");

	gotoXY(34, 14);
	printf("\\    ~-——-~     --~---    ~--      ~-_-~       /");

	gotoXY(35, 15);
	printf("\\           -—~              ~—-         -—~");

	gotoXY(36, 16);
	printf("~—-----—~                      ~—---—~        ");

	return 0;

}
//欢迎界面
int welcomeGame(void){
	int i, j;

	int n;

	//显示字符画
	printSnake();

	//输出标题
	setColor(11);
	//移动光标
	gotoXY(49, 18);
	printf("贪吃蛇游戏\n");

	//设置文本颜色
	setColor(14);

	//打印游戏边框
	for (i = 20; i <= 26; i++){              //控制行
		for (j = 27; j <= 74; j++)           //控制列
		{
			//定位光标
			gotoXY(j, i);
			if (i == 20 || i == 26){
				printf("-");
			}
			else if (j == 27 || j == 74){
				printf("|");
			}
			else{
				printf(" ");
			}

		}
	}

	//输出菜单
	//设置文本颜色
	setColor(12);
	gotoXY(35, 22);
	printf("1. 开始游戏");

	gotoXY(55, 22);
	printf("2. 游戏说明");

	gotoXY(35, 24);
	printf("3. 退出游戏");

	gotoXY(35, 24);
	printf("3. 退出游戏");

	//输出用户选择提示
	gotoXY(27, 27);
	printf("请选择[1 2 3]:");

	//等待用户输入一个数字
	scanf("%d", &n);

	//读取回车字符
	getchar();
	return n;
}

//显示游戏说明
int aboutGame(void)
{
	int i, j;
	//清屏
	system("cls");

	//显示标题
	setColor(13);
	gotoXY(44, 3);
	printf("游戏说明");

	for (i = 6; i <= 22; i++){                //行
		for (j = 20; j <= 75; j++){           //列
			//设置光标
			gotoXY(j, i);
			if (i == 6 || i == 22)
			{
				printf("=");
			}
			else if (j == 20 || j == 75)
			{
				printf("|");
			}
			else
			{
				printf(" ");
			}
		}
	}
	//输出游戏说明列表
	gotoXY(30, 8);
	setColor(3);
	printf("★ 1.不能撞到墙,也不能咬到自己");

	gotoXY(30, 11);
	setColor(5);
	printf("★ 2.F1加速前进, F2减速前进");

	gotoXY(30, 14);
	setColor(11);
	printf("★ 3.使用空格暂停或继续游戏");

	gotoXY(30, 17);
	setColor(13);
	printf("★ 4.使用↑↓→←控制前进方向");

	gotoXY(30, 20);
	setColor(14);
	printf("★ 5.按下Esc键盘退出游戏");

	gotoXY(20, 24);
	setColor(12);
	printf("请按下回车键返回主界面");


	return 0;
}

//输出游戏地图
int printMap(void)
{
	int i, j;

	//清屏
	system("cls");

	//行 27行
	for (i = 0; i < 27; i++){
		//一个方块占2列
		for (j = 0; j < 57; j = j + 2){
			gotoXY(j, i);
			//边框
			if (i == 0 || i == 26 || j == 0 || j == 56)
			{
				setColor(5);
				printf("□");
			}
			else
			{
				setColor(3);
				printf("■");
			}
		}
	}
	return 0;

}

//显示提示和得分
int showScoreTips(void)
{
	int highScore = 0;
	//显示最高得分  文件读取

	gotoXY(64, 4);
	setColor(3);
	highScore = readFile();

	printf("☆☆最高分记录☆☆:%d ", highScore);

	//显示得分
	gotoXY(64, 8);
	setColor(14);
	printf("得分:%d", score);

	//显示温馨提示
	gotoXY(72, 11);
	setColor(12);
	printf("温 馨 提 示");

	//输出上下边框
	setColor(10);
	gotoXY(60, 13);
	printf("========================================");

	gotoXY(60, 25);
	printf("========================================");

	setColor(13);
	gotoXY(64, 14);
	printf("※吃掉每个食物得分:%d 分", add);

	gotoXY(64, 16);
	printf("※ 不能撞到墙,不能撞到自己");

	gotoXY(64, 18);
	printf("※ F1加速前进,F2减速前进");

	gotoXY(64, 20);
	printf("※ 使用空格键暂停或继续游戏");

	gotoXY(64, 22);
	printf("※ 使用↑↓→←控制前进方向");

	gotoXY(64, 24);
	printf("※ 按下Esc键盘退出游戏");

	return 0;

}

//从文件中读取最高分记录
int readFile(void)
{
	int n = 0;

	FILE *fp = NULL;
	//打开文件   r--读方式
	fp = fopen("data.txt", "r");
	if (NULL == fp)
	{
		printf("打开文件失败…\n");
		return 1;
	}

	//读文件 fread fscanf
	//从文件中读取一个int类型 保存到n变量中
	fscanf(fp, "%d", &n);

	//关闭文件
	fclose(fp);

	return n;
}

//初始化蛇
int initSnake(void)
{
	int i = 0;
	snake_t  *new = NULL;
	snake_t  *tmp = NULL;

	//循环创建4各结点
	for (i = 0; i < 4; i++){
		//分配空间
		new = malloc(sizeof(snake_t));
		if (NULL == new)
		{
			printf("malloc failed…\n");
			break;
		}
		memset(new, 0, sizeof(snake_t));

		//初始化列 是个偶数
		new->x = 24 + i * 2;
		//初始化行
		new->y = 5;

		//头插法
		new->next = head;
		head = new;
	}

	//绘制蛇
	tmp = head;
	while (NULL != tmp)
	{
		//设置蛇的颜色为黄色
		setColor(14);
		gotoXY(tmp->x, tmp->y);

		//如果是第一个节点  输出圆形符号
		if (head == tmp)
		{
			printf("●");
		}
		else
		{
			printf("★");
		}

		//指向下一个节点
		tmp = tmp->next;
	}
	return 0;
}

//随机食物
int randFood(void)
{
	snake_t *new = NULL;
	snake_t *tmp = NULL;

	//分配空间
	new = malloc(sizeof(snake_t));
	if (NULL == new)
	{
		printf("malloc failed…\n");
		return -1;
	}

	//循环随机食物  保证食物没有在蛇身
	while (1)
	{
		//清零
		memset(new, 0, sizeof(snake_t));
		//随机x值
		while (1)
		{
			//随机x值    是一个偶数(2,54)
			//rand() %53 -->(0,  52)      -->+2   -->(2,54)
			new->x = rand() % 53 + 2;
			if (new->x % 2 == 0)
			{
				break;
			}
		}

		//rand()产生一个随机数
		//(1,25)
		//rand( ) % 25 --> (0,24)     -->+1   -->(1,25)
		new->y = rand() % 25 + 1;

		//判断食物不能在蛇身上
		tmp = head;
		while (NULL != tmp)
		{
			if ((tmp->x == new->x) && (tmp->y == new->y))
			{
				break;
			}
			tmp = tmp->next;
		}

		//食物不在蛇身上
		if (NULL == tmp)
		{
			gotoXY(new->x, new->y);
			setColor(12);
			printf("●");

			//食物指针
			food = new;
			break;
		}
		else
		{
			continue;
		}
	}
	return 0;
}

//蛇的移动
int moveSnake(void)
{
	snake_t *new = NULL;
	snake_t *tmp = NULL;
	snake_t *save = NULL;

	//分配空间
	new = malloc(sizeof(snake_t));
	if (NULL == new)
	{
		printf("malloc failed…\n");
		return -1;
	}
	memset(new, 0, sizeof(snake_t));

	//向上
	if (direction == UP)
	{
		new->x = head->x;
		new->y = head->y - 1;
	}

	//向下
	if (direction == DOWN)
	{
		new->x = head->x;
		new->y = head->y + 1;
	}

	//向左
	if (direction == LEFT)
	{
		new->x = head->x - 2;
		new->y = head->y;
	}

	//向右
	if (direction == RIGHT)
	{
		new->x = head->x + 2;
		new->y = head->y;
	}

	//头插法
	new->next = head;
	head = new;

	//使用临时节点指向链表第一个节点
	tmp = head;
	//前面是否为食物
	if ((head->x == food->x) && (head->y == food->y))
	{
		while (NULL != tmp)
		{
			//设置蛇的颜色为黄色
			setColor(14);
			gotoXY(tmp->x, tmp->y);

			//如果是第一个节点  输出圆形符号
			if (head == tmp)
			{
				printf("●");
			}
			else
			{
				printf("★");
			}

			//指向下一个节点
			tmp = tmp->next;
		}

		//吃掉食物后分数增加
		score = score + add;

		//随机食物
		randFood();
	}
	else
	{
		//删除最后一个节点
		while (NULL != tmp->next)
		{
			//设置蛇的颜色为黄色
			setColor(14);
			gotoXY(tmp->x, tmp->y);

			//如果是第一个节点  输出圆形符号
			if (head == tmp)
			{
				printf("●");
			}
			else
			{
				printf("★");
			}

			//保存tmp节点
			save = tmp;
			//指向下一个节点
			tmp = tmp->next;
		}

		gotoXY(tmp->x, tmp->y);
		setColor(3);
		printf("■");

		save->next = NULL;
		free(tmp);
		tmp = NULL;
	}

	return 0;
}

//通过按键控制蛇的移动
int moveKeyControl(void)
{
	//默认向右
	direction = RIGHT;

	while (1)
	{
		//更新显示分数和提示
		showScoreTips();

		//向上
		if (GetAsyncKeyState(VK_UP) && direction != DOWN)
		{
			direction = UP;
		}

		//向下
		if (GetAsyncKeyState(VK_DOWN) && direction != UP)
		{
			direction = DOWN;
		}

		//向左
		if (GetAsyncKeyState(VK_LEFT) && direction != RIGHT)
		{
			direction = LEFT;
		}

		//向右
		if (GetAsyncKeyState(VK_RIGHT) && direction != LEFT)
		{
			direction = RIGHT;
		}

		//按下空格键 暂停或者继续
		if (GetAsyncKeyState(VK_SPACE))
		{
			while (1)
			{
				if (GetAsyncKeyState(VK_SPACE))
				{
					break;
				}
				//睡眠200ms
				Sleep(200);
			}
		}

		//按下F5加速
		if (GetAsyncKeyState(VK_F2))
		{
			speedUp();
		}

		//按下F6减速
		if (GetAsyncKeyState(VK_F2))
		{
			speedDown();
		}

		//按下Esc结束游戏
		if (GetAsyncKeyState(VK_ESCAPE))
		{
			endStatus = 3;
			endGame();
			break;
		}

		moveSnake();

		//判断蛇是否撞墙
		if (isHitWall())
		{
			endStatus = 1;
			endGame();
			break;
		}

		//判断蛇是否咬到自己
		if (isBitSelf())
		{
			endStatus = 2;
			endGame();
			break;
		}
		Sleep(sleepTime);
	}
	return 0;
}

//加速移动
int speedUp(void)
{
	if (sleepTime > 50)
	{
		sleepTime = sleepTime - 10;

		//增加的分数
		add = add + 2;
	}
	return 0;
}

//减速移动
int speedDown(void)
{
	if (sleepTime<300)
	{
		sleepTime = sleepTime + 10;

		//增加的分数
		add = add - 2;
	}

	if (sleepTime > 250)
	{
		add = 1;
	}
	return 0;
}

//判断是否撞墙 如果撞墙返回1 否则返回0
int isHitWall(void)
{
	if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
	{
		return 1;
	}
	return 0;

}

//判断蛇是否咬到自己 如果咬到自己返回1 否则返回0
int isBitSelf(void)
{
	snake_t *tmp = NULL;

	tmp = head->next;
	while (NULL != tmp)
	{
		if ((head->x == tmp->x) && (head->y == tmp->y))
		{
			return 1;
		}
		tmp = tmp->next;
	}
	return 0;
}

//游戏失败边框
int failGameUi(void)
{
	int i;

	//清屏
	system("cls");

	//显示标题
	gotoXY(44, 3);
	setColor(12);
	printf("游 戏 失 败!!!");

	//输出上下边框
	gotoXY(17, 5);
	setColor(3);
	printf("+----------------------------------------------------------------+");

	gotoXY(17, 20);
	printf("+----------------------------------------------------------------+");

	for (i = 6; i < 20; i++)
	{
		gotoXY(17, i);
		printf("|");

		gotoXY(82, i);
		printf("|");
	}

	return 0;

}

//游戏失败提示
int endGame(void)
{
	int n;
	int highScore = 0;

	while (1)
	{


		//显示失败界面边框
		failGameUi();

		//1.撞到墙壁
		//2.咬到自己
		//3.按下Esc键
		gotoXY(38, 9);
		setColor(12);

		switch (endStatus)
		{
			//1.撞到墙壁
		case 1:
			printf("您撞到墙壁,游戏结束!!!");
			break;
			//2.咬到自己
		case 2:
			printf("您咬到自己,游戏结束!");
			break;
			//3.按下Esc键
		case 3:
			printf("您已经结束游戏,游戏结束");
			break;
		default:
			break;
		}

		//显示您的得分
		gotoXY(43, 12);
		setColor(13);
		printf("您的得分:%d", score);

		//显示最高得分
		highScore = readFile();

		//显示是否刷记录
		gotoXY(38, 16);
		setColor(10);
		//没有创记录
		if (highScore > score)
		{
			printf("加油喔,离最高分还差%d分", highScore - score);
		}
		else
		{
			printf("恭喜你,你已经创记录了!!!");
			//将最高分写入文件里面
			writeFile(score);
		}

		//显示菜单
		gotoXY(25, 23);
		setColor(12);
		printf("再玩一局请输入:1");

		gotoXY(52, 23);
		printf("直接退出请输入:2");

		gotoXY(46, 25);
		setColor(11);
		printf("请选择:");

		//等待用户输入一个数字
		scanf("%d", &n);
		//清除掉换行符
		getchar();

		if (1 == n)
		{
			//还原到最初状态
			sleepTime = 250;
			score = 0;
			add = 1;

			//销毁蛇节点
			snakeDestroy();

			//初始化头指针为空
			head = NULL;

			break;
		}
		else if (2 == n)
		{
			//结束程序
			exit(0);
		}
		else
		{
			//
			setColor(12);
			gotoXY(30, 27);
			printf("您的输入有误,请重新输入,按下任意键继续");
			getchar();
			continue;
		}

	}
	return 0;
}


//写文件
int writeFile(void)
{
	FILE *fp = NULL;
	//打开文件
	fp = fopen("data.txt", "w");
	if (NULL == fp)
	{
		printf("打开文件失败..\n");
		return -1;
	}

	//写文件
	fprintf(fp, "%d", score);

	//关闭文件
	fclose(fp);

	return 0;

}

//销毁蛇节点
int snakeDestroy(void)
{
	snake_t *tmp = NULL;
	snake_t *save = NULL;

	//指向链表的第一个节点
	tmp = head;
	while (NULL != tmp)
	{
		save = tmp->next;

		free(tmp);

		tmp = save;
	}

	head = NULL;

	return 0;
}
2. main.c    //主函数(包含并调用snake.c中蛇运动函数)
	#define _CRT_SECURE_NO_WARNINGS
	#include"snake.h"
	
	int main(){
	int n;//设置控制台宽高
	system("mode con cols=100 lines=30");

	//设置随机种子
	srand((unsigned int)time(NULL));

	while (1){
		//清屏
		system("cls");

		n = welcomeGame();

		switch (n){
			//开始游戏
		case 1:
			//printf("Loading……\n");
			printMap();

			//显示温馨提示
			showScoreTips();

			//初始化蛇
			initSnake();

			//随机食物
			randFood();

			//通过按键控制蛇的移动
			moveKeyControl();

			break;

			//游戏说明
		case 2:
			aboutGame();
			//printf("游戏说明\n");
			//跳出switch结构
			break;

			//退出游戏
		case 3:
			//结束程序
			exit(0);
			break;

		default:
			;
		}
		//等待用户输入任意一个字符
		getchar();
	}
	system("pause");
	return 0;
	}
3.snake.h    //全局头文件(包含snake.c中的函数声明)
#pragma once

//标准输入和输出
#include<stdio.h>

//字符串处理相关文件
#include<string.h>

//通用函数相关头文件
#include<stdlib.h>

//WindowsAPI相关头文件
#include<Windows.h>

//时间相关头文件
#include<time.h>

//向上
#define UP 1
//向下
#define DOWN 2
//向左
#define LEFT 3
//向右
#define RIGHT 4

//声明蛇节点结构体类型
typedef struct _snake_t{
	//表示x坐标系
	int x;
	//表示y坐标值
	int y;
	//指向蛇下一个节点
	struct _snake_t  *next;
}snake_t;

//设置终端字体颜色
int setColor(int c);

//绘制字符画蛇
int printSnake(void);

//欢迎界面
int welcomeGame(void);

//显示游戏说明
int aboutGame(void);

//输出游戏地图
int printMap(void);

//显示提示和得分
int showScoreTips(void);

//从文件中读取最高分记录
int readFile(void);

//初始化蛇
int initSnake(void);

//随机食物
int randFood(void);

//移动蛇
int moveSnake(void);

//通过按键控制蛇的移动
int moveKeyControl(void);

//加速移动
int speedUp(void);

//减速移动
int speedDown(void);

//判断是否撞墙 
int isHitWall(void);

//判断蛇是否咬到自己
int isBitSelf(void);

//游戏失败边框
int failGameUi(void);

//游戏失败提示
int endGame(void);

//写文件
int writeFile(int score);

//销毁蛇节点
int snakeDestroy(void);

🔰移植运行演示

新建VS工程项目,复制以上3个源文件源码到工程文件后,编译运行(Ctrl + F5)。

新建工程


✅干货分享——C程设实战高效提升

小试牛刀(C实例)

》》》渐入佳境 (C 语言经典100例)

C 语言经典100例

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Python项目案例开发从入门到实战的主题为爬虫、游戏和机器学习源码。这本书旨在让读者通过实际案例的开发,逐步掌握Python的应用技巧和项目开发经验。 首先,书中介绍了爬虫的基础知识和原理,然后通过实战案例,教读者如何使用Python编写自己的爬虫程序。案例涵盖了从简单的网页爬取到级的数据挖掘和分析。读者通过学习这些案例,可以了解爬虫的工作原理和实际应用。 其次,书中还介绍了Python游戏开发的基础知识和技巧。读者可以通过案例学习如何使用Python库和框架,编写自己的游戏程序。案例涵盖了不同类型的游戏,包括文字冒险游戏、迷宫游戏和简单的图形游戏等。读者通过实践,可以逐步提升自己的游戏开发技能。 最后,书中还介绍了机器学习的基本原理和常用算法。通过案例,读者可以学习如何使用Python编写机器学习模型,进行数据预处理和特征工程,并进行模型评估和优化。案例涵盖了分类、回归和聚类等不同类型的机器学习任务,读者可以通过这些案例加深对机器学习的理解,提升自己的数据科学能力。 总体来说,这本书通过实际案例的开发,引导读者逐步掌握Python的应用技巧和项目开发经验。爬虫、游戏和机器学习源码的学习将帮助读者在实践中提升自己的编程能力,并为未来的项目开发打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值