C语言控制台简单实现贪吃蛇(附完整源码)

本文介绍了使用C语言基础语法实现贪吃蛇游戏的方法,涉及kbhit()、getch()等函数用于键盘输入检测,通过系统调用system()清屏,rand()生成随机数决定食物位置。文章详细阐述了游戏的基本思路、代码实现,包括变量声明、主程序、按键检测、食物判定、尾部判定和移动等关键部分,适合初学者练习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        “笔者刚学完c语言基础语法,本着练习的心态用控制台实现了贪吃蛇游戏,于是有了本篇。”

效果预览:

目录

一、预备知识

1、kbhit()

2、getch()

3、system()

4、rand()

二、基本思路

三、代码实现

1、变量声明

2、主程序

3、按键检测

4、食物判定

5、尾部判定加清楚

6、蛇体默认移动、死亡判定

7、源码


公众号摸鱼老K同步更新,感谢关注~


一、预备知识

        基本的语法就不多赘述了,本篇主要介绍基础学习不常涉及到的函数

1、kbhit()

        用于非阻塞地响应键盘输入事件,在本项目中用于检测按键控制蛇体移动。

        功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0

2、getch()

        从stdio流中读字符,即从控制台读取一个字符,但不显示在屏幕上,getch()会暂停输出控制台,直到按下一个键为止,它不使用任何缓冲区来存储输入字符,输入的字符将立即返回,而无需等待回车键。

        返回值:读取的字符的ASCII码值(整数)。

3、system()

int system(const char * command)

        在windows系统中,system函数直接在控制台调用一个command命令。这些命令可以通过system(“HELP”)获取,我们在这只使用system("cls")来清除屏幕输出。

        返回值:命令执行成功返回0,执行失败返回-1。

4、rand()

        rand()函数用于产生一个随机数,其内部实现是用线性同余法实现的,是伪随机数,由于周期较长,因此在一定范围内可以看成是随机的。调用rand()函数会得到一个在0-RAND_MAX。RAND_MAX在头文件stdlib.h中定义。

        我们还可以通过rand()%(n-m+1)+m这个公式实现指定范围(m,n)内的随机数。

二、基本思路

        实现思路就是通过清空控制台再打印输出,如此循环,实现动画效果。

        定义出蛇头,蛇身,蛇尾,程序难点就在蛇体运动和蛇尾判定。首先明确大体过程,蛇头不断朝着正向前进,并且可以通过按键改变方向。蛇的整体运动其实就是蛇头前移,之后在蛇头后面打印出一个蛇身,最后是清楚蛇的末尾,这样就能实现蛇的动态。

        再一个难点是蛇身拐点,也就是多一个拐点蛇身就多处一个运动的矢量,本例程是将拐点xy坐标以及方向存储在三个数组中,通过这三个值判断尾端的移动。这样的好处是编程逻辑清楚简单,相应缺点就是数组大小有限,并且不能释放无用的内存。当你熟练了指针用法之后也可以通过链表存储来改进。这里笔者还不熟练,今后学到可能会回头来优化(刚开始就挖坑~)

        食物就通过随机数生成,死亡判定就直接判断头坐标下一个内容(是墙或者蛇身判定死亡)。

三、代码实现

1、变量声明

//蛇头和蛇身
char head = '#', body = '*';

//蛇头的坐标值,长度,拐点个数
int x = 20, y = 10, length = 10, change = 0;

//记录拐点信息,方向用1233代表wasd
int xchange[999], ychange[999], decation[999] = {0};

//食物坐标
int xfood = 20, yfood = 30;

//尾部坐标,尾部到达拐点标志
int xtail, ytail, tailflag = 0;

2、主程序

int main() {
    //尾部初始值
	xtail = x;
	ytail = y - length;
	while (1) {
        //按键检测函数
		if (kbhit())
			input();
        //蛇体默认移动,触发死亡条件break掉循环
		if (add())
			break;
        //尾部检测,清楚尾部的图案
		tail();
        //吃到食物尾部加长
		addlong();
        //更新屏幕显示
		system("cls");
		printf("\t\t\t成绩:%d\n", length);
		printf("%s", backgd);
	}
	system("cls");
	printf("游戏结束");
	return 0;
}

3、按键检测

用来记录拐点信息

void input() {
	char key = getch();
	change++;
	xchange[change] = x;
	ychange[change] = y;
	if (key == 'w') {
		decation[change] = 1;
	}
	if (key == 'a') {
		decation[change] = 2;
	}
	if (key == 's') {
		decation[change] = 3;
	}
	if (key == 'd') {
		decation[change] = 4;
	}
}

4、食物判定

如果蛇头移动到食物坐标length就会加一,并且再随机一个食物

void addlong() {
	backgd[xfood][yfood] = 'X';
	if (x == xfood && y == yfood && change == 0) {
		length++;
		ytail--;
		xfood = rand() % 25 + 1;
		yfood = rand() % 77 + 1;
	}
	if (x == xfood && y == yfood && change != 0) {
		length++;
		if (decation[tailflag] == 1)
			xtail++;
		if (decation[tailflag] == 2)
			ytail++;
		if (decation[tailflag] == 3)
			xtail--;
		if (decation[tailflag] == 4)
			ytail--;
		xfood = rand() % 25 + 1;
		yfood = rand() % 77 + 1;
	}
}

5、尾部判定加清楚

用tailflag去读取拐点信息,再进行相应的坐标偏移

void tail() {
	if (tailflag == 0) {
		ytail++;
		if (ytail == ychange[tailflag + 1])
			tailflag++;
	} else {
		if (decation[tailflag] == 1) {
			xtail--;
			if (xtail == xchange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
		if (decation[tailflag] == 2) {
			ytail--;
			if (ytail == ychange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
		if (decation[tailflag] == 3) {
			xtail++;
			if (xtail == xchange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
		if (decation[tailflag] == 4) {
			ytail++;
			if (ytail == ychange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
	}
}

6、蛇体默认移动、死亡判定

蛇头根据拐点进行坐标偏移,如果碰到“*”即为死亡

int add() {
	clear();
	if (change == 0) {
		y++;
		backgd[x][y] = head;
		backgd[x][y - 1] = body;
	} else {
		if (decation[change] == 1) {
			if (backgd[x - 1][y] == '*')
				return 1;
			backgd[x - 1][y] = head;
			backgd[x][y] = body;
			x--;
		}
		if (decation[change] == 2) {
			if (backgd[x][y - 1] == '*')
				return 1;
			backgd[x][y - 1] = head;
			backgd[x][y] = body;
			y--;
		}
		if (decation[change] == 3) {
			if (backgd[x + 1][y] == '*')
				return 1;
			backgd[x + 1][y] = head;
			backgd[x][y] = body;
			x++;
		}
		if (decation[change] == 4) {
			if (backgd[x][y + 1] == '*')
				return 1;
			backgd[x][y + 1] = head;
			backgd[x][y] = body;
			y++;
		}
	}
	return 0;
}

7、源码

#include <stdio.h>

char backgd[27][81] = {
	{"********************************************************************************\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"*                                                                              *\n"},
	{"******************************************************************************** "}
};
char head = '#', body = '*';
int x = 20, y = 10, length = 1, change = 0;

int xchange[999], ychange[999], decation[999] = {0};
int xfood = 20, yfood = 30;
int xtail, ytail, tailflag = 0;
void clear() {
	backgd[xtail][ytail] = ' ';
}
void input() {
	char key = getch();
	change++;
	xchange[change] = x;
	ychange[change] = y;
	if (key == 'w') {
		decation[change] = 1;
	}
	if (key == 'a') {
		decation[change] = 2;
	}
	if (key == 's') {
		decation[change] = 3;
	}
	if (key == 'd') {
		decation[change] = 4;
	}
}
void addlong() {
	backgd[xfood][yfood] = 'X';
	if (x == xfood && y == yfood && change == 0) {
		length++;
		ytail--;
		xfood = rand() % 25 + 1;
		yfood = rand() % 77 + 1;
	}
	if (x == xfood && y == yfood && change != 0) {
		length++;
		if (decation[tailflag] == 1)
			xtail++;
		if (decation[tailflag] == 2)
			ytail++;
		if (decation[tailflag] == 3)
			xtail--;
		if (decation[tailflag] == 4)
			ytail--;
		xfood = rand() % 25 + 1;
		yfood = rand() % 77 + 1;
	}
}
void tail() {
	if (tailflag == 0) {
		ytail++;
		if (ytail == ychange[tailflag + 1])
			tailflag++;
	} else {
		if (decation[tailflag] == 1) {
			xtail--;
			if (xtail == xchange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
		if (decation[tailflag] == 2) {
			ytail--;
			if (ytail == ychange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
		if (decation[tailflag] == 3) {
			xtail++;
			if (xtail == xchange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
		if (decation[tailflag] == 4) {
			ytail++;
			if (ytail == ychange[tailflag + 1]) {
				tailflag++;
				return;
			}
		}
	}
}
int add() {
	clear();
	if (change == 0) {
		y++;
		backgd[x][y] = head;
		backgd[x][y - 1] = body;
	} else {
		if (decation[change] == 1) {
			if (backgd[x - 1][y] == '*')
				return 1;
			backgd[x - 1][y] = head;
			backgd[x][y] = body;
			x--;
		}
		if (decation[change] == 2) {
			if (backgd[x][y - 1] == '*')
				return 1;
			backgd[x][y - 1] = head;
			backgd[x][y] = body;
			y--;
		}
		if (decation[change] == 3) {
			if (backgd[x + 1][y] == '*')
				return 1;
			backgd[x + 1][y] = head;
			backgd[x][y] = body;
			x++;
		}
		if (decation[change] == 4) {
			if (backgd[x][y + 1] == '*')
				return 1;
			backgd[x][y + 1] = head;
			backgd[x][y] = body;
			y++;
		}
	}
	return 0;
}
int main() {
	xtail = x;
	ytail = y - length;
	while (1) {
		if (kbhit())
			input();
		if (add())
			break;
		tail();
		addlong();
		system("cls");
		printf("\t\t\t成绩:%d\n", length);
		printf("%s", backgd);
	}
	system("cls");
	printf("游戏结束");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值