贪吃蛇游戏是经典中的经典,给我们的童年带来欢乐。长大之后本以为会玩一些更高级的没想到还是没逃出贪吃蛇这个坑。 本文就来介绍一下比较简单的字符版的贪吃蛇设计思路。
用具:visual studio2017
目标:字符版贪吃蛇:可以根据输入的方向(WASD)移动, 吃掉随机出现的食物并长长一个字符。蛇头撞到身体、障碍(边界)游戏结束。
整体思路:
打印带边框*的地图,以随机出现的$作为食物,并初始化蛇XXXXH(H为蛇头)。
先变换组成蛇的每一个字符的坐标, 再判断蛇头变换后的位置。
让每一个输入的指令控制蛇头的移动方向。蛇头每走一步,每一个蛇身字符变换到它前一个字符的位置。
如果变换后的位置为X或*则game over,如果为$则蛇伸长一个字符,伸长的字符和原贪吃蛇最后两个字符在同一条直线上。
如果变换后没有game over则进行地图的打印,并重复操作。
1. 定义变量:
定义一个12*12的二维字符数组mat(除去边框后蛇的移动空间是10*10)。
定义字符order来储存指令。
定义两个足够长的数组x和y来储存组成蛇的每一个字符的位置坐标。
定义伸长的字符的坐标xr,yr和蛇的长度snakelen(初始值为5)。
2. 编写函数printmat实现打印整个地图
首先传入一个数组mat,使用const使得mat不被改变。
void printmat(const char a[12][12])
定义两个变量count1,count2来查循环的次数
接下来使用双重循环将整个地图打印出来并在结尾换行
该函数的源码如下图:
3. 编写函数change实现蛇身的前进和蛇头根据指令的变换(若game over则返回-1,若吃到食物返回1)
返回值类型为int
需要传入数组x和y来代表蛇字符的坐标,传入蛇的长度len,传入整个地图字符数组mat,传入指令order。
首先将蛇身的每一个字符坐标变换到他前一个字符的位置。
然后用switch进行蛇头坐标的变换。
最后判断变换后的蛇头坐标对应的现在的位置上是否为空,若为X或*则返回-1代表gameover,若为$返回1代表吃到食物伸长一个字符。
该函数源码如下图:
4. 初始化地图边框和蛇及蛇的坐标(蛇最初为5个字符)
使用双重循环初始化二维数组。
将蛇身放在地图的左上角以XXXXH排列。
将现在蛇的每个字符的坐标按从舌头到蛇身的顺序存入数组x和y。
源码如下:
5. 随机确定食物的坐标
用变量dete2控制循环的结束。
用random函数为变量xr和yr赋值使其在1—10之间。
判断得到的坐标位置如果为空则结束随机寻找xr,yr,否则一直寻找。
打印最初的方阵。
源码如下图:
6. 用循环执行每一步的输入指令
到了重头戏了, 这一部分是main函数中最重要也是相对复杂的一部分。
首先以dete(change函数的返回值作为循环条件)当dete==-1时game over这时循环需要结束,所以设置循环while (dete != -1)
其次输入指令order,并初始化dete3(用来表示食物的有无)
用if指令筛选不符合规矩的指令if (order >= 'A'&&order <= 'Z')
执行change函数 传递参数并返回一个值
若返回-1则跳出循环执行循环外语句
若返回1则使snakelen + 1同时给新加入的尾巴字符定义坐标使其和前两个字符在一条直线上
按照4.中方法初始化地图边框,并依据坐标位置按顺序打印蛇头蛇身。
接下来如果食物被吃掉则进入循环用5.中的方法重新随机添加食物
最后打印整个地图
7. 最后如果跳出循环则游戏结束输出game over
以上就是字符版贪吃蛇的设计思路, 希望有所帮助, 以下为字符版贪吃蛇的源码,仅供参考~
#include<stdio.h>
#include<stdlib.h>
void printmat(const char a[12][12]);
int change(int x[], int y[], char order, char mat[12][12], int len);
int main(void)
{
char mat[12][12], order;
int x[1000] = { 0 }, y[1000] = { 0 }, count1, count2, dete = 0, snakelen = 5, xr, yr, dete3, dete2 = 1;
for (count1 = 0; count1 < 12; count1++) //initialize the matrix
{
for (count2 = 0; count2 < 12; count2++)
{
if (count1 == 0 || count1 == 11 || count2 == 0 || count2 == 11)
mat[count1][count2] = '*';
else
mat[count1][count2] = ' ';
}
}
for (count1 = 1; count1 < snakelen; count1++) //define the snake's body
{
mat[1][count1] = 'X';
}
mat[1][count1] = 'H'; //define the snake's head
for (count1 = 0; count1 < 5; count1++) //give snake's position(x,y)
{
x[count1] = 1;
}
for (count1 = 1; count1 < 6; count1++)
{
y[count1 - 1] = 6 - count1;
}
while (dete2)
{
xr = rand() % 10 + 1;
yr = rand() % 10 + 1;
if (mat[xr][yr] == ' ')
{
dete2 = 0;
mat[xr][yr] = '$';
}
}
printmat(mat);
while (dete != -1)
{
scanf("%c", &order); //input
dete3 = 0;
if (order >= 'A'&&order <= 'Z') //omit the unless character
{
dete = change(x, y, order, mat, snakelen); //moving from nail to head to change snake's position
if (dete == -1)
{
break; //if H move to X, return -1(gameover)
}
if (dete == 1)
{
snakelen++;
dete3 = 1;
x[snakelen-1] = 2 * x[snakelen - 2] - x[snakelen - 3];
y[snakelen-1] = 2 * y[snakelen - 2] - y[snakelen - 3];
}
for (count1 = 0; count1 < 12; count1++) //initialize the matrix
{
for (count2 = 0; count2 < 12; count2++)
{
if (count1 == 0 || count1 == 11 || count2 == 0 || count2 == 11)
mat[count1][count2] = '*';
else
mat[count1][count2] = ' ';
}
}
mat[x[0]][y[0]] = 'H'; //model the snake's position now
for (count1 = 1; count1 < snakelen; count1++)
{
mat[x[count1]][y[count1]] = 'X';
}
while (dete3)
{
xr = rand() % 10 + 1;
yr = rand() % 10 + 1;
if (mat[xr][yr] == ' ')
{
dete3 = 0;
mat[xr][yr] = '$';
}
}
mat[xr][yr] = '$';
printmat(mat);
}
}
printf("Game over!"); //if head touch nail ,game over
return 0;
}
void printmat(const char a[12][12]) //print the martix
{
int count1, count2;
for (count1 = 0; count1 < 12; count1++)
{
for (count2 = 0; count2 < 12; count2++)
{
printf("%c", a[count1][count2]);
if (count2 == 11)
{
printf("\n");
}
}
}
}
int change(int x[], int y[], char order, char mat[12][12],int len)
{
int count;
for (count = len - 1; count > 0; count--) //give the body's position:give the forward posotion to behind position
{
x[count] = x[count - 1];
y[count] = y[count - 1];
}
switch (order) //give the head position
{
case 'A':
y[0]--;
break;
case 'D':
y[0]++;
break;
case 'W':
x[0]--;
break;
case 'S':
x[0]++;
break;
}
if (mat[x[0]][y[0]] == 'X' || mat[x[0]][y[0]] == '*')
return -1;
if (mat[x[0]][y[0]] == '$')
return 1;
}
最后的最后感谢阅读~