字符版贪吃蛇设计思路

    贪吃蛇游戏是经典中的经典,给我们的童年带来欢乐。长大之后本以为会玩一些更高级的没想到还是没逃出贪吃蛇这个坑。 本文就来介绍一下比较简单的字符版的贪吃蛇设计思路。

    用具: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;
}


最后的最后感谢阅读~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值