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日)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章