这是大二生为社团招新写的一个基础游戏代码,学了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;
}