掃雷
- 一、問題描述
- 二、基本流程
- 三、步驟
- 1.選單界面
- 2.創建地圖
- 3.初始化地圖
- 4.列印地圖
- 5.玩家翻開坐標
- 6.判斷是否為地雷
- 7.更新地圖
- 8.判斷是否勝利
- 四、代碼實作
一、問題描述
用C語言實作簡易版掃雷,
二、基本流程
1.選單界面,
2.創建地圖 (兩個地圖),
3.初始化地圖,
4.列印地圖,
5.程式讀取玩家輸入的要翻開位置的坐標,并校驗,
6.如果不是地雷,統計當前位置周圍雷的個數, 并顯示到地圖上.,
7.判定游戲是否勝利,
三、步驟
1.選單界面
1.開始游戲 0.退出游戲
int menu(){
printf("----------------------\n");
printf("------1.開始游戲------\n");
printf("------0.退出游戲------\n");
printf("----------------------\n");
int choice = 0;
printf("請輸入你的選擇:");
scanf("%d", &choice);
return choice;
}
2.創建地圖
我們需要兩張地圖,所以要創建兩個二維陣列,
第一個二維陣列,表示玩家看到的地圖,(show)
第二個二維陣列,表示當前位置是不是地雷(1表示是地雷,0表示不是地雷),(mine)
使用宏定義的原因:
1.推高代碼可讀性,后續代碼中遇到9,方便理解含義,
2.提高擴展性,如果將來要修改棋盤尺寸,代碼修改會很方便,
#define MAX_ROW 9
#define MAX_COL 9
char show[MAX_ROW][MAX_COL] = { 0 };
char mine[MAX_ROW][MAX_COL] = { 0 };
3.初始化地圖
使用 * 表示未翻開的地,
show地圖一開始全都是 * ,
mine地圖是由0,1組成的,(1表示是地雷,0表示不是地雷)一開始都為0,隨后由電腦隨機在地圖上生成1,
這里我們使用宏定義了DIFFICULTY,表示地雷的數量:10個,
#define DIFFICULTY 10
void init(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL]){
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
show[row][col] = '*';
//初始化 mine,先全設為'0', 然后隨機生成n個'1'
mine[row][col] = '0';
}
}
int n = DIFFICULTY;
while (n>0){
// 生成雷的隨機位置
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (mine[row][col] == '1'){
// 如果當前位置已經有雷了,就直接進入下次回圈, 重新產生隨機位置
continue;
}
mine[row][col] = '1';
n--;
}
}
4.列印地圖
列印出地圖,
void printMap(char themap[MAX_ROW][MAX_COL]){
printf(" |");
for (int col = 0; col < MAX_COL; col++) {
printf("%d ", col);
}
printf("\n");
printf("--+------------------\n");
for (int row = 0; row < MAX_ROW; row++) {
printf(" %d|", row);
for (int col = 0; col < MAX_COL; col++) {
printf("%c ", themap[row][col]);
}
printf("\n");
}
}
5.玩家翻開坐標
玩家通過輸入坐標的方式翻開土地,
注意:
1.輸入坐標要在地圖范圍內,
2.不能重復翻開土地,
//程式讀取玩家輸入的要翻開位置的坐標, 并校驗
int row = 0;
int col = 0;
printf("請輸入翻開的坐標(row col):");
scanf("%d %d", &row, &col);
if (row < 0 || col < 0 || row >= MAX_ROW || col >= MAX_COL){
printf("輸入的坐標超過范圍,重新輸入:\n");
continue;
}
if (show[row][col] != '*'){
printf("已經翻開,請重新輸入:\n");
continue;
}
6.判斷是否為地雷
如果翻開的位置在mine上顯示為1,那么翻到地雷了,輸出被炸死,列印地雷地圖,讓玩家死得明白,
如果翻開的位置上在mine上不是1,那么繼續下一步驟,
if (mine[row][col] == '1'){
printf("你已經被炸死了!!!\n");
printMap(mine);
break;
}
7.更新地圖
計算周圍的地雷數量,在翻開位置顯示,
updateShow(show,mine,row,col);
// 根據當前 row, col 的位置, 計算出當前位置周圍有幾個雷
// 并且更新顯示到 show 中
void updateShow(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL], int row, int col){
int count = 0;
for (int r = row - 1; r <= row + 1; r++) {
for (int c = col - 1; c <= col + 1; c++) {
if (r < 0 || r >= MAX_ROW
|| c < 0 || c >= MAX_COL) {
continue;
}
if (mine[r][c] == '1') {
count++;
}
}
}
//此時 count 里面就已經存好了 row, col 周圍 八個格子 的雷的個數
// 把這個結果寫到 show 中即可.
// 需要把數字 count 轉成對應的字符
show[row][col] = count + '0';
}
8.判斷是否勝利
定義一個變數safe,表示翻開的不是地雷的土地,每次更新地圖后,safe加一,如果最后翻開的不是地雷的土地等于地圖的大小減地雷數,那么排除所有地雷,確認安全,
//記錄翻開的格子的個數
int safe = 0;
updateShow(show,mine,row,col);
safe++;
if (safe == MAX_ROW*MAX_COL - DIFFICULTY){
printf("已經排除所有的雷,你已經安全!!!\n");
printMap(mine);
break;
}
四、代碼實作
#define _CRT_SECURE_NO_WARNINGS
#define MAX_ROW 9
#define MAX_COL 9
#define DIFFICULTY 10
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int menu(){
printf("----------------------\n");
printf("------1.開始游戲------\n");
printf("------0.退出游戲------\n");
printf("----------------------\n");
int choice = 0;
printf("請輸入你的選擇:");
scanf("%d", &choice);
return choice;
}
void init(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL]){
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
show[row][col] = '*';
mine[row][col] = '0';
}
}
int n = DIFFICULTY;
while (n>0){
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (mine[row][col] == '1'){
continue;
}
mine[row][col] = '1';
n--;
}
}
void printMap(char themap[MAX_ROW][MAX_COL]){
printf(" |");
for (int col = 0; col < MAX_COL; col++) {
printf("%d ", col);
}
printf("\n");
printf("--+------------------\n");
for (int row = 0; row < MAX_ROW; row++) {
printf(" %d|", row);
for (int col = 0; col < MAX_COL; col++) {
printf("%c ", themap[row][col]);
}
printf("\n");
}
}
void updateShow(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL], int row, int col){
int count = 0;
for (int r = row - 1; r <= row + 1; r++) {
for (int c = col - 1; c <= col + 1; c++) {
if (r < 0 || r >= MAX_ROW
|| c < 0 || c >= MAX_COL) {
continue;
}
if (mine[r][c] == '1') {
count++;
}
}
}
show[row][col] = count + '0';
}
void game(){
char show[MAX_ROW][MAX_COL] = { 0 };
char mine[MAX_ROW][MAX_COL] = { 0 };
init(show, mine);
int safe = 0;
while (1){
printMap(show);
int row = 0;
int col = 0;
printf("請輸入翻開的坐標(row col):");
scanf("%d %d", &row, &col);
if (row < 0 || col < 0 || row >= MAX_ROW || col >= MAX_COL){
printf("輸入的坐標超過范圍,重新輸入:\n");
continue;
}
if (show[row][col] != '*'){
printf("已經翻開,請重新輸入:\n");
continue;
}
if (mine[row][col] == '1'){
printf("你已經被炸死了!!!\n");
// 列印一遍地雷的地圖, 讓玩家死的明白
printMap(mine);
break;
}
updateShow(show, mine, row, col);
safe++;
if (safe == MAX_ROW*MAX_COL - DIFFICULTY){
printf("已經排除所有的雷,你已經安全!!!\n");
// 列印一遍地雷的地圖, 讓玩家知道雷在哪
printMap(mine);
break;
}
}
}
int main()
{
srand((unsigned int)time(0));
while (1){
int choice = menu();
if (choice == 1){
game();
}
else if (choice == 0){
printf("退出游戲,byebye!");
break;
}
else{
printf("輸入錯誤,請重新輸入:");
continue;
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/200123.html
標籤:python
下一篇:趙大超的學習周志(一)
