设为首页收藏本站
查看: 1864|回复: 10

C语言游戏代码第二期——贪吃蛇

[复制链接]
  • TA的每日心情

    2019-5-22 22:04
  • 签到天数: 59 天

    [LV.5]常住居民I

    发表于 2018-11-23 15:29:00 | 显示全部楼层 |阅读模式
    文章转载于:
    https://blog.csdn.net/SGAFPZys/article/details/51180061


    /*蛇越长跑得越快*/
    /*作者:SGAFPZ*/
    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include <math.h>
    //#include <unistd.h>
    #include <conio.h>
    #include <string.h>
    #include <time.h>
    void food();
    void show();
    void move();
    void turn();
    void check();
    void ini();
    //void calculate();
    //int movable[4] = { 0, 1, 1, 0 };  //数组的下标表示方向,0123分别表示上下左右,下同
    //int distance[4] = { 9999, 9999, 9999, 9999 };
    int  dy[4] = { 0, 1, 0, -1 };
    int  dx[4] = { -1, 0, 1, 0 };
    int sum = 5;  //蛇总长度
    int over = 0;
    int speed;   
    //int foodx, foody;  //食物的坐标
    char map[17][17];

    struct snake {
        int x, y;  //身体坐标
        int dir;  //方向(只有蛇头的方向是有用的)
    } A[100];

    void ini() {  //初始化界面
        speed = 500;
        over = 0;
        sum = 5;
        //movable[0] = 0; movable[1] = 1; movable[2] = 1; movable[3] = 0;
        //distance[0] = 9999; distance[1] = 9999; distance[2] = 9999; distance[3] = 9999;
        int i, j;
        for (i = 0; i < 100; i++) {  //初始化蛇头和蛇身的数据
            A[i].dir = 0;
            A[i].x = 0;
            A[i].y = 0;
        }
        A[0].x = 1; A[0].y = 1;  //地图左上角设置一条长度为5的蛇
        A[1].x = 1; A[1].y = 2;
        A[2].x = 1; A[2].y = 3;
        A[3].x = 1; A[3].y = 4;
        A[4].x = 1; A[4].y = 5; A[4].dir = 1;
        srand(time(0));
        for (i = 0; i < 17; i++) {  //设置地图
            for (j = 0; j < 17; j++) {
                map[i][j] = '*';
            }
        }
        for (i = 1; i < 16; i++) {
            for (j = 1; j < 16; j++) {
                map[i][j] = ' ';
            }
        }
        //map[6][5] = '*'; map[6][6] = '*'; map[6][7] = '*';
        //map[7][5] = '*'; map[7][7] = '*';
        map[A[4].x][A[4].y] = 'H';  //设置蛇头
        for (i = 0; i < sum - 1; i++) {  //设置蛇身
            map[A[i].x][A[i].y] = 'X';
        }
        food();
        //calculate();
    }


    void show() {  //显示界面
        int i, j, x, y;
        for (i = 0; i < 17; i++) {  //显示界面
            for (j = 0; j < 17; j++) {
                printf("%c", map[i][j]);
            }
            printf("\n");
        }
        while (1) {
            Sleep(speed);  //界面刷新速度
            turn();
            move();
            if (over) {  //设置蛇死掉后可以进行的操作
                while (1) {
                    char ch = _getch();
                    if (ch == 113) {  //输入‘q’结束
                        return;
                    }
                    else if (ch == 114) {  //输入‘r’重新开始
                        ini();
                        break;
                    }
                }
            }
            system("cls");  //清屏
            for (i = 0; i < 17; i++) {  //重新显示界面
                for (j = 0; j < 17; j++) {
                    printf("%c", map[i][j]);
                }
                printf("\n");
            }
            //calculate(); //计算并记录蛇头与食物距离
        }
    }

    void food() {  //生成食物
        int x, y;
        while (1) {
            x = (int)(15 * rand() / (RAND_MAX + 1.0));  //随机产生一组食物坐标
            y = (int)(15 * rand() / (RAND_MAX + 1.0));
            if (map[x][y] == ' ') {  //如果是空格则在该处生成食物
                map[x][y] = 'O';
                //foodx = x;  //记录食物坐标
                //foody = y;
                break;
            }
        }
    }


    void move() {  //蛇移动
        int i, x, y;
        int t = sum;  //t记录当前蛇总长度
        check();  //移动前检查按当前方向移动一步后的情况
        if (t == sum) {  //没有吃到苹果
            for (i = 0; i < sum - 1; i++) {
                if (i == 0) {  //蛇尾坐标处变成空格,把蛇尾坐标变成前一个蛇身的坐标
                    map[A[i].x][A[i].y] = ' ';
                    A[i].x = A[i + 1].x;
                    A[i].y = A[i + 1].y;
                }
                else {  //每个蛇身坐标都变为它前一个蛇身的坐标
                    A[i].x = A[i + 1].x;
                    A[i].y = A[i + 1].y;
                }
                map[A[i].x][A[i].y] = 'X';  //把地图上蛇身坐标处的字符设置成‘X’
            }
            A[sum - 1].x = A[sum - 1].x + dx[A[sum - 1].dir];  //蛇头按当前方向移动一格
            A[sum - 1].y = A[sum - 1].y + dy[A[sum - 1].dir];
            map[A[sum - 1].x][A[sum - 1].y] = 'H';  //把地图上蛇头坐标处的字符设置成‘H’
        }
        else {  //吃到苹果(sum会加1)
            map[A[sum - 2].x][A[sum - 2].y] = 'X';  //把地图上原蛇头坐标处的字符设置成‘X’
            A[sum - 1].x = A[sum - 2].x + dx[A[sum - 2].dir];  //新蛇头的坐标是原蛇头沿当前方向移动一格后的坐标
            A[sum - 1].y = A[sum - 2].y + dy[A[sum - 2].dir];
            A[sum - 1].dir = A[sum - 2].dir;  //新蛇头方向为原蛇头的方向
            map[A[sum - 1].x][A[sum - 1].y] = 'H';  //把地图上蛇头坐标处的字符设置成‘H’
            food();
        }
        /*for(i = 0; i < 4; i++) {  //记录下能走的方向
            x = A[sum - 1].x + dx[i];
            y = A[sum - 1].y + dy[i];
            if(map[x][y] == ' ' || map[x][y] == 'O') {
                movable[i] = 1;  //能走就把对应方向的值设置为1
            } else {
                if(x != A[0].x || y != A[0].y) {
                    movable[i] = 0;  //不能走就把对应方向的值设置为0
                } else {
                    movable[i] = 1;
                }
            }
        }*/
    }

    void check() {  //检查是否死亡或者吃到食物
        int x, y, i, j;
        x = A[sum - 1].x + dx[A[sum - 1].dir];  //记录按当前方向移动一格后蛇头的坐标
        y = A[sum - 1].y + dy[A[sum - 1].dir];
        if (map[x][y] == '*' || map[x][y] == 'X') {  //如果地图上该坐标处字符为‘*’或‘X’就死亡
            if (x != A[0].x || y != A[0].y) {  //蛇尾除外
                map[8][4] = 'G'; map[8][5] = 'A'; map[8][6] = 'M'; map[8][7] = 'E';  //输出“GAME OVER”
                map[8][9] = 'O'; map[8][10] = 'V'; map[8][11] = 'E'; map[8][12] = 'R';
                map[8][8] = ' ';
                system("cls");
                for (i = 0; i < 17; i++) {
                    for (j = 0; j < 17; j++) {
                        printf("%c", map[i][j]);
                    }
                    printf("\n");
                }
                printf("Input 'r' to restart\nInput 'q' to quit\n");
                over = 1;
            }
        }
        else if (map[x][y] == 'O') {  //吃到苹果
            sum++;  //蛇身总长加1
            speed = ((600 - sum * 20)>100) ? (600 - sum * 20) : 100; //速度加快
        }
    }

    void turn() {  //转弯
        if (_kbhit()) {
            char dir = _getch();  //读取输入的键
            switch (dir) {  //改变方向
            case 119: A[sum - 1].dir = (A[sum - 1].dir == 2)?2:0; break;
            case 100: A[sum - 1].dir = (A[sum - 1].dir == 3)?3:1; break;
            case 115: A[sum - 1].dir = (A[sum - 1].dir == 0)?0:2; break;
            case 97: A[sum - 1].dir = (A[sum - 1].dir == 1)?1:3; break;
            }
        }
    }

    /*void calculate() {  //计算并记录蛇头与食物距离
        int i = 0, x, y;
        for(i = 0; i < 4; i++) {
            if(movable[i] == 1) {  //如果该方向能走,则记录下沿该方向走一步后与食物的距离
                x = A[sum - 1].x + dx[i];
                y = A[sum - 1].y + dy[i];
                distance[i] = abs(foodx-x)+abs(foody-y);
            } else {  //如果不能走则把距离设置为9999
                distance[i] = 9999;
            }
        }
    }*/

    int main() {
        printf("'w''s''a''d'控制上下左右\n蛇越长跑得越快~~~\n");
        printf("按任意键开始\n");
        char ch = _getch();
        system("cls");
        ini();
        show();
        return 0;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
  • TA的每日心情

    2019-5-22 22:04
  • 签到天数: 59 天

    [LV.5]常住居民I

     楼主| 发表于 2018-11-23 15:30:50 | 显示全部楼层
    下面的代码接正文:

    2.智能贪吃蛇
    虽然说是智能但是可能并没有你想象中那么智能==。
    基本思路是按照上、右、下、左的顺序搜索方向,使得沿该方向前进能够靠近食物,前进过程中遇到障碍会自动绕开,可是不能避免蛇头被蛇身包围的情况。

    /*蛇越长跑得越快*/
    /*蛇能自己找食物*/
    /*作者:SGAFPZ*/
    #include <stdio.h>
    #include <windows.h>
    #include <stdlib.h>
    #include <math.h>
    //#include <unistd.h>
    #include <conio.h>
    #include <string.h>
    #include <time.h>
    void food();
    void show();
    void move();
    void turn();
    void check();
    void ini();
    void calculate();
    int movable[4] = { 0, 1, 1, 0 };  //数组的下标表示方向,0123分别表示上下左右,下同
    int distance[4] = { 9999, 9999, 9999, 9999 };
    int  dy[4] = { 0, 1, 0, -1 };
    int  dx[4] = { -1, 0, 1, 0 };
    int sum = 5;  //蛇总长度
    int over = 0;
    int speed;   
    int foodx, foody;  //食物的坐标
    char map[17][17];

    struct snake {
        int x, y;  //身体坐标
        int dir;  //方向(只有蛇头的方向是有用的)
    } A[100];

    void ini() {  //初始化界面
        speed = 500;
        over = 0;
        sum = 5;
        movable[0] = 0; movable[1] = 1; movable[2] = 1; movable[3] = 0;
        distance[0] = 9999; distance[1] = 9999; distance[2] = 9999; distance[3] = 9999;
        int i, j;
        for (i = 0; i < 100; i++) {  //初始化蛇头和蛇身的数据
            A[i].dir = 0;
            A[i].x = 0;
            A[i].y = 0;
        }
        A[0].x = 1; A[0].y = 1;  //地图左上角设置一条长度为5的蛇
        A[1].x = 1; A[1].y = 2;
        A[2].x = 1; A[2].y = 3;
        A[3].x = 1; A[3].y = 4;
        A[4].x = 1; A[4].y = 5; A[4].dir = 1;
        srand(time(0));
        for (i = 0; i < 17; i++) {  //设置地图
            for (j = 0; j < 17; j++) {
                map[i][j] = '*';
            }
        }
        for (i = 1; i < 16; i++) {
            for (j = 1; j < 16; j++) {
                map[i][j] = ' ';
            }
        }
        //map[6][5] = '*'; map[6][6] = '*'; map[6][7] = '*';
        //map[7][5] = '*'; map[7][7] = '*';
        map[A[4].x][A[4].y] = 'H';  //设置蛇头
        for (i = 0; i < sum - 1; i++) {  //设置蛇身
            map[A[i].x][A[i].y] = 'X';
        }
        food();
        calculate();
    }


    void show() {  //显示界面
        int i, j, x, y;
        for (i = 0; i < 17; i++) {  //显示界面
            for (j = 0; j < 17; j++) {
                printf("%c", map[i][j]);
            }
            printf("\n");
        }
        while (1) {
            Sleep(speed);  //界面刷新速度
            turn();
            move();
            if (over) {  //设置蛇死掉后可以进行的操作
                while (1) {
                    char ch = _getch();
                    if (ch == 113) {  //输入‘q’结束
                        return;
                    }
                    else if (ch == 114) {  //输入‘r’重新开始
                        ini();
                        break;
                    }
                }
            }
            system("cls");  //清屏
            for (i = 0; i < 17; i++) {  //重新显示界面
                for (j = 0; j < 17; j++) {
                    printf("%c", map[i][j]);
                }
                printf("\n");
            }
            calculate(); //计算并记录蛇头与食物距离
        }
    }

    void food() {  //生成食物
        int x, y;
        while (1) {
            x = (int)(15 * rand() / (RAND_MAX + 1.0));  //随机产生一组食物坐标
            y = (int)(15 * rand() / (RAND_MAX + 1.0));
            if (map[x][y] == ' ') {  //如果是空格则在该处生成食物
                map[x][y] = 'O';
                foodx = x;  //记录食物坐标
                foody = y;
                break;
            }
        }
    }


    void move() {  //蛇移动
        int i, x, y;
        int t = sum;  //t记录当前蛇总长度
        check();  //移动前检查按当前方向移动一步后的情况
        if (t == sum) {  //没有吃到苹果
            for (i = 0; i < sum - 1; i++) {
                if (i == 0) {  //蛇尾坐标处变成空格,把蛇尾坐标变成前一个蛇身的坐标
                    map[A[i].x][A[i].y] = ' ';
                    A[i].x = A[i + 1].x;
                    A[i].y = A[i + 1].y;
                }
                else {  //每个蛇身坐标都变为它前一个蛇身的坐标
                    A[i].x = A[i + 1].x;
                    A[i].y = A[i + 1].y;
                }
                map[A[i].x][A[i].y] = 'X';  //把地图上蛇身坐标处的字符设置成‘X’
            }
            A[sum - 1].x = A[sum - 1].x + dx[A[sum - 1].dir];  //蛇头按当前方向移动一格
            A[sum - 1].y = A[sum - 1].y + dy[A[sum - 1].dir];
            map[A[sum - 1].x][A[sum - 1].y] = 'H';  //把地图上蛇头坐标处的字符设置成‘H’
        }
        else {  //吃到苹果(sum会加1)
            map[A[sum - 2].x][A[sum - 2].y] = 'X';  //把地图上原蛇头坐标处的字符设置成‘X’
            A[sum - 1].x = A[sum - 2].x + dx[A[sum - 2].dir];  //新蛇头的坐标是原蛇头沿当前方向移动一格后的坐标
            A[sum - 1].y = A[sum - 2].y + dy[A[sum - 2].dir];
            A[sum - 1].dir = A[sum - 2].dir;  //新蛇头方向为原蛇头的方向
            map[A[sum - 1].x][A[sum - 1].y] = 'H';  //把地图上蛇头坐标处的字符设置成‘H’
            food();
        }
        for(i = 0; i < 4; i++) {  //记录下能走的方向
            x = A[sum - 1].x + dx[i];
            y = A[sum - 1].y + dy[i];
            if(map[x][y] == ' ' || map[x][y] == 'O') {
                movable[i] = 1;  //能走就把对应方向的值设置为1
            } else {
                if(x != A[0].x || y != A[0].y) {
                    movable[i] = 0;  //不能走就把对应方向的值设置为0
                } else {
                    movable[i] = 1;
                }
            }
        }
    }

    void check() {  //检查是否死亡或者吃到食物
        int x, y, i, j;
        x = A[sum - 1].x + dx[A[sum - 1].dir];  //记录按当前方向移动一格后蛇头的坐标
        y = A[sum - 1].y + dy[A[sum - 1].dir];
        if (map[x][y] == '*' || map[x][y] == 'X') {  //如果地图上该坐标处字符为‘*’或‘X’就死亡
            if (x != A[0].x || y != A[0].y) {  //蛇尾除外
                map[8][4] = 'G'; map[8][5] = 'A'; map[8][6] = 'M'; map[8][7] = 'E';  //输出“GAME OVER”
                map[8][9] = 'O'; map[8][10] = 'V'; map[8][11] = 'E'; map[8][12] = 'R';
                map[8][8] = ' ';
                system("cls");
                for (i = 0; i < 17; i++) {
                    for (j = 0; j < 17; j++) {
                        printf("%c", map[i][j]);
                    }
                    printf("\n");
                }
                printf("Input 'r' to restart\nInput 'q' to quit\n");
                over = 1;
            }
        }
        else if (map[x][y] == 'O') {  //吃到苹果
            sum++;  //蛇身总长加1
            speed = ((600 - sum * 20)>100) ? (600 - sum * 20) : 100; //速度加快
        }
    }

    void turn() {  //转弯
        int i, k = 0;
        for(i = 1; i < 4; i++) {  //找到走一步后离食物距离最短的方向
            if(distance[k] > distance[i]) {
                k = i;
            }
        }
        switch (k) {  //把把蛇头方向改为该方向
            case 0: A[sum - 1].dir = (A[sum - 1].dir == 2)?2:0; break;
            case 1: A[sum - 1].dir = (A[sum - 1].dir == 3)?3:1; break;
            case 2: A[sum - 1].dir = (A[sum - 1].dir == 0)?0:2; break;
            case 3: A[sum - 1].dir = (A[sum - 1].dir == 1)?1:3; break;
        }
    }

    void calculate() {  //计算并记录蛇头与食物距离
        int i = 0, x, y;
        for(i = 0; i < 4; i++) {
            if(movable[i] == 1) {  //如果该方向能走,则记录下沿该方向走一步后与食物的距离
                x = A[sum - 1].x + dx[i];
                y = A[sum - 1].y + dy[i];
                distance[i] = abs(foodx-x)+abs(foody-y);
            } else {  //如果不能走则把距离设置为9999
                distance[i] = 9999;
            }
        }
    }

    int main() {
        printf("你只需要静静地看着它跑\n");
        printf("按任意键开始\n");
        char ch = _getch();
        system("cls");
        ini();
        show();
        return 0;
    }
    回复 支持 1 反对 0

    使用道具 举报

  • TA的每日心情

    6 小时前
  • 签到天数: 160 天

    [LV.7]常住居民III

    发表于 2018-11-23 15:45:03 | 显示全部楼层 赞助商
    走在学习的路上
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2018-12-31 13:22
  • 签到天数: 52 天

    [LV.5]常住居民I

    发表于 2018-11-23 21:14:47 | 显示全部楼层
    菜鸡只配头晕目眩
    回复 支持 反对

    使用道具 举报

    头像被屏蔽
  • TA的每日心情
    难过
    3 天前
  • 签到天数: 194 天

    [LV.7]常住居民III

    发表于 2018-11-24 07:42:29 | 显示全部楼层
    提示: 作者被禁止或删除 内容自动屏蔽
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2019-1-2 13:11
  • 签到天数: 18 天

    [LV.4]偶尔看看III

    发表于 2018-11-26 10:24:02 | 显示全部楼层
    我该怎么办  我对自己也很无奈啊
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-2-27 19:13
  • 签到天数: 37 天

    [LV.5]常住居民I

    发表于 2018-12-27 18:53:41 | 显示全部楼层
    感谢楼主分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 18:30
  • 签到天数: 200 天

    [LV.7]常住居民III

    发表于 2019-1-10 23:54:13 来自手机 | 显示全部楼层
    看到头晕眼花
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-4-23 12:03
  • 签到天数: 51 天

    [LV.5]常住居民I

    发表于 2019-4-6 16:34:07 | 显示全部楼层
    头皮发麻  看晕了
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    3 天前
  • 签到天数: 16 天

    [LV.4]偶尔看看III

    发表于 6 天前 来自手机 | 显示全部楼层
    看的头昏脑胀
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    站长推荐 上一条 /1 下一条

    红盟社区--中国红客联盟 

    Processed in 0.106670 second(s), 24 queries.

    站点统计| 举报| Archiver| 手机版| 黑屋 |   

    Powered by HUC © 2001-2017 Comsenz Inc.

    手机扫我进入移动触屏客户端

    关注我们可获取更多热点资讯

    Honor accompaniments. theme macfee

    快速回复 返回顶部 返回列表