欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言300行代码实现贪吃蛇

程序员文章站 2024-03-18 19:54:28
...

完整代码:

 

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

#define ARRAY_SIZE 20                        // 区域大小
int AreaArray[ARRAY_SIZE][ARRAY_SIZE];        // 数组

#define        WALL            0                // 墙壁
#define        VALID            1                // 可走区域
#define        SELF            2                // 蛇身
#define        NEWP            3                // 果实
#define        HEAD            4                // 蛇头

const char *Shape[] = {
    "■",        // 墙壁图案
    "  ",        // 可走区域图案ww
    "◎",        // 蛇身图案
    "⊙"    ,        // 果实图案
    "●"            // 蛇头图案
};
// 记录分数
int score = 0;
int high_score = 0;
// 蛇的所有坐标
int xy[(ARRAY_SIZE - 2)*(ARRAY_SIZE - 2) + 1][2] = {0};
// 方向状态
enum {
    LEFT,
    TOP,
    RIGHT,
    BOTTOM
} Direction;

// 保存最高记录
void GameSaveHighScore()
{
    FILE *fp = fopen("high_score.txt", "w");
    if (fp == NULL)
    {
        printf("open file error.\n");
        return;
    }
    fprintf(fp, "%d", high_score);
    fclose(fp);
}

// 载入最高记录
void GameLoadHighScore()
{
    FILE *fp = fopen("high_score.txt", "r");
    if (fp == NULL)
    {
        printf("open file error.\n");
        return;
    }
    fscanf(fp, "%d", &high_score);
    fclose(fp);
}

// 生成特定区域内随机数
int GetRand(int start, int end)
{
    static unsigned long count;
    srand((unsigned int)time(0)+ count--);
    return rand() % (end - start + 1) + start;
}

// 刷新果实坐标
void GameUpdateNewp()
{
    static int x, y;
    int i, j, z;
    // 计算蛇长度
    for (i = 0; xy[i][0] || xy[i][1]; i++);
    // 添加上新吃的果实
    i++;
    // 生成随机数
    i = GetRand(0, (ARRAY_SIZE - 2)*(ARRAY_SIZE - 2) - i - 1);
    // 计算新果实坐标
    for (j = 1;i && j < ARRAY_SIZE - 1; j++)
    {
        for (z = 1;i && z < ARRAY_SIZE - 1; z++)
        {
            if (AreaArray[j][z] == VALID)
                i--;
            if (!i) break;
        }
        if (!i) break;
    }
    // 加入新果实
    AreaArray[j][z] = NEWP;
    // 去掉之前的果实
    if (x || y)
        AreaArray[y][x] = VALID;
    //
    x = z;
    y = j;
}

// 根据用户操作更新游戏, 返回新状态
int GameUpdate()
{
    int x = 0, y = 0, i;
    // 根据方向检测碰撞
    switch (Direction)
    {
        case LEFT:
            x--;
            break;
        case TOP:
            y--;
            break;
        case RIGHT:
            x++;
            break;
        case BOTTOM:
            y++;
            break;
    }
    // 计算蛇长度
    for (i = 0; xy[i][0] || xy[i][1]; i++);
    // 判断下一个位置是否与蛇头碰撞
    switch (AreaArray[xy[0][1] + y][xy[0][0] + x])
    {
        case SELF:
        case WALL:
            return 0;        // 撞自己或者撞墙了
        case NEWP:
            score++;
            i++;            // 吃到果实, 长度加1
            xy[i][0] = 0;    // 加结束标志
            xy[i][1] = 0;    // 加结束标志
            GameUpdateNewp();// 刷新果实坐标
        case VALID:
            i--;
            // 移动蛇
            while (i>0)
            {
                xy[i][0] = xy[i-1][0];
                xy[i][1] = xy[i-1][1];
                i--;
            }
            // 蛇头坐标
            xy[0][0] += x;
            xy[0][1] += y;
            break;
    }
    return 1;
}

// 刷新显示
void GameFresh()
{
    int i, j;
    // 去掉显示数组上蛇身旧状态的痕迹
    for (i = 1; i < ARRAY_SIZE - 1; i++)
        for (j = 1; j < ARRAY_SIZE - 1; j++)
            if(AreaArray[i][j]== SELF || AreaArray[i][j] == HEAD)
                AreaArray[i][j] = VALID;
    // 把蛇的坐标更新到显示数组
        // 蛇头
    AreaArray[xy[0][1]][xy[0][0]] = HEAD;
        // 蛇身
    for (i = 1; xy[i][0] || xy[i][1]; i++)
        AreaArray[xy[i][1]][xy[i][0]] = SELF;
    // 清屏
    system("cls");
    // 显示
    for (i = 0; i < ARRAY_SIZE; i++)
    {
        for (j = 0; j < ARRAY_SIZE; j++)
                printf("%s", Shape[AreaArray[i][j]]);
        printf("\n");
    }
    printf("current score: %d\n", score);
    printf("high score: %d\n", high_score);
}

// 游戏初始化
void GameInit()
{
    int i, j;
    // 初始化显示数组整个区域
    for (i = 0; i < ARRAY_SIZE; i++)
        for (j = 0; j < ARRAY_SIZE; j++)
            if (i && j && (i != ARRAY_SIZE - 1) && (j != ARRAY_SIZE - 1))
                AreaArray[i][j] = VALID;    // 可行走区域
            else
                AreaArray[i][j] = WALL;        // 墙壁
                                            // 随机生成蛇头坐标
    xy[0][0] = GetRand(2, ARRAY_SIZE - 3);
    xy[0][1] = GetRand(2, ARRAY_SIZE - 3);
    // 根据蛇头坐标生成蛇身坐标
    if (GetRand(0, 1))
    {
        if (xy[0][0] > ARRAY_SIZE / 2)
        {
            i = xy[0][0] + 1;
            Direction = LEFT;
        }
        else
        {
            i = xy[0][0] - 1;
            Direction = RIGHT;
        }
        j = xy[0][1];
    }
    else
    {
        i = xy[0][0];
        if (xy[0][1] > ARRAY_SIZE / 2)
        {
            j = xy[0][1] + 1;
            Direction = TOP;
        }
        else
        {
            j = xy[0][1] - 1;
            Direction = BOTTOM;
        }
    }
    xy[1][0] = i;
    xy[1][1] = j;
    // 蛇身结束标志
    xy[2][0] = 0;
    xy[2][1] = 0;
    // 更新
    GameUpdate();
    GameUpdateNewp();
    GameFresh();
}

void GameStart()
{
    int state = 1;
    int time = 100;
    system("cls");
    printf("================= Game rule ==============\n");
    printf("\tContinue key : \tany\n");
    printf("\tQuit key : \tQ\n");
    printf("\tUp key : \tW\n");
    printf("\tDown key : \tS\n");
    printf("\tLeft key : \tA\n");
    printf("\tRight key : \tD\n");
    printf("==========================================\n");
    score = 0;
    GameLoadHighScore();
    getch();
    GameInit();
    while (state)
    {
        // 检测有输入
        if(kbhit())
            switch (getch())
            {
                case 'q':
                case 'Q':
                    state = 0;        // 结束游戏
                    break;
                case 'w':
                case 'W':
                    if(Direction != BOTTOM)
                        Direction = TOP;
                    break;
                case 's':
                case 'S':
                    if (Direction != TOP)
                        Direction = BOTTOM;
                    break;
                case 'a':
                case 'A':
                    if (Direction != RIGHT)
                        Direction = LEFT;
                    break;
                case 'd':
                case 'D':
                    if (Direction != LEFT)
                        Direction = RIGHT;
                    break;
                default:;
            }
        state = GameUpdate();        // 更新
        GameFresh();                // 刷新显示
        Sleep(time);
    }
    printf("######### Game over #########\n");
    // 最高记录
    if (score > high_score) high_score = score;
    GameSaveHighScore();
    getch();
}

int main()
{
    while(1) GameStart();
    return 0;
}

 

运行截图:

C语言300行代码实现贪吃蛇

相关标签: 代码 游戏