c語言課程設計之貪吃蛇代碼及思路 c語言課程設計報告之貪吃蛇

 

原文做者:aircrafthtml

原文地址:https://www.cnblogs.com/DOMLX/p/8846529.html前端

 

注:本文檔需與c語言課程設計之貪吃蛇文檔配套使用。c語言實現貪吃蛇代碼可隨意下載 c語言課程設計報告也可隨意下載
1.本代碼在VS2013下可正常運行,其餘版本需根據版本須要進行調試。
2.代碼在Csnake-Csnake裏,想直接打開整個工程直接進入Cnake,點擊Csnake.sln打開  注意這裏可能須要使用相關的IDE環境才能打開,沒有相關環境的話,複製代碼本身建立個工程就好了很簡單的。
3.代碼註釋爲全英文註釋,如有疑問可藉助百度翻譯,或者看文檔報告。python

 

貪吃蛇代碼文檔連接可直接百度雲下載:連接:https://pan.baidu.com/s/1vnXkR8d9-R5lAYpxzcMYxw 密碼:i1q6linux

 

後面在下的博客可能還會有大學常見的課設代碼和報告發布,好比c++MFC課設,數據庫課設,WEB課設,網絡編程課設,linux課設,數據結構課設,python課設,matlab課設,,,想要的話就關注在下的博客吧嘿嘿-----c++

 

 

說到大學都要作的課程設計和報告我仍是決定分享出來,爲何呢?(大學就是給這些無聊的課程,無聊報告和畫圖耽誤的,纔會有那麼多大學生找不到工做)節省你們時間啦 嘿嘿。。。。。。請叫我雷鋒先生。。。算法

說到貪吃蛇仍是直接上代碼吧,解釋最後來。。。。。數據庫

首先是main.cpp文件,控制調用函數。編程

#include "snake.h"

//Transposed structure object
extern  struct Food food;
extern  struct Snake snake;

//main function
int main()
{
    ret = menu();
    if (ret == 1)
    {
        while (finish)
        {
            initMap();                                                                    //Initialization map
            while (TRUE)
            {
                updataFood();                                                        //updata food
                getSpeed();                                                            //speed
                moveSnake();                                                        //move snake
                Sleep(snake.speed);                                                    //Control the speed of the snake
                printFont(FONT_WINDOW_STARTX, FONT_WINDOW_STARTY, snake.speed);        //Right interface
                if (!(isAlive()))
                    break;
            }
            if (finish)                                                                    //Death or customs clearance
            {
                system("cls");
                gotoxy(22, 5);
                printf("Game Over!");
                gotoxy(24, 5);
                printf("按(1)鍵退出遊戲,按其餘任意鍵重玩");
                if (getch() == 49)
                    break;
                system("cls");
            }
            else
            {
                system("cls");
                gotoxy(22, 5);
                printf("恭喜你通關了");
                gotoxy(24, 5);
                printf("按(1)鍵退出遊戲,按其餘任意鍵重玩");
                if (getch() == 49)
                    break;
                system("cls");
            }
            
        }
        
    }

    return 0;
}

 

snake.h 主要聲明函數和定義變量。windows

#pragma once
#ifndef _SNAKE_H_
#define _SNAKE_H_
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#include <time.h>
#pragma warning(disable: 4996)



#define FONT_WINDOW_STARTY 41 //define font window 
#define FONT_WINDOW_STARTX 2
#define FRAME_HEIGHT 20 //define map size
#define FRAME_WIDTH 40
#define UP 'w' //define operate key
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'
#define SNAKE_LEN 50
#define ADD 3


static int i, j, k;
static char ch = UP; //initial first direction
static char Direction = UP;
static int grow = 0; //flag: if snake grow
static int ret = 0;
static int finish = 1;

//Structure declaration
struct Food{
    int x;
    int y;
};
struct Snake{
    int x[SNAKE_LEN];
    int y[SNAKE_LEN];
    int len;
    int speed;
}; //snake[0] is head


//Initialization map
void initMap(void);

//updataFood
void updataFood(void);

//moveSnake
void moveSnake(void);

//Judge whether the snake is alive or not
int isAlive(void);

//get snake speed
void getSpeed(void);

//move cursor
void gotoxy(int x, int y);

//Right interface
void printFont(int x, int y, int speed);

//menu
int menu();


#endif

snake.cpp文件 主要實現函數功能。後端

#include "snake.h"

//Initialization of structure
struct Food food;
struct Snake snake;



//menu
int menu()
{
    gotoxy(14, 45);
    printf("歡迎來到貪吃蛇小遊戲....");
    gotoxy(16, 45);
    printf("開始遊戲請按(1)");
    gotoxy(18, 45);
    printf("按其餘任意鍵退出遊戲QAQ");
    int ch = getch();

    while (TRUE)
    {
        if (ch == 49)                                    //The ASCII value of 1
        {
            ret = 1;
            break;
        }
        else
        {
            break;
        }


    }
    system("cls");
    return ret;
}

//initialize Map
void initMap(void)
{
    ch = UP;
    Direction = UP;
    //initial food
    srand(time(NULL));                                    //Set random number seed
    food.x = rand() % (FRAME_HEIGHT - 2) + 1;
    food.y = rand() % (FRAME_WIDTH - 2) + 1;
    gotoxy(food.x, food.y);
    printf("!");
    //initial snake
    snake.x[0] = FRAME_HEIGHT / 2;
    snake.y[0] = FRAME_WIDTH / 2;
    gotoxy(snake.x[0], snake.y[0]);
    printf("@");
    snake.len = 3;
    snake.speed = 200;
    for (k = 1; k<snake.len; k++)
    {
        snake.x[k] = snake.x[k - 1] + 1;
        snake.y[k] = snake.y[k - 1];
        gotoxy(snake.x[k], snake.y[k]);
        printf("@");
    }
    //initial bar
    for (j = 0; j<FRAME_WIDTH; j++)
    {
        gotoxy(0, j);
        printf("#");
        gotoxy(FRAME_HEIGHT - 1, j);
        printf("#");
    }
    for (i = 1; i<FRAME_HEIGHT - 1; i++)
    {
        gotoxy(i, 0);
        printf("#");
        gotoxy(i, FRAME_WIDTH - 1);
        printf("#");
    }
}

//Right interface
void printFont(int x, int y, int speed)
{
    int i = 1;
    gotoxy(x, y);
    printf("召喚師,歡迎來到貪吃蛇峽谷");

    gotoxy(x + ADD, y);
    if (speed == 200)
    {
        printf("如今的速度是:%d級", i);
    }
    else if (speed == 100)
    {
        printf("如今的速度等級是:%d級", i + 1);
    }
    else if (speed == 50)
    {
        printf("如今的速度等級是:%d級", i + 2);
    }
    else
    {
        printf("恭喜你,召喚師,如今是最高級");
    }
    gotoxy(x + 2 * ADD, y);
    printf("上下左右操做鍵分別是:w,s,a,d");

    gotoxy(x + 3 * ADD, y);
    printf("當吃到本身身體或者撞牆時遊戲結束");

    gotoxy(x + 4 * ADD, y);
    printf("按空格鍵暫停,在按空格鍵繼續");
}

//generate food
void updataFood()
{
    if (snake.x[0] == food.x&&snake.y[0] == food.y)                //When the snake eats food update
    {
        srand(time(NULL));
        food.x = rand() % (FRAME_HEIGHT - 2) + 1;
        food.y = rand() % (FRAME_WIDTH - 2) + 1;
        gotoxy(food.x, food.y);
        printf("!");


        snake.len++;
        grow = 1;
    }
}

//move snake
void moveSnake()
{

    if (!grow)
    {
        gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
        printf(" ");                            //The tail will be empty
    }
    for (k = snake.len - 1; k>0; k--)
    {
        snake.x[k] = snake.x[k - 1];
        snake.y[k] = snake.y[k - 1];
    }
    if (kbhit())
    {
        ch = getch();
        if (ch == ' ')                                                //Pause or continue by space
        while (getch() != ' '){};
        if (ch != UP && ch != DOWN && ch != LEFT && ch != RIGHT)    //Other keys to prevent interference
        {
            ch = Direction;
            goto sport;
        }

        if (Direction != ch)
        {
            if ((Direction == UP &&ch != DOWN) || (Direction == DOWN &&ch != UP) || (Direction == LEFT && ch != RIGHT) || (Direction == RIGHT && ch != LEFT)) //Prevent reverse movement
            {
                Direction = ch;
                goto sport;
            }
            else
            {
                ch = Direction;
                goto sport;
            }

        }
        else
        {
            goto sport;
        }
    }
    else
    {
    sport:
        switch (ch)                            //Move the snake's head
        {
        case UP: snake.x[0]--; break;
        case DOWN:  snake.x[0]++; break;
        case LEFT: snake.y[0]--; break;
        case RIGHT: snake.y[0]++; break;
        default: break;

        }
    }

    gotoxy(snake.x[0], snake.y[0]);
    printf("@");                            //print the snake's head
    grow = 0;
    gotoxy(FRAME_HEIGHT, 0);
}

//Judge whether the snake is alive or not
int isAlive(void)
{
    if (snake.x[0] == 0 || snake.x[0] == FRAME_HEIGHT - 1 || snake.y[0] == FRAME_WIDTH - 1 || snake.y[0] == 0)   //When you touch a wall or eat your own body, you die
        return 0;
    for (k = 1; k<snake.len; k++)
    if (snake.x[k] == snake.x[0] && snake.y[k] == snake.y[0])
        return 0;
    return 1;
}

//speed updata
void getSpeed(void)
{
    if (snake.len <= 6)
        snake.speed = 200;
    else if (snake.len <= 10)
        snake.speed = 100;
    else if (snake.len <= 20)
        snake.speed = 50;
    else if (snake.len <= 30)
        snake.speed = 30;
    else snake.speed = 20;
    if (snake.len == 40)
        finish = 0;
}

//move cursor
void gotoxy(int x, int y)
{
    HANDLE hout;                                //Defining handle objects
    COORD cor;                                    //Defining coordinate objects
    hout = GetStdHandle(STD_OUTPUT_HANDLE);        //Get the handle of the output screen buffer
    cor.X = y;
    cor.Y = x;
    SetConsoleCursorPosition(hout, cor);        //Move Cursor
}

接下來是課程設計的報告。

 

1. 課程設計目的1

2. 課程設計的內容1

3. 課程設計的功能要求1

3.1. 菜單模塊:1

3.2. 地圖初始化模塊:1

3.3. 食物更新模塊:1

3.4. 移動貪吃蛇模塊:1

3.5. 貪吃蛇生命模塊:1

3.7.  獲取貪吃蛇速度模塊.........................................................................................................1

3.7.  移動窗口光標模塊.............................................................................................................1

3.8    幫助系統模塊.........................................................................................................................................1

3.8    退出系統模塊.........................................................................................................................................1

4. 概要設計2

4.1. 系統功能框架圖2

4.2. 功能模塊描述2

5. 詳細設計3

5.1. 各功能模塊的具體實現算法——流程圖3

5.1.1. 主控main函數流程圖3

5.2. 重點設計描述3

6. 系統測試與調試3

7. 課程設計心得體會4

參考資料4

 

1. 課程設計目的

進一步加深、鞏固所學專業課程《C語言程序設計》的基本理論知識,理論聯繫實際,進一步培養本身綜合分析問題和解決問題的能力。掌握運用C語言獨立地編寫、調試應用程序和進行其它相關設計的技能。熟悉使用結構體與時間函數和windows窗口控制函數。

2. 課程設計的內容

設計並實現一個貪吃蛇小遊戲,要求具備如下功能模塊:

(1) 頁面菜單模塊。

(2) 初始化地圖模塊。

(3) 食物更新模塊。

(4) 移動貪吃蛇模塊。

(5) 判斷貪吃蛇是否存活模塊。

(6) 獲取貪吃蛇速度模塊

(7) 移動窗口光標模塊。

(8) 幫助系統模塊

(9) 退出系統模塊

3. 課程設計的功能要求

3.1. 頁面菜單模塊:

² 開始遊戲

² 退出遊戲

3.2. 初始化地圖模塊:

² 實現貪吃蛇存在範圍(這裏用圍牆來限定區域)

² 初始化貪吃蛇(3單位身體長度)

² 初始化食物

3.3. 食物更新模塊:

² 在區域內隨機刷新食物

² 食物不與蛇身體重合

3.4. 移動貪吃蛇模塊:

² 根據玩家按鍵移動貪吃蛇(w,s,a,d)

² Space 空格可暫停或繼續遊戲

² 當貪吃蛇前進時按相反方向移動無效

² 除了程序控制鍵以外的其餘按鍵不會影響貪吃蛇

² 移動貪吃蛇時不會形成屏幕閃爍BUG

3.5. 貪吃蛇生命模塊:

² 當蛇吃到本身身體或者觸碰圍牆時蛇死亡

3.6. 獲取貪吃蛇速度模塊:

² 根據蛇的身體長度來設置速度等級

² 當身體長度足夠長時則通關遊戲

 

3.7. 移動光標模塊:

² 獲取輸出流窗口句柄

² 定義使用存儲座標結構體

² 將座標與窗口句柄傳入函數實現移動光標

 

3.8. 幫助系統模塊:

² 提示玩家一些按鍵控制和遊戲規則

 

3.9. 退出系統模塊:

² 遊戲通關或遊戲結束時給予退出或重玩選擇

 

 

 

4. 概要設計

4.1. 系統功能框架圖

 

 

1 系統功能模塊圖

4.2. 各功能模塊描述:

4.3. 頁面菜單模塊:

² 開始遊戲

² 退出遊戲

4.4. 初始化地圖模塊:

² 實現貪吃蛇存在範圍(這裏用圍牆來限定區域)

² 初始化貪吃蛇(3單位身體長度)

² 初始化食物

4.5. 食物更新模塊:

² 在區域內隨機刷新食物

² 食物不與蛇身體重合

4.6. 移動貪吃蛇模塊:

² 根據玩家按鍵移動貪吃蛇(w,s,a,d)

² Space 空格可暫停或繼續遊戲

² 當貪吃蛇前進時按相反方向移動無效

² 除了程序控制鍵以外的其餘按鍵不會影響貪吃蛇

² 移動貪吃蛇時不會形成屏幕閃爍BUG

4.7. 貪吃蛇生命模塊:

² 當蛇吃到本身身體或者觸碰圍牆時蛇死亡

4.8. 獲取貪吃蛇速度模塊:

² 根據蛇的身體長度來設置速度等級

² 當身體長度足夠長時則通關遊戲

 

4.9. 移動光標模塊:

² 獲取輸出流窗口句柄

² 定義使用存儲座標結構體

² 將座標與窗口句柄傳入函數實現移動光標

 

4.10. 幫助系統模塊:

² 提示玩家一些按鍵控制和遊戲規則

 

4.11. 退出系統模塊:

² 遊戲通關或遊戲結束時給予退出或重玩選擇

 

5. 詳細設計

  1. 思想:一條蛇能夠當作由許多正方形的「小格子」拼湊成,稱做節。節是蛇身上最小的單位。經過移動窗口光標來打印蛇。
  2. 參考資料:《徐飛機博客園》,網上資料,《c語言程序設計》,《windows程序設計》
  3. 基本設計理念:程序關鍵在於表示蛇的圖形及蛇的移動。用一個@字符表示蛇的一節身體,身體每長一節,在身體最後增長一個@。移動時必須從蛇頭開始,因此蛇不能向相反的方向移動,若是不按任意鍵,蛇自行在當前方向上前移,但按下有效方向鍵後,蛇頭朝着該方向移動,一步移動一節身體,因此按下有效方向鍵後,先肯定蛇頭的位置,然後蛇的身體隨蛇頭移動,圖形的實現是吃到食物就在下一個座標信息加一個@ 沒吃到食物就將尾巴置空,蛇頭前在加一個@,蛇的XY數組長度爲保存蛇每一個節點信息食物的出現是先肯定一組隨機數,再填充方格,食物的消失是因爲被蛇身體覆蓋,當吃掉食物後就再也不重畫本次食物,而是生成一組新的隨機數,畫新的食物當蛇頭的位置座標和圍牆的座標或者本身身體的某個節點的座標相同時,蛇就死掉了,遊戲結束。
  4. 代碼模塊示意:

//Initialization map

void initMap(void);

 

//updataFood

void updataFood(void);

 

//moveSnake

void moveSnake(void);

 

//Judge whether the snake is alive or not

int isAlive(void);

 

//get snake speed

void getSpeed(void);

 

//move cursor

void gotoxy(int x, int y);

 

//Right interface

void printFont(int x, int y, int speed);

 

//menu

int menu();

5.1. 各功能模塊的具體實現算法——流程圖

5.1.1. 主控main函數流程圖

 

 

 

2 主控main函數流程圖

5.2. 重點設計描述

Gotoxy();函數來實現打印貪吃蛇整個程序的光標移動,在裏面咱們首先獲取到輸出流緩衝區的窗口句柄,而後在根據結構體存儲X,Y座標信息來實現整個窗口的光標移動

  控制蛇的移動模塊moveSnake();這裏在下根據grow值來判斷是否吃到食物,並實現打印貪吃蛇的移動,貪吃蛇的移動只打印頭部和尾部,這樣防止了每次刷新頁面形成的閃爍。當grow爲0的時候表明沒有吃到食物,先移動光標到蛇尾將蛇尾置空,而後根據位置信息在蛇頭前加一個節點@,表明這個蛇往前移動了一個節點單位。當grow爲1時則不對尾部進行操做,直接根據XY數組信息進行添加一個@節點表明蛇的移動。

另外在移動蛇裏我加了一些判斷限制,避免了除系統指定按鍵以外按鍵的干擾致使程序提早終止,也加了一些過濾判斷,好比當蛇向上移動時,不能直接向下移動。

當按空格鍵的時候能夠實現貪吃蛇遊戲的暫停和繼續。

 

6. 系統測試與調試

在調試貪吃蛇的過程當中主要出現如下幾個BUG

第一:一開始調試時連續快速的按某個方向鍵會使程序崩潰(緣由是程序內部沒有進行過濾操做),此問題已經解決。

第二:當貪吃蛇向上移動時,按下方向鍵程序奔潰遊戲結束(緣由是無過濾操做),此問題已解決。

第三:貪吃蛇在移動的時候窗口會不斷閃爍,影響遊戲體驗(緣由是每次都打印一條蛇,致使整個窗口刷新),此問題已解決。

第四:有時蛇的長度會本身增長(緣由食物出現與身體重合),此問題已經解決。

第五:主main函數文件調用其餘文件變量時沒法調用(緣由沒有用extern進行轉置跨文件調用)

7. 課程設計心得體會

經過此次課程設計,我對c語言又有了更深入的認識。也有了更深一步的喜好,決定必定要努力學好c語言,並能更好的應用於之後的學習工做中。 
此次貪吃蛇的設計,作的不是很完美,也沒想象中的那麼好,但也得到了許多寶貴的經驗:

1) 在設計程序以前,務必要對本身所要設計的題目和內容有一個系統的,大概的瞭解,知道所設計的題目和內容包含哪些資源。 
2) 設計程序採用什麼編程語言並非很是重要,關鍵是要有一個清晰的思路和一個完整的軟件流程圖,全部要先把設計原理與思路搞清楚,再把流程圖畫出來,這樣設計起來就簡單多了。

 

參考資料

[1] Windows程序設計

[2] c語言程序設計

 

 

如有興趣交流分享技術,可關注本人公衆號,裏面會不按期的分享各類編程教程,和共享源碼,諸如研究分享關於c/c++,python,前端,後端,opencv,halcon,opengl,機器學習深度學習之類有關於基礎編程,圖像處理和機器視覺開發的知識

相關文章
相關標籤/搜索