字符游戏-贪吃蛇算法设计

相信大家都玩过贪吃蛇,作为中山大学软件工程专业优秀的学生(说的当然不是我)怎么能连贪吃蛇都不会做呢?(胡言乱语)下面是我的贪吃蛇逻辑,写的比较low,欢迎大佬提出改进意见。
地图、身体、头
首先我们需要一个地图和初始的蛇,可以用一个二维的数组表示。直接手动输入地图和初始的蛇:
这里写图片描述
上面的定义为几个要素的符号,主要是为了改变图形,比如要把蛇头改为@,只要把SNAKE_HEAD改一下就行了。
下面申请几个数组,分别记录蛇的X,Y坐标和食物的X,Y坐标:
这里写图片描述

snake-move
这样,我们就有了蛇,接下来考虑怎么让蛇动起来:
伪代码:
WHILE not 游戏结束 DO
ch=等待输入
CASE ch DO
‘A’:左前进一步,break
‘D’:右前进一步,break
‘W’:上前进一步,break
‘S’:下前进一步,break
END CASE
怎么让蛇前进呢?首先,我们控制蛇头的移动:

这里写图片描述

然后,蛇头后面的身体移动到了原来蛇头的位置,然后其他身体移动到上一段身体的位置。这时候我们需要在移动最开始记录一下蛇头的位置:
int presnakeX = snakeX[snakeLength - 1];
int presnakeY = snakeY[snakeLength - 1];//记录原来蛇头的位置

身体移动的实现:

这里写图片描述

然后我们把地图上这些坐标的元素设为相应的符号:

这里写图片描述

但是,这样打出来的地图还会有上一次的蛇,那我们在移动最开始把地图上所有东西全设为空即可:

这里写图片描述

游戏开始、结束
现在,我们的蛇会跑了,但是我们知道,蛇碰到了障碍物或自己会死,也就是游戏结束。我们可以设定一个变量gamerunning=1,如果撞到了障碍物,gamerunning=0,当gamerunning=1时才进行游戏。
if (map[snakeX[snakeLength - 1]][snakeY[snakeLength - 1]] == WALL_CELL || map[snakeX[snakeLength - 1]][snakeY[snakeLength - 1]] == SNAKE_BODY)//判断是否游戏结束
{
GameOver();
}
食物
现在我们需要给游戏添加食物,蛇吃到食物会加长身体。因为吃到食物的运动和一般的运动不同,所以需要一个变量记录是否吃了食物。如果islonger=1则进行吃食物的运动。
蛇吃了食物(即头的坐标等于食物的坐标)长度加一,只需要将蛇头后面加一节而其他位置不动即可。食物通过一个函数food()生成:
这里写图片描述

添加身体:

这里写图片描述

当然运动前要清空蛇,吃了食物后要把食物的位置设为空。
主函数
好了,现在大体的设定已经完成,接下来是主函数。

int main(void)
{
    srand(time(NULL));
    food();//先生成食物
    output();//开始先打印一遍地图
    char control = 0;
    while (gamerunning==1) {
        scanf_s(" %c", &control, 1);
        snakeMove(control);
        output();
    }
    printf("Game Over!!!");
    return 0;
}

output()是打印地图的函数,每运动一次要重新打印一遍地图,但是如果用printf打印,会出现一个又一个静态的地图,这样影响体验感。我们可以用刷屏函数来解决:

void output()//打印地图
{
    system("cls");//刷屏
    for (int i = 0; i < 12; ++i) {
        printf("%s\n", map[i]);
    }
}

OK现在我们的贪吃蛇就做好了。不过这个蛇还有很多不足。首先,输入方向键后要加回车才能运动。然后,蛇碰到障碍后要在随便按一个键游戏才会结束。这些问题我会在以后的学习中逐个改正。

猜你喜欢

转载自blog.csdn.net/ZhangyunqingGC/article/details/78902426