原文做者: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
進一步加深、鞏固所學專業課程《C語言程序設計》的基本理論知識,理論聯繫實際,進一步培養本身綜合分析問題和解決問題的能力。掌握運用C語言獨立地編寫、調試應用程序和進行其它相關設計的技能。熟悉使用結構體與時間函數和windows窗口控制函數。
設計並實現一個貪吃蛇小遊戲,要求具備如下功能模塊:
(1) 頁面菜單模塊。
(2) 初始化地圖模塊。
(3) 食物更新模塊。
(4) 移動貪吃蛇模塊。
(5) 判斷貪吃蛇是否存活模塊。
(6) 獲取貪吃蛇速度模塊。
(7) 移動窗口光標模塊。
(8) 幫助系統模塊
(9) 退出系統模塊
² 開始遊戲
² 退出遊戲
² 實現貪吃蛇存在範圍(這裏用圍牆來限定區域)
² 初始化貪吃蛇(3單位身體長度)
² 初始化食物
² 在區域內隨機刷新食物
² 食物不與蛇身體重合
² 根據玩家按鍵移動貪吃蛇(w,s,a,d)
² Space 空格可暫停或繼續遊戲
² 當貪吃蛇前進時按相反方向移動無效
² 除了程序控制鍵以外的其餘按鍵不會影響貪吃蛇
² 移動貪吃蛇時不會形成屏幕閃爍BUG
² 當蛇吃到本身身體或者觸碰圍牆時蛇死亡
² 根據蛇的身體長度來設置速度等級
² 當身體長度足夠長時則通關遊戲
² 獲取輸出流窗口句柄
² 定義使用存儲座標結構體
² 將座標與窗口句柄傳入函數實現移動光標
² 提示玩家一些按鍵控制和遊戲規則
² 遊戲通關或遊戲結束時給予退出或重玩選擇
圖1 系統功能模塊圖
² 開始遊戲
² 退出遊戲
² 實現貪吃蛇存在範圍(這裏用圍牆來限定區域)
² 初始化貪吃蛇(3單位身體長度)
² 初始化食物
² 在區域內隨機刷新食物
² 食物不與蛇身體重合
² 根據玩家按鍵移動貪吃蛇(w,s,a,d)
² Space 空格可暫停或繼續遊戲
² 當貪吃蛇前進時按相反方向移動無效
² 除了程序控制鍵以外的其餘按鍵不會影響貪吃蛇
² 移動貪吃蛇時不會形成屏幕閃爍BUG
² 當蛇吃到本身身體或者觸碰圍牆時蛇死亡
² 根據蛇的身體長度來設置速度等級
² 當身體長度足夠長時則通關遊戲
² 獲取輸出流窗口句柄
² 定義使用存儲座標結構體
² 將座標與窗口句柄傳入函數實現移動光標
² 提示玩家一些按鍵控制和遊戲規則
² 遊戲通關或遊戲結束時給予退出或重玩選擇
//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();
圖2 主控main函數流程圖
Gotoxy();函數來實現打印貪吃蛇整個程序的光標移動,在裏面咱們首先獲取到輸出流緩衝區的窗口句柄,而後在根據結構體存儲X,Y座標信息來實現整個窗口的光標移動
控制蛇的移動模塊moveSnake();這裏在下根據grow值來判斷是否吃到食物,並實現打印貪吃蛇的移動,貪吃蛇的移動只打印頭部和尾部,這樣防止了每次刷新頁面形成的閃爍。當grow爲0的時候表明沒有吃到食物,先移動光標到蛇尾將蛇尾置空,而後根據位置信息在蛇頭前加一個節點@,表明這個蛇往前移動了一個節點單位。當grow爲1時則不對尾部進行操做,直接根據XY數組信息進行添加一個@節點表明蛇的移動。
另外在移動蛇裏我加了一些判斷限制,避免了除系統指定按鍵以外按鍵的干擾致使程序提早終止,也加了一些過濾判斷,好比當蛇向上移動時,不能直接向下移動。
當按空格鍵的時候能夠實現貪吃蛇遊戲的暫停和繼續。
在調試貪吃蛇的過程當中主要出現如下幾個BUG:
第一:一開始調試時連續快速的按某個方向鍵會使程序崩潰(緣由是程序內部沒有進行過濾操做),此問題已經解決。
第二:當貪吃蛇向上移動時,按下方向鍵程序奔潰遊戲結束(緣由是無過濾操做),此問題已解決。
第三:貪吃蛇在移動的時候窗口會不斷閃爍,影響遊戲體驗(緣由是每次都打印一條蛇,致使整個窗口刷新),此問題已解決。
第四:有時蛇的長度會本身增長(緣由食物出現與身體重合),此問題已經解決。
第五:主main函數文件調用其餘文件變量時沒法調用(緣由沒有用extern進行轉置跨文件調用)
經過此次課程設計,我對c語言又有了更深入的認識。也有了更深一步的喜好,決定必定要努力學好c語言,並能更好的應用於之後的學習工做中。
此次貪吃蛇的設計,作的不是很完美,也沒想象中的那麼好,但也得到了許多寶貴的經驗:
1) 在設計程序以前,務必要對本身所要設計的題目和內容有一個系統的,大概的瞭解,知道所設計的題目和內容包含哪些資源。
2) 設計程序採用什麼編程語言並非很是重要,關鍵是要有一個清晰的思路和一個完整的軟件流程圖,全部要先把設計原理與思路搞清楚,再把流程圖畫出來,這樣設計起來就簡單多了。
[1] 《Windows程序設計》
[2] 《c語言程序設計》
如有興趣交流分享技術,可關注本人公衆號,裏面會不按期的分享各類編程教程,和共享源碼,諸如研究分享關於c/c++,python,前端,後端,opencv,halcon,opengl,機器學習深度學習之類有關於基礎編程,圖像處理和機器視覺開發的知識