【算法入门】基于基础算法的简易贪吃蛇小游戏(新手向)

        这是大二生为社团招新写的一个基础游戏代码,学了c语言循环、递归就能看懂。

        由于是基础算法简易贪吃蛇代码,在这里我们直接设定地图为10*10的正方形,

在这里,我们先设计一些最基础的游戏规则和游戏道具:

        贪吃蛇每次向上、右、下、左选择一个方向移动(由玩家输入数字1、2、3、4决定)

        贪吃蛇碰壁、碰到自己的身体则游戏失败。

        地图上有两种道具,分别为:‘ * ’(果实)使蛇身长加一

                                                       ‘ # ’(陷阱)如果触碰陷阱则游戏失败

        将地图上所有果实吃完则游戏获胜,结束游戏。

        我们首先设计一个地图初始化函数:SetMAP()

        

void SetMAP(char* MAP) {
	srand(time(0));//设置随机数种子
	for (int i = 0; i < 100; i++) {
		int random = rand() % 8;//产生0-8的随机数
		if (random == 0) {
			MAP[i] = '*';//8分之一的概率是果实
		}
		else if (random == 1) {
			MAP[i] = '#';//8分之一的概率是陷阱
		}
		else if {
			MAP[i] = '0';//其余的都是空地(用‘0’表示)
		}
	}
}

这里我们传入一个字符类型的指针MAP,对字符数组进行初始化

使用srand设置随机数种子,以防产生的随机数不随机

使用rand()方法产生伪随机数,当随机数random=0时标记为果实,当随机数random=1时标记为陷阱,其余情况都标记空地。

接着,我们再设计一个地图打印函数,用于打印出当前的蛇位置以及道具情况。

void printMAP(char* a) {
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			cout << a[i*10+j];
			if (j == 9) {//每输出10个元素,输出换行
				cout << endl;
			}
		}
	}
	cout << endl;
}

这里由于个人习惯,我使用了iostream里的cout方法进行输出,没有接触C++的同学可以使用printf()函数代替使用,效果一样。

c语言中换行为 \n

接着是程序的主要函数,也是功能函数gaming()函数

void gaming(int x,int y) {
	//判断是否越界
	if (x < 0 || x>9 || y < 0 || y>9) {
		cout << "Fail Out of range" << endl;
		return;
	}
	//判断是否存在食物在地图上,用作获胜条件判断
	for (int i = 0; i < MAX * MAX; i++) {
		if (MAP[i] == '*') {
			f= 0;
			break;
		}
	}
	if (f == 1) {
		cout<<"WIN"<<endl;
		return;
	}
	int i;//玩家输入运动方向
	std::cin >> i;
	if (i == 1) {//向上运动
		x--;//向上移动一格
		if (MAP[x * 10 + y] == 'w') {//判断是否碰到自己
			cout << "Fail touching yourself" << endl;
			return;
		}
		for (int i = 0; i < q.size(); i++) {//清空之前的路径
			MAP[q[i]] = '0';
		}
		q.insert(q.begin(), x * 10 + y);//将位置插入队列
		if (MAP[x * 10 + y] == '#') {//判断是否碰到陷阱
			cout << "Fail touching the wall" << endl;
			return;
		}
		else if (MAP[x * 10 + y] != '*') {//判断是否碰到食物,如果碰到就删除队列最后一个元素
			q.pop_back();
		}
		if (x < 0) {//判断是否越界
			cout << "Fail out of range" << endl;
			return;
		}
	}
	else if (i == 2) {//向右运动
		y++;//向下移动一格
		if (MAP[x * 10 + y] == 'w') {//判断是否碰到自己
			cout << "Fail touching yourself" << endl;
			return;
		}
		for (int i = 0; i < q.size(); i++) {//清空之前的路径
			MAP[q[i]] = '0';
		}
		q.insert(q.begin(), x * 10 + y);//将位置插入队列
		if (MAP[x * 10 + y] == '#') {//判断是否碰到陷阱
			cout << "Fail touching the wall" << endl;
			return;
		}
		else if (MAP[x * 10 + y] != '*') {//判断是否碰到食物,如果碰到就删除队列最后一个元素
			q.pop_back();
		}
		if (y > 9) //判断是否越界
		{
			cout << "Fail out of range" << endl;
			return;
		}
		
	}
	
	else if (i == 3) {//向下运动
			x++;
			if (MAP[x * 10 + y] == 'w') {
				cout << "Fail touch yourself" << endl;
				return;
			}
			for (int i = 0; i < q.size(); i++) {
				MAP[q[i]] = '0';
			}
			q.insert(q.begin(), x * 10 + y);
			if (MAP[x * 10 + y] == '#') {
				cout << "Fail Of wall" << endl;
				return;
			}
			else if (MAP[x * 10 + y] != '*') {
				q.pop_back();
			}
			if (x > 9) {
				cout << "Fail Out of range" << endl;
				return;
			}
	}
	else if (i == 4) {//向左运动
			y--;
			if (MAP[x * 10 + y] == 'w') {
				cout << "Fail touch yourself" << endl;
				return;
			}
			for (int i = 0; i < q.size(); i++) {
				MAP[q[i]] = '0';
			}
			q.insert(q.begin(), x * 10 + y);
			if (MAP[x * 10 + y] == '#') {
				cout << "Fail Of wall" << endl;
				return;
			}
			else if (MAP[x * 10 + y] != '*') {
				q.pop_back();
			}
			if (y < 0) {
				cout << "Fail Out of range" << endl;
				return;
			}
	}
	
	MAP[x * 10 + y] = '0';//将当前位置置为0
	
	for (int i = 0; i < q.size(); i++) {//将路径上的位置改为w
		MAP[q[i]] = 'w';
	}
	
	printMAP(MAP);//输出一次,表示此时蛇的状态
	
	f = 1;//将获胜标志置为1
	gaming(x, y);//进入下一个动作阶段
}

代码比较长,而且if判断较多,但其实很简单,大多都是重复的判断与处理。

需要注意的是,为了方便蛇身体信息的更新,我们在每一次游戏运动过程中将运动轨迹清除,再根据我们记录的轨迹队列更新到地图上,实现蛇的动态变化。

那么到这里,为我们的功能就已经实现了,接下来就是主函数的编写

int main() {
	cout<<"上1,右2,下3,左4"<<endl;
	SetMAP(MAP);//初始化一次地图
	printMAP(MAP);
	cout << "请输入初始位置" << endl;
	int x, y;
	int a, b;
	cin >> a >> b;
	x = a - 1;//调整下标
	y = b - 1;//调整下标
	if (MAP[10*x+y]!='0') {
		cout << "Fail Wrong position" << endl;
		return 0;
	}
	MAP[10*x+y] = 'w';
	q.insert(q.begin(), x * 10 + y);
	printMAP(MAP);
	MAP[10*x+y] = '0';
	gaming(x, y);
	return 0;
}

至此,我们的小游戏就完整编写完毕了,快动手试试吧!

完整代码如下

#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<vector>
#define MAX 10
std::vector<int>q;
int f = 1;
char MAP[MAX*MAX] = {  };
using namespace std;
void SetMAP(char* MAP) {
	srand(time(0));
	for (int i = 0; i < 100; i++) {
		int random = rand() % 8;
		if (random == 0) {
			MAP[i] = '*';
		}
		else if (random == 1) {
			MAP[i] = '#';
		}
		else   {
			MAP[i] = '0';
		}
	}
}
void printMAP(char* a) {
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			cout << a[i*10+j];
			if (j == 9) {//每输出10个元素,输出换行
				cout << endl;
			}
		}
	}
	cout << endl;
}
void gaming(int x,int y) {
	//判断是否越界
	if (x < 0 || x>9 || y < 0 || y>9) {
		cout << "Fail Out of range" << endl;
		return;
	}
	//判断是否存在食物在地图上,用作获胜条件怕判断
	for (int i = 0; i < MAX * MAX; i++) {
		if (MAP[i] == '*') {
			f= 0;
			break;
		}
	}
	if (f == 1) {
		cout<<"WIN"<<endl;
		return;
	}
	int i;//玩家输入运动方向
	std::cin >> i;
	if (i == 1) {//向上运动
		x--;//向上移动一格
		if (MAP[x * 10 + y] == 'w') {//判断是否碰到自己
			cout << "Fail touching yourself" << endl;
			return;
		}
		for (int i = 0; i < q.size(); i++) {//清空之前的路径
			MAP[q[i]] = '0';
		}
		q.insert(q.begin(), x * 10 + y);//将位置插入队列
		if (MAP[x * 10 + y] == '#') {//判断是否碰到陷阱
			cout << "Fail touching the wall" << endl;
			return;
		}
		else if (MAP[x * 10 + y] != '*') {//判断是否碰到食物,如果碰到就删除队列最后一个元素
			q.pop_back();
		}
		if (x < 0) {//判断是否越界
			cout << "Fail out of range" << endl;
			return;
		}
	}
	else if (i == 2) {//向右运动
		y++;//向下移动一格
		if (MAP[x * 10 + y] == 'w') {//判断是否碰到自己
			cout << "Fail touching yourself" << endl;
			return;
		}
		for (int i = 0; i < q.size(); i++) {//清空之前的路径
			MAP[q[i]] = '0';
		}
		q.insert(q.begin(), x * 10 + y);//将位置插入队列
		if (MAP[x * 10 + y] == '#') {//判断是否碰到陷阱
			cout << "Fail touching the wall" << endl;
			return;
		}
		else if (MAP[x * 10 + y] != '*') {//判断是否碰到食物,如果碰到就删除队列最后一个元素
			q.pop_back();
		}
		if (y > 9) //判断是否越界
		{
			cout << "Fail out of range" << endl;
			return;
		}
		
	}
	
	else if (i == 3) {//向下运动
			x++;
			if (MAP[x * 10 + y] == 'w') {
				cout << "Fail touch yourself" << endl;
				return;
			}
			for (int i = 0; i < q.size(); i++) {
				MAP[q[i]] = '0';
			}
			q.insert(q.begin(), x * 10 + y);
			if (MAP[x * 10 + y] == '#') {
				cout << "Fail Of wall" << endl;
				return;
			}
			else if (MAP[x * 10 + y] != '*') {
				q.pop_back();
			}
			if (x > 9) {
				cout << "Fail Out of range" << endl;
				return;
			}
	}
	else if (i == 4) {//向左运动
			y--;
			if (MAP[x * 10 + y] == 'w') {
				cout << "Fail touch yourself" << endl;
				return;
			}
			for (int i = 0; i < q.size(); i++) {
				MAP[q[i]] = '0';
			}
			q.insert(q.begin(), x * 10 + y);
			if (MAP[x * 10 + y] == '#') {
				cout << "Fail Of wall" << endl;
				return;
			}
			else if (MAP[x * 10 + y] != '*') {
				q.pop_back();
			}
			if (y < 0) {
				cout << "Fail Out of range" << endl;
				return;
			}
	}
	
	MAP[x * 10 + y] = '0';//将当前位置置为0
	
	for (int i = 0; i < q.size(); i++) {//将路径上的位置改为w
		MAP[q[i]] = 'w';
	}
	
	printMAP(MAP);//输出一次,表示此时蛇的状态
	
	f = 1;//将获胜标志置为1
	gaming(x, y);//进入下一个动作阶段
}
int main() {
	cout<<"上1,右2,下3,左4"<<endl;
	SetMAP(MAP);//初始化一次地图
	printMAP(MAP);
	cout << "请输入初始位置" << endl;
	int x, y;
	int a, b;
	cin >> a >> b;
	x = a - 1;//调整下标
	y = b - 1;//调整下标
	if (MAP[10*x+y]!='0') {
		cout << "Fail Wrong position" << endl;
		return 0;
	}
	MAP[10*x+y] = 'w';
	q.insert(q.begin(), x * 10 + y);
	printMAP(MAP);
	MAP[10*x+y] = '0';
	gaming(x, y);
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值