数据结构课程设计------扫雷游戏(升级版,可展开)
本程序由團隊中的一個人所寫,本人看懂并寫下此文章
題目:掃雷
3.1問題描述
掃雷游戲
[基本要求]
(1)完成棋盤的初始化并在標準顯示器中顯示
(2)通過輸入行列值確定用戶輸入
(3)游戲進行給出提示信息
(4)給出游戲的測試程序。
3.2.算法設計與分析
3.2.1設計思路分析
首先定義一個二維數組的棋盤,用偽隨機數在棋盤上生成地雷。通過從鍵盤上輸入坐標,判斷此位置是不是存在地雷,存在則游戲結束,不存在則展開棋盤。展開的周圍顯示出附近存在的地雷個數。依次類推,直到找出所有地雷。
3.2.2設計程序流程圖(要求圖文并茂)
首先進入菜單,選擇開始游戲,生成棋盤與地雷,然后顯示棋盤,用戶輸入相應的位置坐標,程序進行判斷該位置是否為地雷,是的話游戲結束,不是的話則展開棋盤,繼續輸入并統計地雷個數,依次類推,直到地雷數統計完則游戲結束。
3.2.3數據結構定義
3.2.4算法的時間復雜度分析
棋盤初始化模塊的算法,對定義好的二維數組元素進行定義,時間復雜度為O(1)。
模擬棋盤初始化算法,對定義好的二維數組元素進行定義,時間復雜度為O(1)。
打印棋盤的算法,通過依次遍歷二維數組打印數據元素,時間復雜度為O(n)。
地雷生成算法,通過偽隨機數在棋盤上生成地雷,時間復雜度為O(n)。
判斷是否為地雷算法,通過數據匹配的方式進行判斷,時間復雜度為O(1)。
統計地雷個數的算法,通過數據匹配的方式進行統計,時間復雜度為O(n)。
棋盤展開算法,每次輸入坐標展開棋盤,時間復雜度為O(1)。
3.3源程序清單(帶注釋)
Game.h #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #define COUNT 10 #define ROW 9 #define CLO 9 #define ROWS 11 #define CLOS 11 void printbroad(char arr[ROW][CLO], int row, int clo); void arr_init(char arr[ROW][CLO], int row, int clo); void menu(); void arrs_randinit(char arrs[ROWS][CLOS], int row, int clo); //生成隨機雷 void arrs_init(char arrs[ROWS][CLOS], int row, int clo); void print(char arrs[ROWS][CLOS], int row, int clo); void sweep(char arrs[ROWS][CLOS], char arr[ROW][CLO], int row, int clo); //掃雷 int is_thunder(char arrs[ROWS][CLOS], char arr[ROW][CLO], int row, int clo); int count(char arrs[ROWS][CLOS], int row, int clo); //計算周圍雷的數目 void movefirst(char arrs[ROWS][CLOS], int row, int clo); void open(char arrs[ROWS][CLOS], char arr[ROW][CLO], int i, int j); Game.c #pragma warning(disable:4996) #include"game.h" int num = ROW*CLO - COUNT; void menu() {printf("****************************************\n");printf("*************** 1.play **************\n");printf("*************** 0.exit **************\n");printf("****************************************\n");} //打印掃雷棋盤 void printbroad(char arr[ROW][CLO], int row, int clo) {int i = 0;int j = 0;printf(" ");//打印掃雷棋盤的橫坐標for (i = 1; i <= row; i++){printf("%d ", i );}printf("\n");for (i = 1; i <= row; i++){printf("--");}printf("--");printf("\n");for (i = 0; i < row; i++){//打印掃雷棋盤的縱坐標printf("%d| ", i+1);for (j = 0; j < clo; j++){printf("%c ", arr[i][j]);}printf("\n");}printf("\n"); }void arr_init(char arr[ROW][CLO], int row, int clo) {//這個函數的功能是將該數組所有置*memset(&arr[0][0], '*', row*clo*sizeof(arr[0][0])); } void arrs_init(char arrs[ROWS][CLOS], int row, int clo) {memset(&arrs[0][0], '0', row*clo*sizeof(arrs[0][0])); }//生成隨機地雷,1代表地雷,0代表沒有地雷; void arrs_randinit(char arrs[ROWS][CLOS], int row, int clo) {int count = COUNT;int i = 0;int j = 0;do{//生成隨機橫縱坐標i = rand() % 9+1; //生成1~9的橫坐標j = rand() % 9+1; //生成1~9的縱坐標if (arrs[i][j] != '1') //如果此處有地雷,則繼續循環{arrs[i][j] = '1';count--;}} while (count);} void print(char arrs[ROWS][CLOS], int row, int clo) {int i = 0;int j = 0;printf(" ");for (i = 1; i < row - 1; i++){printf("%d ", i);}printf("\n");for (i = 1; i < row - 1; i++){printf("--");}printf("--");printf("\n");printf("1|");for (i = 1; i < row-1; i++){printf(" ");for (j = 1; j < clo-1; j++){printf("%c ", arrs[i][j]);}printf("\n");if (i == 9){continue;}printf("%d|", i+1);}//int i = 0;//int j = 0;//printf(" ");打印掃雷棋盤的橫坐標//for (i = 1; i <= row-2; i++)//{// printf("%d ", i);//}//printf("\n");//for (i = 1; i <= row-2; i++)//{// printf("--");//}//printf("--");//printf("\n");//for (i = 0; i < row-2; i++)//{// //打印掃雷棋盤的縱坐標// printf("%d| ", i + 1);// for (j = 0; j < clo-2; j++)// {// printf("%c ", arrs[i][j]);// }// printf("\n");//}//printf("\n"); }int is_thunder(char arrs[ROWS][CLOS],char arr[ROW][CLO], int row, int clo) {if (arrs[row][clo] == '1'){return 0;}else{return 1;} }//計算周圍一圈(8個數)有多少個地雷 int count(char arrs[ROWS][CLOS], int row, int clo) {int count = 0;return ((arrs[row - 1][clo - 1] +arrs[row - 1][clo] +arrs[row - 1][clo + 1] +arrs[row][clo - 1] +arrs[row][clo + 1] +arrs[row + 1][clo - 1] +arrs[row + 1][clo] +arrs[row + 1][clo + 1])-'0'*8);} //當玩家第一次就點到地雷時,得把地雷移走 void movefirst(char arrs[ROWS][CLOS], int row, int clo) {int x = 0;int y = 0;while (1){x = rand() % 9 + 1;y = rand() % 9 + 1;if (arrs[x][y] != '1'){arrs[x][y] = '1';break;}}arrs[row][clo] = '0'; }void sweep(char arrs[ROWS][CLOS], char arr[ROW][CLO], int row, int clo) {//判斷是否為第一次掃雷的標志位int first = 0;int x = 0;int y = 0;int flag = 1;int ret = 0;while (flag){printf("請輸入坐標>\n");scanf("%d%d", &x, &y);//如果是雷,則返回0,否則返回1;ret = is_thunder(arrs, arr, x, y);if (x >= 1 && x <= 9 && y >= 1 && y <= 9){first++;switch (ret){case 1:if (count(arrs, x, y) == 0){open(arrs, arr, x - 1, y - 1);}else {arr[x - 1][y - 1] = count(arrs, x, y) + '0';num--;}printbroad(arr, ROW, CLO);//printf("\n%d\n", num);break;case 0://如果第一次就碰到了雷,就將雷移走,提升游戲體驗if (first == 1){movefirst(arrs, x, y);if (count(arrs, x, y) == 0){open(arrs, arr, x - 1, y - 1);}else {arr[x-1][y-1] = count(arrs, x, y) + '0';num--;}printbroad(arr, ROW, CLO);break;}printf("你被炸掉了\nGAMEOVER!!!!!!!!\n");print(arrs, ROWS, CLOS);flag = 0;break;}if (0 == num){printf("游戲結束,玩家贏!!!\n");break;}}else{printf("輸入錯誤,請重新輸入:\n");}} } int right(int i, int j) {if ( (i + 1)>=1 && (i + 1)<=9 && (j + 1)>=1 &&(j + 1)<= 9 ){return 1;}return 0; }void open(char arrs[ROWS][CLOS], char arr[ROW][CLO], int i, int j) {//如果當前位置沒有地雷,而且當前位置在棋盤上沒有被顯示,則顯示出周圍一圈雷的數量;if (arrs[i+1][j+1] == '0' && arr[i][j] == '*'&&right(i,j)){arr[i][j] = count(arrs, i+1, j+1) + '0';num--;}//左一位置if (arrs[i + 1][j] == '0' && arr[i][j - 1] == '*'&&right(i, j-1)){arr[i][j-1] = count(arrs, i+1, j) + '0';num--;if (count(arrs, i+1, j) == 0){open(arrs, arr, i, j-1);}}//右一位置if (arrs[i + 1][j + 2] == '0' && arr[i][j + 1] == '*'&&right(i, j+1)){arr[i][j + 1] = count(arrs, i+1, j + 2) + '0';num--;if (count(arrs, i+1, j + 2) == 0){open(arrs, arr, i, j + 1);}}//上一位置if (arrs[i][j + 1] == '0' && arr[i - 1][j] == '*'&&right(i-1, j)){arr[i - 1][j] = count(arrs, i, j+1) + '0';num--;if (count(arrs, i, j+1) == 0){open(arrs, arr, i-1, j);}}//左上位置if (arrs[i][j] == '0' && arr[i - 1][j - 1] == '*'&&right(i-1, j-1)){arr[i - 1][j - 1] = count(arrs, i, j) + '0';num--;if (count(arrs, i, j) == 0){open(arrs, arr, i - 1, j - 1);}}//右上if (arrs[i][j + 2] == '0' && arr[i - 1][j + 1] == '*'&&right(i-1, j+1)){arr[i - 1][j + 1] = count(arrs, i, j + 2) + '0';num--;if (count(arrs, i, j + 2) == 0){open(arrs, arr, i-1, j + 1);}}//右下if (arrs[i + 2][j + 2] == '0' && arr[i + 1][j + 1] == '*'&&right(i+1, j+1)){arr[i + 1][j + 1] = count(arrs, i + 2, j + 2) + '0';num--;if (count(arrs, i + 2, j + 2) == 0){open(arrs, arr, i + 1, j + 1);}}//下if (arrs[i + 2][j + 1] == '0' && arr[i + 1][j] == '*'&&right(i+1, j)){arr[i + 1][j] = count(arrs, i + 2, j+1) + '0';num--;if (count(arrs, i + 2, j+1) == 0){open(arrs, arr, i + 1, j);}}//左下if (arrs[i + 2][j] == '0' && arr[i + 1][j - 1] == '*'&&right(i+1, j-1)){arr[i + 1][j - 1] = count(arrs, i + 2, j) + '0';num--;if (count(arrs, i + 2, j) == 0){open(arrs, arr, i + 1, j - 1);}} } Test.c #pragma warning(disable:4996) #include"game.h" void playgame() {char arr[ROW][CLO] = { 0 }; //顯示棋盤char arrs[ROWS][CLOS] = { 0 }; //真正操作的棋盤arr_init(arr, ROW, CLO);arrs_init(arrs, ROWS, CLOS);arrs_randinit(arrs, ROWS, CLOS);printbroad(arr, ROW, CLO);print(arrs, ROWS, CLOS);sweep(arrs, arr, ROW, CLO);} int main() {srand((unsigned int)time(NULL));int key = 0;do{menu();scanf("%d", &key);if (key == 1)playgame();else if (key == 0)printf("退出游戲\n");elseprintf("輸入有誤,請重新輸入:\n");} while (key);return 0; }3.4執行結果
生成棋盤與地雷
輸入坐標進行判斷
輸入坐標進行判斷
游戲結束
3.5存在問題分析
(1)沒有實現插旗的功能。
(2)不能統計以往的游戲信息,沒有實現數據保存。
(3)沒有排行榜功能。
(4)不能進行游戲難度的設定。
3.6結論
這次的掃雷程序代碼量比較大,一開始給我們小組造成了一些困難,但經過我們的查找資料,相互交流,將這些困難一一克服,其中的展開函數經過我們的不斷調試,終于將正確的參數確定。完成了這項代碼,我覺得我的代碼能力提高了很多,對問題的分析有了進一步的提升,即使出現問題,經過不斷的調試,耐心的對待,最后總會成功的。在以后的學習中更要腳踏實地,不怕困難。
總結
以上是生活随笔為你收集整理的数据结构课程设计------扫雷游戏(升级版,可展开)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都大熊猫繁育基地领养
- 下一篇: dnf女枪炮师70武器装备穿什么好?