C语言实现贪食蛇游戏

//2020-6-18
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <time.h>
#include <windows.h>

const int height = 20;   //地图的高
const int length = 20;   //地图的长
char Map[height][length]; //游戏地图

int key;  //按键保存
int snakeLen = 4;   //蛇的长度,刚开始时为4
int gameOver = 0;   //自吃或碰墙时gameOver=1,游戏结束

//左、右、上、下的方向
int  dx[4] = {0, 0, -1, 1};
int  dy[4] = {-1, 1, 0, 0};

enum
{
    LeftKey = 75,
    RightKey = 77,
    UpKey = 72,
    DownKey = 80
};

struct Snake    //蛇的每个节点的数据类型
{
     int r;     //行位置
     int c;     //列位置
     int dir;   //当前节点的方向, 0,1,2,3分别为左右上下
}Snake[height * length];

const char head = '@';  //蛇头
const char body = '#';  //蛇身
const char food = '*';  //食物

//函数声明
void Initial();     //地图的初始化
void CreateFood(); //在地图上随机产生食物
void Show();        //刷新显示地图
void GetPressKey();      //取出按键,并判断方向
void Move();        //蛇的移动
void CheckBorder();  //检查蛇头是否越界
void CheckHead(int r, int c);  //检查蛇头移动后的位置情况

int main()
{
    Initial();

    Show();

    return 0;
}

void Initial()  //地图的初始化
{
    int i, j;
    int hx, hy;
    system("title 贪吃蛇");  //控制台的标题
    memset(Map, '.', sizeof(Map));  //初始化地图全部为空'.'
    //system("cls");
    srand(time(0));     //随机种子
    hx = rand() % height; //产生蛇头
    hy = rand() % length;
    Map[hx][hy] = head;
    Snake[0].r = hx;  Snake[0].c = hy;
    Snake[0].dir = -1;

    CreateFood();       //随机产生食物

    for(i = 0; i < height; i++)   //地图显示
    {
        for(j = 0; j < length; j++)
        {
            printf("%c", Map[i][j]);
        }
        printf("\n");
    }

    printf("\nC语言贪吃蛇\n");
    printf("按任意方向键开始游戏\n");

    getch();   //先接受一个按键,使蛇开始往该方向走

    GetPressKey();  //取出按键,并判断方向
}

void CreateFood()  //在地图上随机产生食物
{
    int fx, fy;
    while(1)
    {
        fx = rand() % height;
        fy = rand() % length;
        if(Map[fx][fy] == '.')  //不能出现在蛇所占有的位置
        {
            Map[fx][fy] = food;
            break;
        }
    }
}

void Show()  //刷新显示地图
{
    int i, j;
    while(1)
    {
        Sleep(500); //延迟半秒(1000为1s),即每半秒刷新一次地图

        GetPressKey();   //先判断按键在移动

        Move();

        if(gameOver)  //自吃或碰墙即游戏结束
        {
            printf("\n**游戏结束**\n");
            printf("    >_<\n");
            getchar();
            break;
        }

        system("cls");   //清空地图再显示刷新吼的地图

        for(i = 0; i < height; i++)
        {
            for(j = 0; j < length; j++)
            {
                printf("%c", Map[i][j]);
            }
            printf("\n");
        }

        printf("\nC语言贪吃蛇\n");
        printf("按任意方向键开始游戏\n");
    }
}

void GetPressKey()  //取出按键,并判断方向
{
    if(kbhit() != 0) //检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
    {
        while(kbhit() != 0)  //可能存在多个按键,要全部取完,以最后一个为主
        {
            key = getch(); //将按键从控制台中取出并保存到key中
        }

        switch(key)
        {   //左
            case LeftKey:
            {
                Snake[0].dir = 0;
                break;
            }
            //右
            case RightKey:
            {
                Snake[0].dir = 1;
                break;
            }
            //上
            case UpKey:
            {
                Snake[0].dir = 2;
                break;
            }
            //下
            case DownKey:
            {
                Snake[0].dir = 3;
                break;
            }
        }
    }
}

void Move()   //蛇的移动
{
    int i, r, c;
    int len = snakeLen;  //保存当前蛇的长度
    //记录当前蛇头的位置,并设置为空,蛇头先移动

    r = Snake[0].r;
    c = Snake[0].c;
    Map[r][c] = '.';

    Snake[0].r = Snake[0].r + dx[ Snake[0].dir ];
    Snake[0].c = Snake[0].c + dy[ Snake[0].dir ];

    CheckBorder();   //蛇头是否越界

    CheckHead(r, c);  //蛇头移动后的位置情况,参数为: 蛇头的开始位置

    if(snakeLen == len)  //未吃到食物即蛇身移动哦
    {
        for(i = 1; i < snakeLen; i++)  //要从蛇尾节点向前移动哦,前一个节点作为参照
        {
            if(i == 1)   //尾节点设置为空再移动
            {
                Map[ Snake[i].r ][ Snake[i].c ] = '.';
            }

            if(i == snakeLen-1)  //为蛇头后面的蛇身节点,特殊处理
            {
                Snake[i].r = r;
                Snake[i].c = c;
                Snake[i].dir = Snake[0].dir;
            }
            else   //其他蛇身即走到前一个蛇身位置
            {
                Snake[i].r = Snake[i+1].r;
                Snake[i].c = Snake[i+1].c;
                Snake[i].dir = Snake[i+1].dir;
            }
            Map[ Snake[i].r ][ Snake[i].c ] = '#'; //移动后要置为'#'蛇身
        }
    }
}

void CheckBorder()  //检查蛇头是否越界
{
    if(Snake[0].r < 0 || Snake[0].r >= height || Snake[0].c < 0 || Snake[0].c >= length)
    {
        gameOver = 1;
    }
}

void CheckHead(int r, int c)  //检查蛇头移动后的位置情况
{
    if(Map[ Snake[0].r ][ Snake[0].c ] == '.')  //为空
    {
        Map[ Snake[0].r ][ Snake[0].c ] = '@';
    }
    else
    {
        if(Map[ Snake[0].r ][ Snake[0].c ] == '*')  //为食物
        {
            Map[ Snake[0].r ][ Snake[0].c ] = '@';
            Snake[snakeLen].r = r;   //新增加的蛇身为蛇头后面的那个
            Snake[snakeLen].c = c;
            Snake[snakeLen].dir = Snake[0].dir;
            Map[ Snake[snakeLen].r ][ Snake[snakeLen].c ] = '#';
            snakeLen++;
            CreateFood();  //食物吃完了马上再产生一个食物
        }
        else
        {
            gameOver = 1;
        }
    }
}
了解中小学信息学竞赛请加微信307591841(QQ同号)



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值