原始碼地址
https://blog.csdn.net/weixin_45906253/article/details/121237647?spm=1001.2101.3001.6650.9&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-9-121237647-blog-129464051.235^v43^pc_blog_bottom_relevance_base7&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-9-121237647-blog-129464051.235^v43^pc_blog_bottom_relevance_base7&utm_relevant_index=16
內容簡介
該程式是一款簡易的掃雷小遊戲,玩家開始遊戲後,先初始化遊戲棋盤,然後佈置雷區,接著玩家根據提示輸入座標進行排雷操作,直到排除所有非雷區域或踩到雷結束遊戲。
流程圖
如圖,該程式的不足是作為一款排雷遊戲,其內容過於單一,只有一種模式,且沒有計時功能,沒有行列顯示,使用者選擇時非常容易輸錯座標,原始碼中游戲介面比較簡單,缺少美化和互動設計,玩家體驗可能不夠好。原始碼沒有成績錄入功能,玩家一次遊玩後沒有任何資料儲存,無法讓使用者感受到每次遊玩的不同與自身的進步
二次開發
針對以上問題,我為遊戲增加了選擇難度功能,計時功能,顯示行列功能(有點沒對齊=……=),把檔案寫入檔案功能,可以為使用者提供更好的遊玩體驗
選擇難度功能,程式碼如下
點選檢視程式碼
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
cout << "請選擇: ";
cin >> input;
switch (input)
{
case 1:
cout << "選擇難度級別:" << endl;
cout << "1. 初級(10個雷,9x9棋盤)" << endl;
cout << "2. 中級(20個雷,12x12棋盤)" << endl;
cout << "3. 高階(30個雷,15x15棋盤)" << endl;
int difficulty;
cin >> difficulty;
cout << "開始遊戲" << endl;
game(difficulty);
break;
case 0:
cout << "退出遊戲" << endl;
break;
default:
cout << "選擇錯誤。請重新選擇" << endl;
break;
}
} while (input);
return 0;
}
void game(int difficulty)
{
char lay_mine[16][16]; // 存放佈雷資訊
char search_mine[16][16]; // 存放排查出雷的資訊
int size = 0;
int num_mines = 0;
if (difficulty == 1)
{
size = 9;
num_mines = 10;
}
else if (difficulty == 2)
{
size = 12;
num_mines = 20;
}
else if (difficulty == 3)
{
size = 15;
num_mines = 30;
}
initialize_mineboard(lay_mine, '0', size);
initialize_mineboard(search_mine, '*', size);
print_mineboard(search_mine, size);
set_laymine(lay_mine, num_mines);
set_searchmine(lay_mine, search_mine, size, num_mines);
}
增加了計時功能,程式碼如下
點選檢視程式碼
#include <chrono>
void set_searchmine(char lay_mine[][16], char search_mine[][16], int size, int num_mines)
{
auto start = high_resolution_clock::now();
int i = 0;
int j = 0;
int flag = 0;
while (flag < size * size - num_mines)
{
cout << "請輸入要排查的座標:" << endl;
cin >> i >> j;
if ((i >= 1 && i <= size) && (j >= 1 && j <= size))
{
if (lay_mine[i][j] == 'X')
{
cout << "很遺憾,你所輸入座標為雷區,遊戲失敗!" << endl;
print_mineboard(lay_mine, size);
break;
}
else
{
search_mine[i][j] = mine_message(lay_mine, i, j) + '0';
flag++;
print_mineboard(search_mine, size);
}
}
else
cout << "輸入座標不合法,請重新輸入" << endl;
}
auto stop = high_resolution_clock::now();
auto duration = duration_cast<seconds>(stop - start);
cout << "遊戲結束,用時:" << duration.count() << " 秒" << endl;
if (flag == size * size - num_mines)
{
cout << "恭喜你,排雷成功!" << endl;
print_mineboard(lay_mine, size);
record_score(duration.count(), true);
}
else
{
record_score(duration.count(), false);
}
}
增加成績錄入功能
點選檢視程式碼
#include<fstream>
void record_score(int time, bool success);
......
void record_score(int time, bool success)
{
ofstream myfile("scores.txt", ios::app);
if (myfile.is_open())
{
if (success)
{
myfile << "遊戲成功,用時:" << time << " 秒" << endl;
}
else
{
myfile << "遊戲失敗,用時:" << time << " 秒" << endl;
}
myfile.close();
}
else
{
cout << "無法開啟檔案" << endl;
}
}
改進後如圖:
改進後程式碼
點選檢視程式碼
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<time.h>
#include<chrono>
using namespace std;
using namespace std::chrono;
void menu();
void game(int difficulty);
void initialize_mineboard(char mine[][16], char set, int size);
void print_mineboard(char mine[][16], int size);
void set_laymine(char lay_mine[][16], int num_mines);
void set_searchmine(char lay_mine[][16], char search_mine[][16], int size, int num_mines);
int mine_message(char lay_mine[][16], int i, int j);
void record_score(int time, bool success);
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
cout << "請選擇: ";
cin >> input;
switch (input)
{
case 1:
cout << "選擇難度級別:" << endl;
cout << "1. 初級(10個雷,9x9棋盤)" << endl;
cout << "2. 中級(20個雷,12x12棋盤)" << endl;
cout << "3. 高階(30個雷,15x15棋盤)" << endl;
int difficulty;
cin >> difficulty;
cout << "開始遊戲" << endl;
game(difficulty);
break;
case 0:
cout << "退出遊戲" << endl;
break;
default:
cout << "選擇錯誤。請重新選擇" << endl;
break;
}
} while (input);
return 0;
}
void menu()
{
cout << "**********************" << endl;
cout << "****** 掃雷遊戲 ******" << endl;
cout << "******* 1.play *******" << endl;
cout << "******* 0.exit *******" << endl;
cout << "**********************" << endl;
}
void game(int difficulty)
{
char lay_mine[16][16]; // 存放佈雷資訊
char search_mine[16][16]; // 存放排查出雷的資訊
int size = 0;
int num_mines = 0;
if (difficulty == 1)
{
size = 9;
num_mines = 10;
}
else if (difficulty == 2)
{
size = 12;
num_mines = 20;
}
else if (difficulty == 3)
{
size = 15;
num_mines = 30;
}
initialize_mineboard(lay_mine, '0', size);
initialize_mineboard(search_mine, '*', size);
print_mineboard(search_mine, size);
set_laymine(lay_mine, num_mines);
set_searchmine(lay_mine, search_mine, size, num_mines);
}
void initialize_mineboard(char mine[][16], char set, int size)
{
int i = 0;
int j = 0;
for (i = 0; i <= size; i++)
for (j = 0; j <= size; j++)
mine[i][j] = set;
}
void print_mineboard(char mine[][16], int size)
{
int i = 0;
int j = 0;
cout << " ";
for (i = 1; i <= size; i++)
{
cout << " " << i;
}
cout << endl;
for (i = 1; i <= size; i++)
{
if (i < 10)
{
cout << " " << i << " ";
}
else
{
cout << i << " ";
}
for (j = 1; j <= size; j++)
cout << "----";
cout << endl;
cout << " ";
for (j = 1; j <= size; j++)
cout << "| " << mine[i][j] << " ";
cout << "|" << endl;
}
cout << " ";
for (j = 1; j <= size; j++)
cout << "----";
cout << endl;
}
void set_laymine(char lay_mine[][16], int num_mines)
{
int n = num_mines; // 佈置雷的數量
while (n)
{
int i = rand() % 15 + 1; // 隨機佈雷
int j = rand() % 15 + 1;
if (lay_mine[i][j] == '0')
{
lay_mine[i][j] = 'X'; // 雷的標誌設為‘X’
n--;
}
}
}
void set_searchmine(char lay_mine[][16], char search_mine[][16], int size, int num_mines)
{
auto start = high_resolution_clock::now();
int i = 0;
int j = 0;
int flag = 0;
while (flag < size * size - num_mines)
{
cout << "請輸入要排查的座標:" << endl;
cin >> i >> j;
if ((i >= 1 && i <= size) && (j >= 1 && j <= size))
{
if (lay_mine[i][j] == 'X')
{
cout << "很遺憾,你所輸入座標為雷區,遊戲失敗!" << endl;
print_mineboard(lay_mine, size);
break;
}
else
{
search_mine[i][j] = mine_message(lay_mine, i, j) + '0';
flag++;
print_mineboard(search_mine, size);
}
}
else
cout << "輸入座標不合法,請重新輸入" << endl;
}
auto stop = high_resolution_clock::now();
auto duration = duration_cast<seconds>(stop - start);
cout << "遊戲結束,用時:" << duration.count() << " 秒" << endl;
if (flag == size * size - num_mines)
{
cout << "恭喜你,排雷成功!" << endl;
print_mineboard(lay_mine, size);
record_score(duration.count(), true);
}
else
{
record_score(duration.count(), false);
}
}
int mine_message(char lay_mine[][16], int i, int j)//所輸入座標周圍雷的個數
{
int count = 0;
for (int x = i - 1; x <= i + 1; x++)
{
for (int y = j - 1; y <= j + 1; y++)
{
if (lay_mine[x][y] == 'X')
count++;
}
}
return count;
}
void record_score(int time, bool success)
{
ofstream myfile("scores.txt", ios::app);
if (myfile.is_open())
{
if (success)
{
myfile << "遊戲成功,用時:" << time << " 秒" << endl;
}
else
{
myfile << "遊戲失敗,用時:" << time << " 秒" << endl;
}
myfile.close();
}
else
{
cout << "無法開啟檔案" << endl;
}
}
改進後流程圖
心得
透過這次二次開發,我學習到開發小遊戲除了要完成基本功能外,還要儘可能提高使用者體驗,遊戲過於單一則遊戲壽命不會長久,要有創新思想,為遊戲增添新的功能以延長遊戲壽命,要事先調查使用者的需求,,瞭解使用者想要哪些功能,以便更好的開發遊戲,避免浪費時間做無用功。在修改程式碼時,要注意新增功能與之前的功能是否衝突,將程式碼分解為模組和函式,每個模組負責一個特定的功能,是個不錯的避免錯誤發生的方法。