C语言简单贪吃蛇源码(分数,暂停)

上代码

运行环境 vscode g++,dev codeblock等可以运行。
没有用到数据结构和控制光标的函数。

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

#define N (20)
#define M (20)
#define L (N * M)
#define True 1
#define False 0

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3

typedef struct mark
{
    int x;
    int y;
} bodySnake;

char scoreFile[] = "score.txt";

void drawMap(bodySnake snake[], char map[][M], const int headIndex,
             const int endIndex, const int food_x, const int food_y, int score, const int *maxScore);
void initSnake();
void snakeMove(bodySnake snake[], char map[][M], int *headIndex, int *endIndex, int direction[], int *food_x, int *food_y, int *score, int *maxScore, int *pause);

void move(bodySnake snake[], int *headIndex, int direction[], const int snakeHead);
void artificialMove(bodySnake snake[], int *headIndex,
                    int *endIndex, int direction[], char click, int snakeHead, int *pause);
int snakeEatFood(bodySnake snake[], const int headIndex,
                 const int food_x, const int food_y, int *score, int *maxScore);
void markMap(bodySnake snake[], char map[][M], const int headIndex,
             const int endIndex, const int food_x, const int food_y);
void foodConflictSnake(bodySnake snake[], int *food_x, int *food_y,
                       const int headIndex, const int endIndex);
void gameOver(int score);
void snakeDead(bodySnake snake[], int headIndex, int endIndex, int *active);
int viewScore(const char scoreFile[]);
void updateScore(int score, int *maxScore);
int readMaxScore(const char scoreFile[]);
void help();
void returnMenu();
void menu();
void initFile(const char scoreFile[]);

int main()
{
    menu();
    return 0;
}

void initSnake()
{

    //地图
    char map[N][M] = {0};
    //初始蛇的身体
    bodySnake snake[L]; //装蛇的数组
    snake[0].x = 3, snake[0].y = 3;
    snake[1].x = 3, snake[1].y = 4;
    snake[2].x = 3, snake[2].y = 5;

    map[3][3] = 1, map[3][4] = 1, map[3][5] = 1;

    int endIndex = 0;  //蛇尾
    int headIndex = 2; //蛇头

    //随机食物
    srand((unsigned)time(NULL));
    int food_x = rand() % N;
    int food_y = rand() % M;

    int direction[4] = {0, 0, 0, 1};
    int maxScore = readMaxScore(scoreFile);
    int score = 0;
    int active = True;
    int pause = False;
    while (active)
    {
        drawMap(snake, map, headIndex, endIndex, food_x, food_y, score, &maxScore);
        snakeMove(snake, map, &headIndex, &endIndex,
                  direction, &food_x, &food_y, &score, &maxScore, &pause);
        snakeDead(snake, headIndex, endIndex, &active);
    }
    gameOver(score);
}

void menu()
{
    system("cls");
    initFile(scoreFile);
    printf("*****************************************\n");
    printf("*                                       *\n");
    printf("*                1.开始游戏.            *\n");
    printf("*                2.查看帮助.            *\n");
    printf("*                3.查看历史最高分.      *\n");
    printf("*                                       *\n");
    printf("*****************************************\n");
    int choose;
    scanf("%1d", &choose);
    while (getchar() != '\n')
    {
        continue;
    }

    if (choose == 1)
    {
        initSnake();
    }
    else if (choose == 2)
    {
        help();
        returnMenu();
    }
    else if (choose == 3)
    {
        viewScore(scoreFile);
        returnMenu();
    }
    else
    {
        menu();
    }
}

void help()
{
    system("cls");
    printf("w s a d对应上下左右,空格键暂停,q直接退出(不保存分数)\n");
    printf("祝你好运!\n");
}

void returnMenu()
{
    int choose;
    printf("\n\n1.返回菜单\t\t\t2.退出\n");
    scanf("%1d", &choose);
    while (getchar() != '\n')
    {
        continue;
    }
    menu();
}

void initFile(const char scoreFile[])
{
    FILE *fp;
    if ((fp = fopen(scoreFile, "r")) == NULL)
    {
        int score = 0;
        fp = fopen(scoreFile, "w");
        fprintf(fp, "%d\n", score);
    }
    fclose(fp);
}

int viewScore(const char scoreFile[])
{
    system("cls");
    int score;
    FILE *fp;
    if ((fp = fopen(scoreFile, "r")) != NULL)
    {
        fscanf(fp, "%d", &score);
        printf("你的历史最高分为%d.", score);
    }
    fclose(fp);
    return score;
}

int readMaxScore(const char scoreFile[])
{
    int score = 0;
    FILE *fp;
    if ((fp = fopen(scoreFile, "r")) != NULL)
    {
        fscanf(fp, "%d", &score);
    }
    else
    {
        printf("打开失败!");
    }
    fclose(fp);
    return score;
}

void markMap(bodySnake snake[], char map[][M], const int headIndex,
             const int endIndex, const int food_x, const int food_y)
{
    if (headIndex > endIndex)
    {
        for (int i = endIndex; i <= headIndex; i++)
        {
            map[snake[i].x][snake[i].y] = 1;
        }
    }
    else
    {
        for (int i = endIndex; i < L; i++)
        {
            map[snake[i].x][snake[i].y] = 1;
        }
        for (int i = 0; i <= headIndex; i++)
        {
            map[snake[i].x][snake[i].y] = 1;
        }
    }
    map[food_x][food_y] = 2;
}

void drawMap(bodySnake snake[], char map[][M], const int headIndex,
             const int endIndex, const int food_x, const int food_y, int score, const int *maxScore)
{
    markMap(snake, map, headIndex, endIndex, food_x, food_y);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (map[i][j] == 0)
            {
                printf("--");
            }
            else if (map[i][j] == 1)
            {
                printf("★");
            }
            else if (map[i][j] == 2)
            {
                printf("●");
            }
        }
        putchar(10);
    }
    printf("你的当前分数:%d.\t\t\t历史最高分为:%d\n", score, *maxScore);
    Sleep(40);
    system("cls");
}

void snakeMove(bodySnake snake[], char map[][M], int *headIndex, int *endIndex, int direction[], int *food_x, int *food_y, int *score, int *maxScore, int *pause)
{

    int snakeHead = (*headIndex + 1) % L;
    if (kbhit())
    {
        char click = getch();
        artificialMove(snake, headIndex, endIndex, direction, click, snakeHead, pause);
    }
    else if (!*pause)
    {
        move(snake, headIndex, direction, snakeHead);
    }
    //是否吃了食物
    int eat = snakeEatFood(snake, *headIndex, *food_x, *food_y, score, maxScore);
    if (eat)
    {
        *food_x = rand() % N;
        *food_y = rand() % M;
        foodConflictSnake(snake, food_x, food_y, *headIndex, *endIndex);
    }
    //没吃到食物且没暂停,才去掉尾巴。即暂停或吃到食物才不去掉尾巴
    else if (!eat && !*pause)
    {
        int x = snake[*endIndex].x;
        int y = snake[*endIndex].y;
        //去掉尾巴
        map[x][y] = 0;
        //尾巴前行
        *endIndex = (*endIndex + 1) % L;
    }
}

void move(bodySnake snake[], int *headIndex, int direction[], const int snakeHead)
{
    snake[snakeHead].x = (snake[*headIndex].x + direction[UP] + direction[DOWN] + N) % N;
    snake[snakeHead].y = (snake[*headIndex].y + direction[LEFT] + direction[RIGHT] + M) % M;
    *headIndex = snakeHead;
}

void artificialMove(bodySnake snake[], int *headIndex,
                    int *endIndex, int direction[], char click, int snakeHead, int *pause)
{
    if ((click == 'w' || click == 'W') && direction[DOWN] != 1)
    {
        direction[UP] = -1, direction[DOWN] = 0, direction[LEFT] = 0, direction[RIGHT] = 0;
    }
    else if ((click == 's' || click == 'S') && direction[UP] != -1)
    {
        direction[UP] = 0, direction[DOWN] = 1, direction[LEFT] = 0, direction[RIGHT] = 0;
    }
    else if ((click == 'a' || click == 'A') && direction[RIGHT] != 1)
    {
        direction[UP] = 0, direction[DOWN] = 0, direction[LEFT] = -1, direction[RIGHT] = 0;
    }
    else if ((click == 'd' || click == 'D') && direction[LEFT] != -1)
    {
        direction[UP] = 0, direction[DOWN] = 0, direction[LEFT] = 0, direction[RIGHT] = 1;
    }
    else if (click == ' ')
    {
        if (*pause == False)
        {
            *pause = True;
        }
        else
        {
            *pause = False;
        }
    }
    else if (click == 'q')
    {
        exit(0);
    }
    if (!*pause)
    {
        move(snake, headIndex, direction, snakeHead);
    }
}

int snakeEatFood(bodySnake snake[], const int headIndex,
                 const int food_x, const int food_y, int *score, int *maxScore)
{
    if (snake[headIndex].x == food_x && snake[headIndex].y == food_y)
    {
        *score += 10;
        updateScore(*score, maxScore);
        return True;
    }
    return False;
}

void updateScore(int score, int *maxScore)
{

    if (score > *maxScore)
    {
        *maxScore = score;
    }
}

void foodConflictSnake(bodySnake snake[], int *food_x, int *food_y,
                       const int headIndex, const int endIndex)
{
    int conflict = False;
    do
    {
        conflict = False;
        if (headIndex > endIndex)
        {
            for (int i = endIndex; i <= headIndex; i++)
            {
                if (*food_x == snake[i].x && *food_y == snake[i].y)
                {
                    conflict = True;
                    break;
                }
            }
        }
        else
        {
            for (int i = endIndex; i < L; i++)
            {
                if (*food_x == snake[i].x && *food_y == snake[i].y)
                {
                    conflict = True;
                    break;
                }
            }
            for (int i = 0; i <= headIndex; i++)
            {
                if (*food_x == snake[i].x && *food_y == snake[i].y)
                {
                    conflict = True;
                    break;
                }
            }
        }
        if (conflict)
        {
            *food_x = rand() % N;
            *food_y = rand() % M;
        }
    } while (conflict);
}

void snakeDead(bodySnake snake[], int headIndex, int endIndex, int *active)
{
    if (headIndex > endIndex)
    {
        for (int i = endIndex; i < headIndex; i++)
        {
            if (snake[i].x == snake[headIndex].x &&
                snake[i].y == snake[headIndex].y)
            {
                *active = False;
                break;
            }
        }
    }
    else
    {
        for (int i = endIndex; i < L; i++)
        {
            if (snake[i].x == snake[headIndex].x &&
                snake[i].y == snake[headIndex].y)
            {
                *active = False;
                break;
            }
        }
        for (int i = 0; i < headIndex; i++)
        {
            if (snake[i].x == snake[headIndex].x &&
                snake[i].y == snake[headIndex].y)
            {
                *active = False;
                break;
            }
        }
    }
}

void gameOver(int score)
{
    int historyScore = readMaxScore(scoreFile);
    if (score > historyScore)
    {
        FILE *fp;
        fp = fopen(scoreFile, "w");
        fprintf(fp, "%d\n", score);
        fclose(fp);
        printf("\t\t\t恭喜你打破了历史记录!\t\t\t\n");
    }
    printf("\t\t\tGame Over!\t\t\t\n");
}
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在C语言编写的贪吃蛇游戏中,当贪吃蛇吃到一定分数的食物时,游戏会出现如下的加速效果。 贪吃蛇是一种经典的游戏,玩家需要控制蛇的移动方向,使其吃到食物并不断变长。一开始,贪吃蛇的移动速度较慢,但随着贪吃蛇吃到越来越多的食物,分数也会逐渐增加。当分数达到一定阈值时,游戏会出现加速效果,使得贪吃蛇的移动速度变快。 实现这个功能,首先需要获得游戏中的贪吃蛇得分。在C语言中,可以使用一个整数变量来代表分数。每当贪吃蛇吃到食物时,分数加一,并将新的分数显示在游戏界面上。 接下来,需要设置一个阈值来判断何时触发加速效果。当分数达到设定的阈值时,加速效果就会被触发。可以使用一个if语句来比较当前分数和阈值的大小,如果大于等于阈值,则加速。 在C语言中,加速效果可以通过两种方式实现。一种是改变贪吃蛇的移动速度,可以通过调整移动的时间间隔来实现加速。另一种是改变贪吃蛇的移动步长,可以通过增加每次移动的格子数来实现加速。 在游戏的循环中,需要不断检测当前分数是否达到了阈值,如果达到了,则将移动速度或步长进行调整,以实现加速效果。可以使用条件语句或循环控制语句来实现这个逻辑。 总之,通过适当设置阈值,并在达到一定分数时实现贪吃蛇的加速效果,可以增加游戏的难度和挑战性,让游戏更加有趣。 ### 回答2: 在C语言编写贪吃蛇游戏时,可以通过设置一定的分数目标来触发食物加速的功能。当贪吃蛇吃到的食物数量达到一定的分数时,游戏可以加速。 在游戏开始时,可以设定一个初始的游戏速度。当贪吃蛇吃到食物时,可以通过判断当前得分是否达到设定的分数目标来确定是否进行加速操作。当得分达到目标时,可以通过减小时间延迟来加快游戏的速度。这样,在每次移动时,贪吃蛇的移动就会更加迅速。 在程序编码上,可以使用一个变量来记录当前的得分,并与设定的分数目标进行比较。当得分超过或等于设定的目标分数时,通过相应的代码来修改时间延迟的数值,从而实现加速的效果。 比如,可以使用一个if语句判断当前得分和目标分数的关系,当达到目标分数时,修改一个控制时间延迟的变量的数值,从而实现加速,具体代码如下: ``` int score = 0; // 记录得分 int targetScore = 100; // 分数目标 int delay = 100; // 初始时间延迟 // 游戏循环 while (1) { // 贪吃蛇移动逻辑 // ... // 判断是否达到分数目标 if (score >= targetScore) { // 达到目标分数,加速 delay -= 10; targetScore += 100; // 更新目标分数,为下一次加速做准备 } // 控制移动的速度 sleep(delay); } ``` 在以上代码中,通过不断地比较得分和目标分数的大小关系,可以在达到目标分数时不断地减小时间延迟的值,从而实现游戏的加速效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值