对字符游戏贪吃蛇的设计及算法介绍

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/SYSU_yzt/article/details/78888935
#pragma warning(disable:4996)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SNAKE_MAX_LENGTH 20
#define SNAKE_HEAD 'H'
#define SNAKE_BODY 'X'
#define BLANK_CELL ' '
#define SNAKE_FOOD '$'
#define WALL_CELL '*'

void snakemove(int, int, int);

void put_money(void);

void output(void);

void gameover(void);

char map[12][12] =
{
    "************",
    "*XXXXH     *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "************",
};

int x;
int y;
int n = 1;
char t;

int snakeY[SNAKE_MAX_LENGTH] = { 5,4,3,2,1 };
int snakeX[SNAKE_MAX_LENGTH] = { 1,1,1,1,1 };
int snakelength = 5;
int turn = 0;
int holdx;
int holdy;
int i;
int j;
int key=0;
int moneyX;
int moneyY;

int main()
{
    srand(time(NULL));
    put_money();
    while (n)
    {

        for (i = 0; i < snakelength; i++)
        {
            if (snakeX[i] == moneyX&&snakeY[i] == moneyY)
            {
                snakelength++;
                /*for (j = snakelength-1; j >0; j--)
                {
                    snakeX[j] = snakeX[j - 1];
                    snakeY[j] = snakeY[j - 1];
                }
                switch (turn)
                {
                case 1:snakeX[0] = snakeX[1]; snakeY[0] = snakeY[1] - 1; break;
                case 2:snakeX[0] = snakeX[1]; snakeY[0] = snakeY[1] + 1; break;
                case 3:snakeY[0] = snakeY[1]; snakeX[0] = snakeX[1] - 1; break;
                case 4:snakeY[0] = snakeY[1]; snakeX[0] = snakeX[1] + 1; break;
                }*/
                snakeX[snakelength - 1] = snakeX[snakelength - 2] + snakeX[snakelength - 2] - snakeX[snakelength - 3];
                snakeY[snakelength - 1] = snakeY[snakelength - 2] + snakeY[snakelength - 2] - snakeY[snakelength - 3];
                put_money();
                break;
            }
        }
        for (x = 0; x < snakelength; x++)
        {
            for (y = 0; y < snakelength; y++)
            {
                if (snakeX[x] == snakeX[y] && snakeY[x] == snakeY[y]&&x!=y)
                {
                    key = 1;
                }
            }
        }
        map[moneyX][moneyY] = '$';
        for (x = 0; x < 12; x++)
        {
            for (y = 0; y < 12; y++)
            {
                printf("%c", map[x][y]);
            }
            printf("\n");
        }
        switch (getch())
        {
        case 'A':snakemove(snakeX[0], snakeY[0], 1);     break;
        case 'D':snakemove(snakeX[0], snakeY[0], 2);     break;
        case 'W':snakemove(snakeX[0], snakeY[0], 3);     break;
        case 'S':snakemove(snakeX[0], snakeY[0], 4);     break;
        }

        for (i = 0; i < snakelength; i++)
        {
            if (snakeX[i] == 0 || snakeX[i] == 11 || snakeY[i] == 0 || snakeY[i] == 11)
            {
                key = 1;
            }
        }

        if (key)
        {
            system("cls");
            printf("Game Over\n");
            break;
        }

        for (x = 1; x < 11; x++)
        {
            for (y = 1; y < 11; y++)
            {
                map[x][y] = ' ';
            }
        }

        for (i = 0; i < snakelength; i++)
        {
            map[snakeX[i]][snakeY[i]] = 'X';
        }
        map[snakeX[0]][snakeY[0]] = 'H';


        system("cls");
    }
    return 0;
}

void snakemove(int x, int y, int k)
{
    int counter;
    switch (k)
    {
    case 1:
        for (counter = snakelength - 1; counter >0; counter--)
        {
            snakeX[counter] = snakeX[counter - 1];
            snakeY[counter] = snakeY[counter - 1];
        }
        snakeY[0] = snakeY[0] - 1;
        turn = 1;
        break;
    case 2:
        for (counter = snakelength - 1; counter > 0; counter--)
        {
            snakeX[counter] = snakeX[counter - 1];
            snakeY[counter] = snakeY[counter - 1];
        }
        snakeY[0] = snakeY[0] + 1;
        turn = 2;
        break;
    case 3:
        for (counter = snakelength - 1; counter >0; counter--)
        {
            snakeX[counter] = snakeX[counter - 1];
            snakeY[counter] = snakeY[counter - 1];
        }
        snakeX[0] = snakeX[0] - 1;
        turn = 3;
        break;
    case 4:
        for (counter = snakelength - 1; counter>0; counter--)
        {
            snakeX[counter] = snakeX[counter - 1];
            snakeY[counter] = snakeY[counter - 1];
        }
        snakeX[0] = snakeX[0] + 1;
        turn = 4;
        break;
    }
}

void put_money()
{
    int op = 1;
    while (op)
    {
        moneyX = (rand() % 10) + 1;
        moneyY = (rand() % 10) + 1;
        op = 0;
        for (i = 0; i < snakelength; i++)
        {
            if (moneyX == snakeX[i] || moneyY == snakeY[i])
            {
                op = 1;
                break;
            }
        }
    }
}

以上我是设计的字符游戏贪吃蛇的源代码。

(创新)玩法

本游戏遵循经典游戏贪吃蛇的大概思路这里写图片描述
创新方面打算在后续加入移动的障碍物以及有时间限制的食物,在技术上的实现可能性很大,只是后续需要解决的一个问题就是实现程序的流畅性而不是等待输入字符。

基本设计

游戏以二维矩阵map[12][12]作为地图,地图的四周以*字符作为墙壁,蛇身为X,蛇头为H。游戏需要玩家按下“W”,“A”,”S”,”D”中的一个才能将蛇移动,不然程序会一直等待输入停滞下来。游戏利用put_money函数在地图中空白的地方随机摆放金币$,在蛇头碰到金币之后,蛇自动在尾部加一个单位长度,这时候需要注意的是,如果蛇的尾巴紧挨墙壁,那么在吃到金币后,蛇便会死去,出现game over字样。

这里写图片描述

算法介绍

本游戏最关键的算法是蛇的移动,在蛇的移动过程中,只有四个输入WASD,因此我选择使用SWITCH函数来对应四种不同的情况,我们以向右移动D为例。按下D后,我设计了一个FOR循环,循环length-1次,将SNAKEX[N]=SNAKE[N-1],SNAKEY同理,最后一步将蛇头SNAKEX[0],按照我们的输入移动,这样蛇就类似于一条毛毛虫完成了一次蠕动。

猜你喜欢

转载自blog.csdn.net/SYSU_yzt/article/details/78888935