贪吃蛇游戏算法

算法思路

贪吃蛇的算法大致可分为

  • 创建地图
  • 创建蛇
  • 随机在地图内产生食物
  • 蛇的移动
    • 智能
      • 蛇头、蛇尾的运动
      • 自动选择方向
    • 手动
      • 读入方向键
      • 蛇头、蛇尾的运动
  • 蛇的捕食
    • 食物的消失
    • 蛇头的运动
  • 判断是否撞墙或撞自己
  • 输出图像

手动蛇

头文件

#include
#include
#include
#include
#include
#include
#include

自定义数值和函数

#define snake_length 5//蛇初始长度
#define map_row 10//地图行
#define map_line 10//地图列
#define snake_head 'H'//蛇头
#define snake_body 'X'//蛇身
#define wail '#'//墙
#define food '*'//食物

int body=1;
char direction = 'd';//蛇移动方向
int tail_x = 1, tail_y = 1;//蛇尾坐标
int head_x = 1, head_y = 5;//初始蛇头位置
int food_x = 1, food_y = 1;//食物位置

void creatmap( char map[map_row][map_line]);//创建地图
void creatsnake(int snake[map_row][map_line]);//初始化蛇的位置
void creatfood(int snake[map_row][map_line]);//随机产生食物
void printmap(char map[map_row][map_line],int snake[map_row][map_line]);//输出地图、蛇、食物
int judge(char map[map_row][map_line]);//判断蛇是否撞墙或撞自己,是返回0,否返回1
void move(int snake[map_row][map_line], char map[map_row][map_line]);//蛇的移动加捕食
void check(char *direction,char *direction1);//排除反方向

主函数

int main()
{
    char map[map_row][map_line];
    int snake[map_row][map_line] = { 0 };
    creatmap(map);
    creatsnake(snake);
    srand((unsigned)time(NULL));
    creatfood(snake);

    int a = 1;
    while (a == 1)//蛇每移动一次判断一次输出一次
    {
        printmap(map,snake);
        move(snake,map);
        a = judge(map);
    }
    printf("Game over");
    return 0;
}

创建地图

void creatmap( char  map[map_row][map_line])//地图大小可调节,可自定义
{
    for (int i = 0; i < map_line; ++i)
    {
        map[0][i] = wail;
        map[map_row-1][i] = wail;
    }
    for (int i = 1; i < map_row-1; ++i)
    {
        map[i][0] = wail;
        map[i][map_line-1] = wail;
    }
    for (int i = 1; i < map_row-1; ++i)
    {
        for (int j = 1; j < map_line-1; ++j)
            map[i][j] = ' ';
    }
}

创建蛇

void creatsnake(int snake[map_row][map_line])//蛇的初始长度为5
{
    for (int i = 1; i < snake_length; ++i)
    {
        snake[1][i] = body;
        ++body;
    }
}

随机产生食物

void creatfood(int snake[map_row][map_line])//随机产生食物不与地图和蛇重合
{
    while (snake[food_x][food_y] != 0)
    {
        food_x = rand() % 8 + 1;
        food_y = rand() % 8 + 1;
    }
    snake[food_x][food_y] = -1;//食物在snake矩阵中用-1表示
}

输出图像

void printmap(char map[map_row][map_line],int snake[map_row][map_line])
{
    /*snake中,0表空闲位置,-1表食物,正数表蛇*/
    for (int i = 1; i < map_row-1; ++i)
    {
        for (int j = 1; j < map_line-1; ++j)
        {
            if (snake[i][j] == 0)map[i][j] = ' ';
            else map[i][j] = snake_body;
        }
    }
    map[head_x][head_y] = snake_head;
    map[food_x][food_y] = food;//蛇头、食物单独定义
    for (int i = 0; i < map_row; ++i)
    {
        for (int j = 0; j < map_line; ++j)
            printf("%c", map[i][j]);
        printf("\n");
    }
}

判断是否撞墙或撞自己

int judge(char map[map_row][map_line])
{
    if (map[head_x][head_y]!=' '&& map[head_x][head_y]!=food)
        return 0;
    else
        return 1;
}

判断读入方向是否与前进方向相反

void check(char *direction,char *direction1)//与前进方向相反不执行
{
    if (*direction == 'w')
        if (*direction1 == 's')
            *direction = 's';
    if (*direction == 's')
        if (*direction1 == 'w')
            *direction = 'w';
    if (*direction == 'a')
        if (*direction1 == 'd')
            *direction = 'd';
    if (*direction == 'd')
        if (*direction1 == 'a')
            *direction = 'a';
}

蛇的移动和捕食

void move(int snake[map_row][map_line], char map[map_row][map_line])
{
    /*w 上
      s 下
      a 左
      d 右*/
    Sleep(1000);//调节速度
    int a;
    if (_kbhit())//判断是否改变方向
    {



        char direction1 = direction;
        direction = getchar();
        check(&direction, &direction1);
        getchar();
    }
        switch (direction)
    {

    case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
    case 's':snake[head_x][head_y] = body; body++; head_x++; break;
    case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
    case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
    }
        if (snake[head_x][head_y] != -1)//没吃到,尾消失,头前进
    {
        a = snake[tail_x][tail_y];
        snake[tail_x][tail_y] = 0;
        if (tail_x + 1 < map_row - 1 && snake[tail_x + 1][tail_y] == a+1)
            tail_x = tail_x + 1;
        else
            if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
                tail_x = tail_x - 1;
            else
                if (tail_y + 1 < map_line - 1 && snake[tail_x][tail_y + 1] == a + 1)
                    tail_y = tail_y + 1;
                else
                    if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1)
                        tail_y = tail_y - 1;
    }
    else//吃到尾不消失,产生新的食物
    {
        creatfood(snake);
    }
}

完整代码

#include
#include
#include
#include
#include
#include
#include

#define snake_length 5//蛇初始长度
#define map_row 10//地图行
#define map_line 10//地图列
#define snake_head 'H'//蛇头
#define snake_body 'X'//蛇身
#define wail '#'//墙
#define food '*'//食物

int body=1;
char direction = 'd';//蛇移动方向
int tail_x = 1, tail_y = 1;//蛇尾坐标
int head_x = 1, head_y = 5;//初始蛇头位置
int food_x = 1, food_y = 1;//食物位置

void creatmap( char map[map_row][map_line]);//创建地图
void creatsnake(int snake[map_row][map_line]);//初始化蛇的位置
void creatfood(int snake[map_row][map_line]);//随机产生食物
void printmap(char map[map_row][map_line],int snake[map_row][map_line]);//输出地图、蛇、食物
int judge(char map[map_row][map_line]);//判断蛇是否撞墙或撞自己,是返回0,否返回1
void move(int snake[map_row][map_line], char map[map_row][map_line]);//蛇的移动加捕食
void check(char *direction,char *direction1);//排除反方向

int main()
{
    char map[map_row][map_line];
    int snake[map_row][map_line] = { 0 };
    creatmap(map);
    creatsnake(snake);
    srand((unsigned)time(NULL));
    creatfood(snake);

    int a = 1;
    while (a == 1)
    {
        printmap(map,snake);
        move(snake,map);
        a = judge(map);
    }
    printf("Game over");
    return 0;
}

void creatmap( char  map[map_row][map_line])
{
    for (int i = 0; i < map_line; ++i)
    {
        map[0][i] = wail;
        map[map_row-1][i] = wail;
    }
    for (int i = 1; i < map_row-1; ++i)
    {
        map[i][0] = wail;
        map[i][map_line-1] = wail;
    }
    for (int i = 1; i < map_row-1; ++i)
    {
        for (int j = 1; j < map_line-1; ++j)
            map[i][j] = ' ';
    }
}
void creatsnake(int snake[map_row][map_line])
{
    for (int i = 1; i < snake_length; ++i)
    {
        snake[1][i] = body;
        ++body;
    }
}
void creatfood(int snake[map_row][map_line])
{
    while (snake[food_x][food_y] != 0)
    {
        food_x = rand() % 8 + 1;
        food_y = rand() % 8 + 1;
    }
    snake[food_x][food_y] = -1;
}
void printmap(char map[map_row][map_line],int snake[map_row][map_line])
{

    for (int i = 1; i < map_row-1; ++i)
    {
        for (int j = 1; j < map_line-1; ++j)
        {
            if (snake[i][j] == 0)map[i][j] = ' ';
            else map[i][j] = snake_body;
        }
    }
    map[head_x][head_y] = snake_head;
    map[food_x][food_y] = food;
    for (int i = 0; i < map_row; ++i)
    {
        for (int j = 0; j < map_line; ++j)
            printf("%c", map[i][j]);
        printf("\n");
    }
}
int judge(char map[map_row][map_line])
{
    if (map[head_x][head_y]!=' '&& map[head_x][head_y]!=food)
        return 0;
    else
        return 1;
}
void check(char *direction,char *direction1)//与前进方向相反不执行
{
    if (*direction == 'w')
        if (*direction1 == 's')
            *direction = 's';
    if (*direction == 's')
        if (*direction1 == 'w')
            *direction = 'w';
    if (*direction == 'a')
        if (*direction1 == 'd')
            *direction = 'd';
    if (*direction == 'd')
        if (*direction1 == 'a')
            *direction = 'a';
}
void move(int snake[map_row][map_line], char map[map_row][map_line])
{
    /*w 上
      s 下
      a 左
      d 右*/
    Sleep(1000);//调节速度
    int a;
    if (_kbhit())//判断是否改变方向
    {



        char direction1 = direction;
        direction = getchar();
        check(&direction, &direction1);
        getchar();
    }



    switch (direction)
    {

    case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
    case 's':snake[head_x][head_y] = body; body++; head_x++; break;
    case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
    case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
    }
        if (snake[head_x][head_y] != -1)//没吃到,尾消失
    {
        a = snake[tail_x][tail_y];
        snake[tail_x][tail_y] = 0;
        if (tail_x + 1 < map_row - 1 && snake[tail_x + 1][tail_y] == a+1)
            tail_x = tail_x + 1;
        else
            if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
                tail_x = tail_x - 1;
            else
                if (tail_y + 1 < map_line - 1 && snake[tail_x][tail_y + 1] == a + 1)
                    tail_y = tail_y + 1;
                else
                    if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1)
                        tail_y = tail_y - 1;
    }
    else//吃到尾不消失,产生新的食物
    {
        creatfood(snake);
    }
}

智能蛇

智能蛇与手动蛇除移动方式外,其余均相同

蛇的移动捕食

void move(int snake[map_row][map_line], char map[map_row][map_line])
{
    /*w 上
      s 下
      a 左
      d 右*/
    Sleep(1000);//调节速度
    int a;
    //蛇头向食物方向靠近
        if (food_y - head_y > 0)direction = 'd';
        else if (food_y - head_y < 0)direction = 'a';
        else if (food_x - head_x > 0)direction = 's';
        else if (food_x - head_x < 0)direction = 'w';

    switch (direction)
    {

    case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
    case 's':snake[head_x][head_y] = body; body++; head_x++; break;
    case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
    case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
    }
    if (map[head_x][head_y]!=' '&&map[head_x][head_y] != food)//判断是否相撞,相撞改方向
    {
        switch (direction)//返回原值
        {

        case 'w': body--; head_x++; break;
        case 's': body--; head_x--; break;
        case 'a': body--; head_y++; break;
        case 'd': body--; head_y--; break;
        }
        if (direction == 'd') {
            if (food_x - head_x >= 0)direction = 's';
            else if (food_x - head_x < 0)direction = 'w';
        }
        else if (direction == 'a')
        {
            if (food_x - head_x >= 0)direction = 's';
            else if (food_x - head_x < 0)direction = 'w';
        }
        else if (direction == 'w')
        {
            if (food_y - head_y >= 0)direction = 'd';
            else if (food_y - head_y < 0)direction = 'a';
        }
        else
        {
            if (food_y - head_y >= 0)direction = 'd';
            else if (food_y - head_y < 0)direction = 'a';
        }
        switch (direction)
        {

        case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
        case 's':snake[head_x][head_y] = body; body++; head_x++; break;
        case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
        case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
        }
    }
    if (map[head_x][head_y] != ' '&&map[head_x][head_y] != food)//再次判断
    {
        int t = 1;
        while (map[head_x][head_y] != ' '&&map[head_x][head_y] != food)
        {
            switch (direction)//返回原值
            {
            case 'w': body--; head_x++; break;
            case 's': body--; head_x--; break;
            case 'a': body--; head_y++; break;
            case 'd': body--; head_y--; break;
            }
            if (t == 1)direction = 'w';
            else if (t == 2)direction = 'd';
            else if (t == 3)direction = 'a';
            else if (t == 4)direction = 's';
            else if (t >= 4)break;
            ++t;
            switch (direction)
            {
            case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
            case 's':snake[head_x][head_y] = body; body++; head_x++; break;
            case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
            case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
            }
        }
    }
    if (snake[head_x][head_y] != -1)//没吃到,尾消失
    {
        a = snake[tail_x][tail_y];
        snake[tail_x][tail_y] = 0;
        if (tail_x + 1 < map_row - 1 && snake[tail_x + 1][tail_y] == a+1)
            tail_x = tail_x + 1;
        else
            if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
                tail_x = tail_x - 1;
            else
                if (tail_y + 1 < map_line - 1 && snake[tail_x][tail_y + 1] == a + 1)
                    tail_y = tail_y + 1;
                else
                    if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1)
                        tail_y = tail_y - 1;
    }
    else//吃到尾不消失,产生新的食物
    {
        creatfood(snake);
    }
}

全部代码

#include
#include
#include
#include
#include
#include
#include

#define snake_length 5//蛇初始长度
#define map_row 10//地图行
#define map_line 10//地图列
#define snake_head 'H'//蛇头
#define snake_body 'X'//蛇身
#define wail '#'//墙
#define food '*'//食物

int body=1;
char direction = 'd';//蛇移动方向
int tail_x = 1, tail_y = 1;//蛇尾坐标
int head_x = 1, head_y = 5;//初始蛇头位置
int food_x = 1, food_y = 1;//食物位置

void creatmap( char map[map_row][map_line]);//创建地图
void creatsnake(int snake[map_row][map_line]);//初始化蛇的位置
void creatfood(int snake[map_row][map_line]);//随机产生食物
void printmap(char map[map_row][map_line],int snake[map_row][map_line]);//输出地图、蛇、食物
int judge(char map[map_row][map_line]);//判断蛇是否撞墙或撞自己,是返回0,否返回1
void move(int snake[map_row][map_line], char map[map_row][map_line]);//蛇的移动加捕食
void check(char *direction,char *direction1);//排除反方向

int main()
{
    char map[map_row][map_line];
    int snake[map_row][map_line] = { 0 };
    creatmap(map);
    creatsnake(snake);
    srand((unsigned)time(NULL));
    creatfood(snake);

    int a = 1;
    while (a == 1)
    {
        printmap(map,snake);
        move(snake,map);
        a = judge(map);
    }
    printf("Game over");
    return 0;
}

void creatmap( char  map[map_row][map_line])
{
    for (int i = 0; i < map_line; ++i)
    {
        map[0][i] = wail;
        map[map_row-1][i] = wail;
    }
    for (int i = 1; i < map_row-1; ++i)
    {
        map[i][0] = wail;
        map[i][map_line-1] = wail;
    }
    for (int i = 1; i < map_row-1; ++i)
    {
        for (int j = 1; j < map_line-1; ++j)
            map[i][j] = ' ';
    }
}
void creatsnake(int snake[map_row][map_line])
{
    for (int i = 1; i < snake_length; ++i)
    {
        snake[1][i] = body;
        ++body;
    }
}
void creatfood(int snake[map_row][map_line])
{
    while (snake[food_x][food_y] != 0)
    {
        food_x = rand() % 8 + 1;
        food_y = rand() % 8 + 1;
    }
    snake[food_x][food_y] = -1;
}
void printmap(char map[map_row][map_line],int snake[map_row][map_line])
{

    for (int i = 1; i < map_row-1; ++i)
    {
        for (int j = 1; j < map_line-1; ++j)
        {
            if (snake[i][j] == 0)map[i][j] = ' ';
            else map[i][j] = snake_body;
        }
    }
    map[head_x][head_y] = snake_head;
    map[food_x][food_y] = food;
    for (int i = 0; i < map_row; ++i)
    {
        for (int j = 0; j < map_line; ++j)
            printf("%c", map[i][j]);
        printf("\n");
    }
}
int judge(char map[map_row][map_line])
{
    if (map[head_x][head_y]!=' '&& map[head_x][head_y]!=food)
        return 0;
    else
        return 1;
}
void check(char *direction,char *direction1)//与前进方向相反不执行
{
    if (*direction == 'w')
        if (*direction1 == 's')
            *direction = 's';
    if (*direction == 's')
        if (*direction1 == 'w')
            *direction = 'w';
    if (*direction == 'a')
        if (*direction1 == 'd')
            *direction = 'd';
    if (*direction == 'd')
        if (*direction1 == 'a')
            *direction = 'a';
}
void move(int snake[map_row][map_line], char map[map_row][map_line])
{
    /*w 上
      s 下
      a 左
      d 右*/
    Sleep(1000);//调节速度
    int a;


        if (food_y - head_y > 0)direction = 'd';
        else if (food_y - head_y < 0)direction = 'a';
        else if (food_x - head_x > 0)direction = 's';
        else if (food_x - head_x < 0)direction = 'w';

    switch (direction)
    {

    case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
    case 's':snake[head_x][head_y] = body; body++; head_x++; break;
    case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
    case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
    }
    if (map[head_x][head_y]!=' '&&map[head_x][head_y] != food)
    {
        switch (direction)
        {

        case 'w': body--; head_x++; break;
        case 's': body--; head_x--; break;
        case 'a': body--; head_y++; break;
        case 'd': body--; head_y--; break;
        }
        if (direction == 'd') {
            if (food_x - head_x >= 0)direction = 's';
            else if (food_x - head_x < 0)direction = 'w';
        }
        else if (direction == 'a')
        {
            if (food_x - head_x >= 0)direction = 's';
            else if (food_x - head_x < 0)direction = 'w';
        }
        else if (direction == 'w')
        {
            if (food_y - head_y >= 0)direction = 'd';
            else if (food_y - head_y < 0)direction = 'a';
        }
        else
        {
            if (food_y - head_y >= 0)direction = 'd';
            else if (food_y - head_y < 0)direction = 'a';
        }
        switch (direction)
        {

        case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
        case 's':snake[head_x][head_y] = body; body++; head_x++; break;
        case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
        case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
        }
    }
    if (map[head_x][head_y] != ' '&&map[head_x][head_y] != food)
    {
        int t = 1;
        while (map[head_x][head_y] != ' '&&map[head_x][head_y] != food)
        {
            switch (direction)
            {
            case 'w': body--; head_x++; break;
            case 's': body--; head_x--; break;
            case 'a': body--; head_y++; break;
            case 'd': body--; head_y--; break;
            }
            if (t == 1)direction = 'w';
            else if (t == 2)direction = 'd';
            else if (t == 3)direction = 'a';
            else if (t == 4)direction = 's';
            else if (t >= 4)break;
            ++t;
            switch (direction)
            {
            case 'w':snake[head_x][head_y] = body; body++; head_x--; break;
            case 's':snake[head_x][head_y] = body; body++; head_x++; break;
            case 'a':snake[head_x][head_y] = body; body++; head_y--; break;
            case 'd':snake[head_x][head_y] = body; body++; head_y++; break;
            }
        }
    }
    if (snake[head_x][head_y] != -1)//没吃到,尾消失
    {
        a = snake[tail_x][tail_y];
        snake[tail_x][tail_y] = 0;
        if (tail_x + 1 < map_row - 1 && snake[tail_x + 1][tail_y] == a+1)
            tail_x = tail_x + 1;
        else
            if (tail_x - 1 > 0 && snake[tail_x - 1][tail_y] == a + 1)
                tail_x = tail_x - 1;
            else
                if (tail_y + 1 < map_line - 1 && snake[tail_x][tail_y + 1] == a + 1)
                    tail_y = tail_y + 1;
                else
                    if (tail_y - 1 > 0 && snake[tail_x][tail_y - 1] == a + 1)
                        tail_y = tail_y - 1;
    }
    else//吃到尾不消失,产生新的食物
    {
        creatfood(snake);
    }
}


你可能感兴趣的:(贪吃蛇游戏算法)