c語言寫掃雷新手詳解
- 一、用到的知識點
- 1、分支陳述句
- 2、回圈陳述句
- 3、二維陣列
- 4、最好分塊,使代碼的功能更加獨立,思維邏輯更加清楚,此程式我寫了:test.c用來存放我的主函式,game.h用來定義和宣告函式,還有放置頭檔案,然后定義了game.c來實作函式
- 二、思緒和代碼
- 1、想要做出這個游戲,最起碼有一個選單讓人選擇是否開始游戲,因此我們需要先寫出一個選單程式,最簡單的選單資料如下:
- 2、當我們有選單了,我們現在就可以開始選擇是否進行游戲了,也就可以開始書寫我們的主函式了,寫的時候需要考慮到玩家可能想玩不止一次,因此我們需要用到回圈,因為最起碼要玩一次,所以這里建議使用do while陳述句,并且要考慮到玩家可能選擇錯誤,沒有選擇到play和exit,這里建議將switch陳述句嵌套進do while陳述句里面,下面實作代碼:
- 3、當我們的選單框架做出來以后,現在開始填充游戲內容,用函式game(),這里面寫選擇進入游戲后的操作,運用函式進行分塊,可以使你的代碼更有邏輯,建議運用,下面將詳細解說如何思考和書寫這個game()函式:
- (1)我們想要實作一個比較簡單的9*9的掃雷,最起碼我們需要棋盤,可以進行放雷和掃雷,因為需要兩個功能,這里我們盡量讓他們的功能獨立起來,因此定義兩個二維陣列,并且我們需要考慮到,如果掃雷的時候,我們需要排查最邊上的格子,如果直接進行排查,將會發生越界,因為你只定義了9\*9,其實排查邊上的格子的時候你已經掃描到了11\*11大小的格子,因此定義的時候,我們最好定義一個11\*11的棋盤,但是我們只列印9\*9的出來,這樣就可以防止他越界,示例代碼如下:
- (2)現在兩個二維陣列已經構造好了,我們需要對其進行初始化,使得我們可以更好地列印掃雷的棋盤,這里在初始化放雷棋盤的時候,將其初始化為字符'0',這里需要注意,此處是個伏筆,為了方便后面的排雷程式,初始化代碼如下:
- (3)現在我們需要將我們設計好的棋盤列印出來,注意,我們設計了11\*11的,但是我們只列印9\*9的,在列印的時候,我們還可以順便檢查一下,我們的放雷陣列是否初始化成功,代碼如下:
- (4)現在棋盤列印好了,我們需要開始給里面放置雷,為了不把代碼寫死,一會雷的數量,我們會通過#define來實作,在放置雷的時候我們還要考慮到此處是否已經有雷,還有雷的位置需要有隨機性,這里用到了rand(),srand(),time(),因此一會需要書寫頭檔案,代碼如下:
- (5)現在棋盤有了,雷也放置好了,可以開始進行掃雷了,掃雷的時候先要判斷這個位置是否已經被掃過了,如果掃過,重新掃,如果沒有掃過,我們需要開始判斷,這個地方是不是雷,如果是雷的話,玩家炸死,游戲結束,如果不是雷的話,則需要判斷,以這個位置為中心的九宮格里面有幾個雷,并且將雷的數量顯示出來,這里就用到剛才初始化雷盤'0'和定義雷為'1'伏筆的時候了,'0'的ASCII數為48,'1'的ASCII數為49,九宮格周圍的八個字符加起來再減去'0'\*8,則能得到這個九宮格有幾個雷,得到的是整形數字,想要將其轉化為字符的話,加上'0',然后將其列印出來,這里用到了一些ASCII的一些知識,代碼如下:
- 三、代碼完整示例如下
- 四、優化
一、用到的知識點
1、分支陳述句
其中主要應用了if else陳述句
2、回圈陳述句
回圈需要do while 陳述句和for()陳述句還有while陳述句
3、二維陣列
二維陣列在定義的時候,行可以為不寫為空,但是列必須要寫,例如arr[][5]={0}
4、最好分塊,使代碼的功能更加獨立,思維邏輯更加清楚,此程式我寫了:test.c用來存放我的主函式,game.h用來定義和宣告函式,還有放置頭檔案,然后定義了game.c來實作函式
二、思緒和代碼
1、想要做出這個游戲,最起碼有一個選單讓人選擇是否開始游戲,因此我們需要先寫出一個選單程式,最簡單的選單資料如下:
//頭檔案放入game.h里面
#include<stdio.h>
//主體部分放入test.c
void menu()
{
printf("*********************************\n");
printf("******* 1. play ********\n");
printf("******* 0. exit ********\n");
printf("*********************************\n");
}
2、當我們有選單了,我們現在就可以開始選擇是否進行游戲了,也就可以開始書寫我們的主函式了,寫的時候需要考慮到玩家可能想玩不止一次,因此我們需要用到回圈,因為最起碼要玩一次,所以這里建議使用do while陳述句,并且要考慮到玩家可能選擇錯誤,沒有選擇到play和exit,這里建議將switch陳述句嵌套進do while陳述句里面,下面實作代碼:
//放入test.c里面
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("請做出你的選擇:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戲!\n");
break;
default:
printf("輸入錯誤,請重新輸入!\n");
break;
}
} while (input);
return 0;
}
3、當我們的選單框架做出來以后,現在開始填充游戲內容,用函式game(),這里面寫選擇進入游戲后的操作,運用函式進行分塊,可以使你的代碼更有邏輯,建議運用,下面將詳細解說如何思考和書寫這個game()函式:
//放入test.c里面
void game()
{
//這里進行函式的填充
}
(1)我們想要實作一個比較簡單的9*9的掃雷,最起碼我們需要棋盤,可以進行放雷和掃雷,因為需要兩個功能,這里我們盡量讓他們的功能獨立起來,因此定義兩個二維陣列,并且我們需要考慮到,如果掃雷的時候,我們需要排查最邊上的格子,如果直接進行排查,將會發生越界,因為你只定義了9*9,其實排查邊上的格子的時候你已經掃描到了11*11大小的格子,因此定義的時候,我們最好定義一個11*11的棋盤,但是我們只列印9*9的出來,這樣就可以防止他越界,示例代碼如下:
//這樣將其全部定義出來,如果以后想要修改大小的話,可以直接在此處修改
//放入game.h里面
#define ROW 11
#define COL 11
#define ROWS ROW-2
#define COLS COL-2
//填充game()函式
放入test.c里面
void game()
{
char mine[ROW][COL] = { 0 };//定義放置雷的二維陣列
char show[ROW][COL] = { 0 };//定義進行掃雷的二維陣列
}
(2)現在兩個二維陣列已經構造好了,我們需要對其進行初始化,使得我們可以更好地列印掃雷的棋盤,這里在初始化放雷棋盤的時候,將其初始化為字符’0’,這里需要注意,此處是個伏筆,為了方便后面的排雷程式,初始化代碼如下:
//繼續對game()函式進行填充
//放入test.c里面
void game()
{
char mine[ROW][COL] = { 0 };//定義放置雷的二維陣列
char show[ROW][COL] = { 0 };//定義進行掃雷的二維陣列
Init(mine, ROW, COL, '0');//初始化雷陣列,令其全部為字符‘0’,令其為‘0’,方便一會統計雷數
Init(show, ROW, COL, '*');//初始化掃雷陣列,令其全部為字符‘*’
}
//放入game.h里面
void Init(char arr[ROW][COL], int row, int col, char set);
//放入game.c里面去實作
//對雷陣列還有掃雷陣列進行初始化
void Init(char arr[ROW][COL],int row,int col,char set)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
arr[i][j] = set;
}
}
}
(3)現在我們需要將我們設計好的棋盤列印出來,注意,我們設計了11*11的,但是我們只列印9*9的,在列印的時候,我們還可以順便檢查一下,我們的放雷陣列是否初始化成功,代碼如下:
//放入test.c里面
void game()
{
char mine[ROW][COL] = { 0 };//定義放置雷的二維陣列
char show[ROW][COL] = { 0 };//定義進行掃雷的二維陣列
Init(mine, ROW, COL, '0');//初始化雷陣列,令其全部為字符‘0’,令其為‘0’,方便一會統計雷數
//Display(mine, ROWS, COLS);//列印雷的初始化看看
Init(show, ROW, COL, '*');//初始化掃雷陣列,令其全部為字符‘*’
Display(show, ROWS, COLS);//列印一下初始化的掃雷陣列
}
//放入game.h里面
void Display(char arr[ROW][COL], int row, int col);
//放入game.c里面去實作
//列印出掃雷盤
void Display(char arr[ROW][COL], int rows, int cols)
{
int i = 0;
int j = 0;
int count = 1;
int tmp = 0;
for (tmp = 0; tmp <= rows; tmp++)
printf("%d ", tmp);
printf("\n");
for (i = 1,count=1; i <= rows; i++,count++)
{
printf("%d ", count);
for (j = 1; j <= cols; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
(4)現在棋盤列印好了,我們需要開始給里面放置雷,為了不把代碼寫死,一會雷的數量,我們會通過#define來實作,在放置雷的時候我們還要考慮到此處是否已經有雷,還有雷的位置需要有隨機性,這里用到了rand(),srand(),time(),因此一會需要書寫頭檔案,代碼如下:
//放入test.c里面,繼續對game()進行填充
void game()
{
char mine[ROW][COL] = { 0 };//定義放置雷的二維陣列
char show[ROW][COL] = { 0 };//定義進行掃雷的二維陣列
Init(mine, ROW, COL, '0');//初始化雷陣列,令其全部為字符‘0’,令其為‘0’,方便一會統計雷數
//Display(mine, ROWS, COLS);//列印雷的初始化看看
Init(show, ROW, COL, '*');//初始化掃雷陣列,令其全部為字符‘*’
Display(show, ROWS, COLS);//列印一下初始化的掃雷陣列
assign(mine, ROWS, COLS);//布置雷
//Display(mine, ROWS, COLS);//可以列印雷檢測一下是否正確
}
//放入game.h里面
#include<stdlib.h>
#include<time.h>
void assign(char mine[ROW][COL], int rows, int cols);
#define easy 10
//放入game.c里面去實作
//開始給mine布置雷
void assign(char mine[ROW][COL], int rows, int cols)
{
int count = 0;
// int x = rand() % rows + 1;//不能放到外面,導致雷的位置無法更新
// int y = rand() % cols + 1;
while ( count < easy)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';//將雷定義為字符1,為了方便一會掃雷
}
else
continue;
count++;
}
}
(5)現在棋盤有了,雷也放置好了,可以開始進行掃雷了,掃雷的時候先要判斷這個位置是否已經被掃過了,如果掃過,重新掃,如果沒有掃過,我們需要開始判斷,這個地方是不是雷,如果是雷的話,玩家炸死,游戲結束,如果不是雷的話,則需要判斷,以這個位置為中心的九宮格里面有幾個雷,并且將雷的數量顯示出來,這里就用到剛才初始化雷盤’0’和定義雷為’1’伏筆的時候了,‘0’的ASCII數為48,‘1’的ASCII數為49,九宮格周圍的八個字符加起來再減去’0’*8,則能得到這個九宮格有幾個雷,得到的是整形數字,想要將其轉化為字符的話,加上’0’,然后將其列印出來,這里用到了一些ASCII的一些知識,代碼如下:
//放入test.c里面,繼續對game()進行填充
void game()
{
char mine[ROW][COL] = { 0 };//定義放置雷的二維陣列
char show[ROW][COL] = { 0 };//定義進行掃雷的二維陣列
Init(mine, ROW, COL, '0');//初始化雷陣列,令其全部為字符‘0’,令其為‘0’,方便一會統計雷數
//Display(mine, ROWS, COLS);//列印雷的初始化看看
Init(show, ROW, COL, '*');//初始化掃雷陣列,令其全部為字符‘*’
Display(show, ROWS, COLS);//列印一下初始化的掃雷陣列
assign(mine, ROWS, COLS);//布置雷
//Display(mine, ROWS, COLS);//列印雷檢測一下是否正確
check_mine(mine, show, ROWS, COLS);//開始掃雷
}
//放入game.h里面
void check_mine(char mine[ROW][COL], char[ROW][COL], int rows, int cols);
//放入game.c里面去實作
//開始掃雷
void check_mine(char mine[ROW][COL], char show[ROW][COL], int rows, int cols)
{
int x = 0;
int y = 0;
int count = 0;
while (1)
{
printf("請輸入坐標掃雷:");
scanf("%d%d", &x, &y);
if (show[x][y] == '*')
{
if (mine[x][y] == '0')
{
int num = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] +
mine[x + 1][y]+ mine[x + 1][y + 1] - '0' * 8;
show[x][y] = num + '0';
Display(show, ROWS, COLS);
count++;
}
else
{
printf("不好意思你被炸死了!\n");
Display(mine, ROWS, COLS);
break;
}
}
else
printf("此處已經排查過!請重新排查!\n");
if (count == rows*cols - easy)
{
printf("恭喜你排雷成功!\n");
Display(show, ROWS, COLS);
break;
}
}
}
三、代碼完整示例如下
//test.c里面
#include"game.h"
void menu()
{
printf("*********************************\n");
printf("******* 1. play ********\n");
printf("******* 0. exit ********\n");
printf("*********************************\n");
}
void game()
{
char mine[ROW][COL] = { 0 };//定義放置雷的二維陣列
char show[ROW][COL] = { 0 };//定義進行掃雷的二維陣列
Init(mine, ROW, COL, '0');//初始化雷陣列,令其全部為字符‘0’,令其為‘0’,方便一會統計雷數
//Display(mine, ROWS, COLS);//列印雷的初始化看看
Init(show, ROW, COL, '*');//初始化掃雷陣列,令其全部為字符‘*’
Display(show, ROWS, COLS);//列印一下初始化的掃雷陣列
assign(mine, ROWS, COLS);//布置雷
//Display(mine, ROWS, COLS);//列印雷檢測一下是否正確
check_mine(mine, show, ROWS, COLS);//開始掃雷
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("請做出你的選擇:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戲!\n");
break;
default:
printf("輸入錯誤,請重新輸入!\n");
break;
}
} while (input);
return 0;
}
//game.h里面
#include<stdio.h>
#define ROW 11
#define COL 11
#define ROWS ROW-2
#define COLS COL-2
void Init(char arr[ROW][COL], int row, int col, char set);
void Display(char arr[ROW][COL], int row, int col);
#include<stdlib.h>
#include<time.h>
void assign(char mine[ROW][COL], int rows, int cols);
#define easy 10
void check_mine(char mine[ROW][COL], char[ROW][COL], int rows, int cols);
//game.c里面
#include"game1.h"
//對雷陣列還有掃雷陣列進行初始化
void Init(char arr[ROW][COL],int row,int col,char set)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
arr[i][j] = set;
}
}
}
//列印出掃雷盤
void Display(char arr[ROW][COL], int rows, int cols)
{
int i = 0;
int j = 0;
int count = 1;
int tmp = 0;
for (tmp = 0; tmp <= rows; tmp++)
printf("%d ", tmp);
printf("\n");
for (i = 1,count=1; i <= rows; i++,count++)
{
printf("%d ", count);
for (j = 1; j <= cols; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
//開始給mine布置雷
void assign(char mine[ROW][COL], int rows, int cols)
{
int count = 0;
// int x = rand() % rows + 1;//不能放到外面,導致雷的位置無法更新
// int y = rand() % cols + 1;
while ( count < easy)
{
int x = rand() % rows + 1;
int y = rand() % cols + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
}
else
continue;
count++;
}
}
//開始掃雷
void check_mine(char mine[ROW][COL], char show[ROW][COL], int rows, int cols)
{
int x = 0;
int y = 0;
int count = 0;
while (1)
{
printf("請輸入坐標掃雷:");
scanf("%d%d", &x, &y);
if (show[x][y] == '*')
{
if (mine[x][y] == '0')
{
int num = mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] +
mine[x + 1][y]+ mine[x + 1][y + 1] - '0' * 8;
show[x][y] = num + '0';
Display(show, ROWS, COLS);
count++;
}
else
{
printf("不好意思你被炸死了!\n");
Display(mine, ROWS, COLS);
break;
}
}
else
printf("此處已經排查過!請重新排查!\n");
if (count == rows*cols - easy)
{
printf("恭喜你排雷成功!\n");
Display(show, ROWS, COLS);
break;
}
}
}
四、優化
代碼寫出來了,這是最簡單的一個掃雷,還可以進行好多優化,例如插旗,拔旗,標記之類的,希望讀者可以發散性的思考,改進,優化,相信你可以的!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/77123.html
標籤:其他
