c语言之简单的贪吃蛇 -- 详解以及源代码

一. 前言

   小时候都玩过贪吃蛇这个经典的小游戏,在我们的普通手机里似乎都是必备的。它伴随着我们的童年,经历了好多好多时光。它带给我们了许多的乐趣。

   我做这个的目的其实想放松放松. 利用了几天的空闲时间做做.

   也是想尝试以前想过但未实现的一个小游戏.

二. 问题描述

   包含等级选择,暂停/继续和分数制。

三. 分析思路

   下面就来讲讲贪吃蛇的设计思路.

1.地图

   地图含简单, 利用char的二维数组, 将外围一圈设置为城墙, 我使用的是’#’代表墙.

2.食物的产生

   利用随机函数(rand())产生随机食物的坐标, 该坐标的值不能与墙重合, 不能与蛇身重合. 若重合的话, 重新找一对xy的值. 食物我这里用的是’O’表示.

3. 构造一条蛇

   使用另一个int类型的二维数组,为什么用int后面讲.用’Q’代表蛇脑袋, ‘a’代表蛇身体, 开始时, 初始化到某以位置上.

4.蛇的移动

   利用上下左右或者wasd空着蛇的走位. 以及当蛇每走一步就利用 system(“cls”)清屏, 重新打印, 模拟蛇的移动.

5. 游戏结束

   当蛇撞墙, 以及咬到自己的身体时候游戏结束.

四. 编程所需知识

1.二维数组
2.一些系统函数
3.随机函数

以上几点所需知识会的话, 完全也可以做出一个来.
可以先自己尝试一番~再继续往下看.

五. 代码具体分析

1.所需的基本的自定义函数,全局变量, 以及头文件

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

string.h : memset();函数
windows.h: gotoxy()函数(尽管这个是自定义的, 内部需要涉及到这个头文件)
stdlib.h: system();
conio.h: getch();
time.h: 随机函数的种子

# define de_lenth 5 //蛇初始长度
# define ROW_MAX 20//地图行
# define LINE_MAX 30//地图列

int Head_x = ROW_MAX/2, Head_y = LINE_MAX/2;//蛇的初始坐标
int Head_v = 5;//判断是否为头
int Tail_x = 0, Tail_y = 0;//蛇尾坐标
int count = 0;//计数
char direct = 'a';//蛇移动的方向
void gotoxy(int x, int y);//将光标定位到某一位置, 用于显示结果, 以及暂停是使用
void CreateMap(char map[ROW_MAX][LINE_MAX]);//创建地图
void TraverseMap(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]);//输出地图以及蛇的全部
void CreateSnake(int snkae[ROW_MAX][LINE_MAX]);//构造蛇的初始位置
void run(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]);//蛇的移动
int JudgeWall(void);//判断蛇是否撞墙
void CreateFood(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]);//产生随机食物
void MoveTail(int snake[ROW_MAX][LINE_MAX]);//蛇尾部的移动
int EatFood(char map[ROW_MAX][LINE_MAX]);//蛇吃到食物的操作
void Result(void);//显示结果

2.主函数

int main()
{
    char map[ROW_MAX][LINE_MAX];
    int snake[ROW_MAX][LINE_MAX];
    srand(time(NULL));

/**************初始画面**************/
    memset(map, 0, sizeof(map));
    memset(snake, 0, sizeof(snake));
    system("cls");
    CreateMap(map); 
//  gotoxy(1, 1);
    CreateSnake(snake);
    CreateFood(map, snake);
    TraverseMap(map, snake);
/**************初始画面**************/

/*********运动*****************/
    run(map, snake);
/******************************/

    Result();

    return 0;
}

3. 创建地图

void CreateMap(char map[ROW_MAX][LINE_MAX]){
//将行为0和ROW_MAX的位置赋值为'#', 以及列为0和LINE_MAX赋值为'#', 表示墙;
    int i, j;   

    for(i = 0; i < ROW_MAX; ++i)
        map[i][0] = '#';
    for(j = 1; j < LINE_MAX; ++j)
        map[0][j] = '#';
    for(i = ROW_MAX-1, j = 1; j < LINE_MAX; ++j)
        map[i][j] = '#';
    for(j = LINE_MAX-1, i = 1; i < ROW_MAX; ++i)
        map[i][j] = '#';
}

3.构造一条蛇

void CreateSnake(int snake[ROW_MAX][LINE_MAX]){

    int i, j;
    int value = Head_v;
    snake[Head_x][Head_y] = value;

    for(i = Head_x, j = Head_y+1; j < Head_y + de_lenth; ++j)
        snake[i][j] = --value;
    Tail_x = i;
    Tail_y = --j;
}

解释: 蛇脑袋的值是最大的(初始为5), 蛇尾是最小的(初始为1), 这样写得目的是为了, 蛇移动时, 只需要移动蛇脑袋和蛇尾部即可, 蛇尾部移动规律就是找到比它大一的那个值. 所以我设置为Int类型.

4.产生随机食物

void CreateFood(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]){

    int food_x = 0;
    int food_y = 0;

    while (map[food_x][food_y] == '#' || snake[food_x][food_y] != 0){

        food_x = rand()%(ROW_MAX-3) + 1;
        food_y = rand()%(LINE_MAX-3) + 1;
    }

    map[food_x][food_y] = 'O';
}

解释: 为什么是-3呢, 举个例子, 地图22x22/(0.0)-(21.21), 而实际区域是(1.1)-(20.20), 就要产生1-20的随机数, 也就是 0-19的随机数+1, 22-19 = 3, 所以减3.
食物不能与墙以及蛇身体重合.
食物放到地图的数组里.

5.输出地图以及蛇的全部

void TraverseMap(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]){

    int i, j;

    for (i = 0; i < ROW_MAX; ++i){
        for (j = 0; j < LINE_MAX; ++j){
            if(snake[i][j] == 0)
                printf("%c", map[i][j]);
            else{
                if(snake[i][j] == Head_v)
                    putchar('Q');
                else
                    putchar('a');               
            }
        }
        putchar('\n');
    }
}

解释: 在输出地图的同时顾忌到蛇, 这样就能输出地图的同时输出蛇.

6.判断蛇是否撞墙

int JudgeWall(void){

    if((Head_x == 0 || Head_x == ROW_MAX-1) || (Head_y == 0 || Head_y == LINE_MAX-1))
        return 0;
    else 
        return 1;
}

解释: 如果撞墙则返回0 因为 后面用到的是 if(JudgeWall())

7. 蛇尾部的移动

void MoveTail(int snake[ROW_MAX][LINE_MAX]){

    if (snake[Tail_x][Tail_y]+1 == snake[Tail_x-1][Tail_y]){

        snake[Tail_x][Tail_y] = 0;
        Tail_x--;
    }
    else if (snake[Tail_x][Tail_y]+1 == snake[Tail_x+1][Tail_y]){

        snake[Tail_x][Tail_y] = 0;
        Tail_x++;
    }
    else if (snake[Tail_x][Tail_y]+1 == snake[Tail_x][Tail_y-1]){

        snake[Tail_x][Tail_y] = 0;
        Tail_y--;
    }
    else{

        snake[Tail_x][Tail_y] = 0;
        Tail_y++;
    }
}

解释: 这就是之前所说的, 蛇尾部去寻找, 比它大一的位置, 位置可能有上下左右, 所以4种情况

7. 蛇吃到食物操作

int EatFood(char map[ROW_MAX][LINE_MAX]){

    if(map[Head_x][Head_y] == 'O'){

        map[Head_x][Head_y] = 0;
        count++;
        return 0;
    }
    else
        return 1;
}

解释: 6.7是在一起的, if(EatFood(map)) MoveTail(snake);
没有吃到食物的话, 尾部正常移动, 吃到, 尾部不移动.

8. 蛇的运动(精华)

void run(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]){
/*
上   -32 0xffffffe0 72 H
下   -32 0xffffffe0 80 P
左   -32 0xffffffe0 75 K
右   -32 0xffffffe0 77 M
*/
    char sh, ch;
    while(1){

        if(JudgeWall()){
        /**********判断键盘是否敲击***********/
            if (kbhit()){

                ch = getch();
                if (ch == -32){

                    sh = getch();
                    switch (sh){

                        case 'H': direct = 'w'; break;
                        case 'P': direct = 's'; break;
                        case 'K': direct = 'a'; break;
                        case 'M': direct = 'd'; break;                  
                    }
                }
                else{                   
                    switch (ch){

                    case 'w':case 'W': direct = 'w'; break;
                    case 's':case 'S': direct = 's'; break;
                    case 'a':case 'A': direct = 'a'; break;
                    case 'd':case 'D': direct = 'd'; break;

                    }
                }               
            }
        /************************************/

        /**************蛇的运动******************/
            switch (direct){

                case 'w':
                    if(snake[Head_x-1][Head_y] != 0)
                        return;

                    snake[Head_x-1][Head_y] = ++Head_v;
                    Head_x--;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;
                case 'a':
                    if(snake[Head_x][Head_y-1] != 0)
                        return;

                    snake[Head_x][Head_y-1] = ++Head_v;
                    Head_y--;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;
                case 's':
                    if(snake[Head_x+1][Head_y] != 0)
                        return;

                    snake[Head_x+1][Head_y] = ++Head_v;
                    Head_x++;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;                  
                case 'd': 
                    if(snake[Head_x][Head_y+1] != 0)
                        return;

                    snake[Head_x][Head_y+1] = ++Head_v;
                    Head_y++;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;          
            }
            system("cls");
            TraverseMap(map, snake);
        /****************************************/
        }
        else
            return;
    }
}

分两部分解释
解释: 键盘是否被敲击, 运用到了 kbhit() 这个函数, 如果被敲击, 则返回1, 没有则返回0.
以及还需要注意一点的是, 上下左右是组合键, 需要用到文中代码的格式,

                ch = getch();
                if (ch == -32){

                    sh = getch();
                    switch (sh){

                        case 'H': direct = 'w'; break;
                        case 'P': direct = 's'; break;
                        case 'K': direct = 'a'; break;
                        case 'M': direct = 'd'; break;                  
                    }
                }

上下左右的第一个字节是0xe0即-32; 如果是的话, 则在使用一个getch(); 判断具体什么键.
以及增加了也可以使用wasd控制方向. 如果不是-32的话, 就进入这块的代码;
并将direct 赋值 为那一方向的值;

解释:蛇的运动: 通过direct的值判断 蛇的走向;
if(snake[Head_x-1][Head_y] != 0) return;
这代码是判断是否咬到自己的身体(以及下三个方向同理).
更新即将要到 snake[Head_x-1][Head_y] 位置的值; 并更蛇脑袋的新坐标 Head_x–;
接下来就是, 看有没有吃到食物, 没有则移动尾部, 吃到则不移动位置, 并在创建一个新的食物坐标;
最后就是清屏打印移动一个位置的蛇;

9. 将光标移动到任意位置

void gotoxy(int x, int y)
{
    CONSOLE_SCREEN_BUFFER_INFO    csbiInfo;                            
    HANDLE    hConsoleOut;
    hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
    csbiInfo.dwCursorPosition.X = x;                                    
    csbiInfo.dwCursorPosition.Y = y;                                    
    SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); 
}

解释: 会用即可, 注意的是, x向右是x轴的正半轴,y向下就y的正半轴;所以 (1,2)代表第二行第一列(与数组表示有点不同);

10. 输出结果

void Result(void){
    int i, j;
    for(i = ROW_MAX/2-2; i <= ROW_MAX/2+1; ++i){
        gotoxy(0, i);
        for(j = 0; j <= LINE_MAX; ++j)
            putchar(' ');
    }
    gotoxy(LINE_MAX/2-4<0?0:LINE_MAX/2-4, ROW_MAX/2-1);
    printf("The end!\n");
    gotoxy(LINE_MAX/2-8<0?0:LINE_MAX/2-8, ROW_MAX/2);
    printf("Your score is %d\n", count);
    gotoxy(0,ROW_MAX-1);
}

解释: 将结果显示在图的中间, 最后将光标转至地图外.

六. 完善

1.设置

由于不同的处理器, 蛇的移动速度也不一样;
以及可以修改地图的大小;

int ROW = ROW_MAX;
int LINE = LINE_MAX;
int times = 1;//均为全局变量
//若增加此函数, 要达到修改的目的, 须将之前所有函数体中的 _MAX 删去(函数名中的_MAX不必删除)
//或者等后面的源代码

void SetUp(void){

    char ch;
    int row;
    int line;
    int speed;
    system("cls");
    printf("\tSET UP\n");
    printf("1. speed\n");
    printf("2. area\n");
    printf("0. return\n");

    ch = getch();
    while(1){
        switch (ch){

        case '1':
            printf("The less the figure the faster speed level(1~8)\n");
            printf("Speed level: ");
            scanf("%d", &speed);
            times = speed>8? 8: speed<1? 1: speed;
            printf("The speed leve: %ld", times);
            break;
        case '2':
            printf("Update length and width(the max size is 80 x 80 and input 0 default)\n");
            printf("length: ");
            scanf("%d", &row);
            printf("width: ");
            scanf("%d", &line);

            if(line != 0 && row != 0){

                ROW = row+2;
                LINE = line+2;
                Head_x = ROW/2;
                Head_y = LINE/2;
            }
            printf("After updating length: %d\twidth: %d\n", row, line);

            break;

            default:
                return;
        }
        for(long i = 0; i < 400000000; ++i);//延时显示结果
        //fflush(stdin);
        system("cls");
        printf("\tSET UP\n");
        printf("1. speed\n");
        printf("2. area\n");
        printf("0. return\n");

        ch = getch();
    }

}

延时函数

void dely (void){

    for(long i = 0; i <= pow(16, times); ++i)
        ;
}

将此代码插入到此位置即可.

//处理按上下左右;
if(direct == 'w'){

    if(sh == 'P')
        continue;
}
else if (direct == 's'){

    if(sh == 'H')
        continue;
}
else if (direct == 'a'){

    if(sh == 'M')
        continue;
}
else{

    if(sh == 'K')
        continue;
}

//处理按wasd;
while(1){

        if(JudgeWall()){
        /**********判断键盘是否敲击***********/

        /************************************/

        /**************蛇的运动******************/

        /****************************************/
        }
        else
            return;
        dely();
    }

2. 方向会冲突

当方向为上时, 按下, 会结束游戏. 所以要增加一个条件, 防止冲突;

if(direct == 'w'){

    if(ch == 's' || ch == 'S')
        continue;
}
else if (direct == 's'){

    if(ch == 'w' || ch == 'W')
        continue;
}
else if (direct == 'a'){

    if(ch == 'd' || ch == 'D')
        continue;
}
else{

    if(ch == 'a' || ch == 'A')
        continue;
}

3. 其它

例如:
   更改颜色(蛇的颜色, 食物颜色)
   以及完善界面.等

七. 源代码

//2017年5月19日 21:06:33
//2017年5月22日 20:42:40
# include <stdio.h>
# include <string.h>
# include <windows.h>
# include <stdlib.h>
# include <conio.h>
# include <time.h>
# include <math.h>

# define de_lenth 5//蛇初始长度
# define ROW_MAX 20//地图行
# define LINE_MAX 30//地图列

int ROW = ROW_MAX;
int LINE = LINE_MAX;
int Head_x = ROW_MAX/2, Head_y = LINE_MAX/2;//蛇的初始坐标
int Head_v = 5;//判断是否为头
int Tail_x = 0, Tail_y = 0;//蛇尾坐标
int count = 0;//计数
char direct = 'a';//蛇移动的方向
int times = 1;

void SetUp(void);
void CreateMap(char map[ROW_MAX][LINE_MAX]);//创建地图
void CreateSnake(int snkae[ROW_MAX][LINE_MAX]);//构造蛇的初始位置
void CreateFood(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]);//产生随机食物
void TraverseMap(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]);//输出地图以及蛇的全部
int JudgeWall(void);//判断蛇是否撞墙
void MoveTail(int snake[ROW_MAX][LINE_MAX]);//蛇尾部的移动
int EatFood(char map[ROW_MAX][LINE_MAX]);//蛇吃到食物的操作
void run(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]);//蛇的移动
void gotoxy(int x, int y);//将光标定位到某一位置, 用于显示结果, 以及暂停是使用
void Result(void);//显示结果
void dely(void);

int main()
{
    char map[ROW_MAX][LINE_MAX];
    int snake[ROW_MAX][LINE_MAX];
    char ch;
    srand(time(NULL));
/************设置*********************/   
    system("cls");
    printf("\tPress T/t to set up\n");
    printf("Press any other key to start!\n");
    ch = getch();

    if(ch == 'T' || ch == 't')
        SetUp();
/*************************************/

/**************初始画面**************/
    memset(map, 0, sizeof(map));
    memset(snake, 0, sizeof(snake));
    system("cls");
    CreateMap(map); 
//  gotoxy(1, 1);
    CreateSnake(snake);
    CreateFood(map, snake);
    TraverseMap(map, snake);
/**************初始画面**************/

/**********运动*****************/
    run(map, snake);
/*******************************/

/*************结果***************/
    Result();
/********************************/
    return 0;
}

void SetUp(void){

    char ch;
    int row;
    int line;
    int speed;
    system("cls");
    printf("\tSET UP\n");
    printf("1. speed\n");
    printf("2. area\n");
    printf("0. return\n");

    ch = getch();
    while(1){
        switch (ch){

        case '1':
            printf("The less the figure the faster speed level(1~8)\n");
            printf("Speed level: ");
            scanf("%d", &speed);
            times = speed>8? 8: speed<1? 1: speed;
            printf("The speed leve: %ld", times);
            break;
        case '2':
            printf("Update length and width(the max size is 80 x 80 and input 0 default)\n");
            printf("length: ");
            scanf("%d", &row);
            printf("width: ");
            scanf("%d", &line);

            if(line != 0 && row != 0){

                ROW = row+2;
                LINE = line+2;
                Head_x = ROW/2;
                Head_y = LINE/2;
            }
            printf("After updating length: %d\twidth: %d\n", row, line);

            break;

            default:
                return;
        }
        for(long i = 0; i < 400000000; ++i);
        //fflush(stdin);
        system("cls");
        printf("\tSET UP\n");
        printf("1. speed\n");
        printf("2. area\n");
        printf("0. return\n");

        ch = getch();
    }

}

void CreateMap(char map[ROW_MAX][LINE_MAX]){
//将行为0和ROW_MAX的位置赋值为'#', 以及列为0和LINE_MAX赋值为'#', 表示墙;
    int i, j;


    for(i = 0; i < ROW; ++i)
        map[i][0] = '#';
    for(j = 1; j < LINE; ++j)
        map[0][j] = '#';
    for(i = ROW-1, j = 1; j < LINE; ++j)
        map[i][j] = '#';
    for(j = LINE-1, i = 1; i < ROW; ++i)
        map[i][j] = '#';
}

void CreateSnake(int snake[ROW_MAX][LINE_MAX]){

    int i, j;
    int value = Head_v;
    snake[Head_x][Head_y] = value;

    for(i = Head_x, j = Head_y+1; j < Head_y + de_lenth; ++j)
        snake[i][j] = --value;
    Tail_x = i;
    Tail_y = --j;
}

void CreateFood(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]){

    int food_x = 0;
    int food_y = 0;

    while (map[food_x][food_y] == '#' || snake[food_x][food_y] != 0){

        food_x = rand()%(ROW-3) + 1;
        food_y = rand()%(LINE-3) + 1;
    }

    map[food_x][food_y] = 'O';
}

void TraverseMap(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]){

    int i, j;

    for (i = 0; i < ROW; ++i){
        for (j = 0; j < LINE; ++j){
            if(snake[i][j] == 0)
                printf("%c", map[i][j]);
            else{
                if(snake[i][j] == Head_v)
                    putchar('Q');
                else
                    putchar('a');               
            }
        }
        putchar('\n');
    }
}

int JudgeWall(void){

    if((Head_x == 0 || Head_x == ROW-1) || (Head_y == 0 || Head_y == LINE-1))
        return 0;
    else 
        return 1;
}



void MoveTail(int snake[ROW_MAX][LINE_MAX]){

    if (snake[Tail_x][Tail_y]+1 == snake[Tail_x-1][Tail_y]){

        snake[Tail_x][Tail_y] = 0;
        Tail_x--;
    }
    else if (snake[Tail_x][Tail_y]+1 == snake[Tail_x+1][Tail_y]){

        snake[Tail_x][Tail_y] = 0;
        Tail_x++;
    }
    else if (snake[Tail_x][Tail_y]+1 == snake[Tail_x][Tail_y-1]){

        snake[Tail_x][Tail_y] = 0;
        Tail_y--;
    }
    else{

        snake[Tail_x][Tail_y] = 0;
        Tail_y++;
    }
}

int EatFood(char map[ROW_MAX][LINE_MAX]){

    if(map[Head_x][Head_y] == 'O'){

        map[Head_x][Head_y] = 0;
        count++;
        return 0;
    }
    else
        return 1;
}

void run(char map[ROW_MAX][LINE_MAX], int snake[ROW_MAX][LINE_MAX]){
/*
上   -32 0xffffffe0 72 H
下   -32 0xffffffe0 80 P
左   -32 0xffffffe0 75 K
右   -32 0xffffffe0 77 M
*/
    char sh, ch;
    while(1){

        if(JudgeWall()){
        /**********判断键盘是否敲击***********/
            if (kbhit()){

                ch = getch();
                if (ch == -32){

                    sh = getch();
                    if(direct == 'w'){

                        if(sh == 'P')
                            continue;
                    }
                    else if (direct == 's'){

                        if(sh == 'H')
                            continue;
                    }
                    else if (direct == 'a'){

                        if(sh == 'M')
                            continue;
                    }
                    else{

                        if(sh == 'K')
                            continue;
                    }

                    switch (sh){

                        case 'H': direct = 'w'; break;
                        case 'P': direct = 's'; break;
                        case 'K': direct = 'a'; break;
                        case 'M': direct = 'd'; break;              
                    }
                }
                else{

                    if(direct == 'w'){

                        if(ch == 's' || ch == 'S')
                            continue;
                    }
                    else if (direct == 's'){

                        if(ch == 'w' || ch == 'W')
                            continue;
                    }
                    else if (direct == 'a'){

                        if(ch == 'd' || ch == 'D')
                            continue;
                    }
                    else if (direct == 'd'){

                        if(ch == 'a' || ch == 'A')
                            continue;
                    }

                    switch (ch){

                    case 'w':case 'W': direct = 'w'; break;
                    case 's':case 'S': direct = 's'; break;
                    case 'a':case 'A': direct = 'a'; break;
                    case 'd':case 'D': direct = 'd'; break;
                    case 27:
                        int i, j;
                        for(i = ROW/2-1; i <= ROW/2+1; ++i){
                                gotoxy(0, i);
                                for(j = 0; j <= LINE; ++j)
                                    putchar(' ');
                        }

                        gotoxy(LINE/2-8<0?0:LINE/2-8, ROW/2);
                        system("pause");

                        break;

                    }
                }               
            }
        /************************************/

        /**************蛇的运动******************/
            switch (direct){

                case 'w':
                    if(snake[Head_x-1][Head_y] != 0)
                        return;

                    snake[Head_x-1][Head_y] = ++Head_v;
                    Head_x--;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;
                case 'a':
                    if(snake[Head_x][Head_y-1] != 0)
                        return;

                    snake[Head_x][Head_y-1] = ++Head_v;
                    Head_y--;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;
                case 's':
                    if(snake[Head_x+1][Head_y] != 0)
                        return;

                    snake[Head_x+1][Head_y] = ++Head_v;
                    Head_x++;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;                  
                case 'd': 
                    if(snake[Head_x][Head_y+1] != 0)
                        return;

                    snake[Head_x][Head_y+1] = ++Head_v;
                    Head_y++;
                    if(EatFood(map))
                        MoveTail(snake);
                    else
                        CreateFood(map, snake);
                    break;          
            }
            system("cls");
            TraverseMap(map, snake);
        /****************************************/
        }
        else
            return;
        dely();
    }
}



void gotoxy(int x, int y)
{
    CONSOLE_SCREEN_BUFFER_INFO    csbiInfo;                            
    HANDLE    hConsoleOut;
    hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
    csbiInfo.dwCursorPosition.X = x;                                    
    csbiInfo.dwCursorPosition.Y = y;                                    
    SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); 
}

void Result(void){
    int i, j;
    for(i = ROW/2-2; i <= ROW/2+1; ++i){
        gotoxy(0, i);
        for(j = 0; j <= LINE; ++j)
            putchar(' ');
    }
    gotoxy(LINE/2-4<0?0:LINE/2-4, ROW/2-1);
    printf("The end!\n");
    gotoxy(LINE/2-8<0?0:LINE/2-8, ROW/2);
    printf("Your score is %d\n", count);
    gotoxy(0,ROW);
    printf("Press any key to quit\n");
    printf("Thank you!\n");
    getch();
}

void dely (void){

    for(long i = 0; i <= pow(16, times); ++i)
        ;
}

八. 总结

看似复杂的程序, 实则思路理解了, 也变的简单化了;
以及要学会多搜索, kbhit()函数, 以及如何表示上下左右, 之类的东西, 都是搜索出来的.

好的~~
谢谢~~(2017年5月25日)

  • 55
    点赞
  • 181
    收藏
    觉得还不错? 一键收藏
  • 33
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值