マインスイーパ
序文
以前に 2 次元配列に基づいたバックギャモンのミニゲームを作成しましたが、今度は別のミニゲーム、マインスイーパ (レベル 9) を完了できるようになりました。
一般的な考え方は次のとおりです。
1. まずメニュー オプションを作成し、ゲームに参加するには「1」を選択し、ゲームを終了するには「0」を選択します。 2.
2 つの同一のボード ( 1 つは自分用、もう 1 つはショー用)を初期化します(両方のボードには 11 行 11 列があります)。 ; 地雷ボードは地雷に関連するボードで、地雷のある位置は「1」に初期化され、地雷のない位置は「0」に初期化され、プレイヤーは表示されません。ショー ボードはプリント ボードに属し、最初はすべて地雷除去プロセス中に印刷されるショーボード上の数字は、ポイント周囲の地雷の総数を示します。
3. 鉱山ボード上に鉱山を配置し、srand 関数で乱数を取得し、(x = rand() % row + 1 ; y = rand() %col + 1) を使用して9 つの鉱山配置位置を生成し、配置します。鉱山ボードの中央の 9 行 9 列にあります(11 行 11 列のチェス盤は初期化されませんか? 現時点で 9 行 9 列を選択する理由は、より適切な計算があるためです)地雷を確認する際はボードの境界線を越えてください。そうでない場合は、立ち入り禁止の可能性があります。 )
4. 機雷の配置が完了すると、掃海ステージが開始され、安全なポイントが選択されるたびに、機雷ボード上のそのポイントの周囲 8 つの位置で機雷の総数が数えられ、機雷の総数が割り当てられます。ショーボードと地雷ボードへ 対応する位置にある地雷がプレイヤーに表示され、地雷を踏むと最初のボードの地雷の分布がプレイヤーに表示されます。
1. 掃海作業の全体枠組み分析
メイン機能に入った後、まずメニュー印刷を実行し、メニューオプションに従ってゲームをプレイするか終了するかを選択します。ゲームオプションを選択した後、最初のステップは2つのチェス盤を初期化し、次のステップは地雷を配置することです。地雷除去を開始するには、もちろんチェス盤を中央に印刷する機能があります。
1.全体の枠組み構築
int main()
{
system("color 5E");
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("\t\t\t请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("\n\n\t\t\t退出成功!\n");
break;
default:
printf("\n\n\t\t\t选择错误,请重新输入!\n");
Sleep(2000);
system("cls");
}
} while (input);
return 0;
}
これには、srand 関数と time タイムスタンプ関数が含まれており、time 関数の戻り値を unsigned int 型に変換し、その後の鉱山レイアウト用に srand 関数を通じて乱数を生成します。
2. メニューの実装
void menu()
{
printf("\n\n\t\t\t-------------欢迎使用------------\n\n");
printf("\t\t\t☆☆ 扫雷 ☆☆\n\n");
printf("\t\t\t☆☆ 1.play ☆☆\n\n");
printf("\t\t\t☆☆ 0.exit ☆☆\n\n");
printf("\t\t\t---------------------------------\n\n");
}
メニューのプロンプトに従って、プレーヤーはゲームのプレイを続けるかゲームを終了するかを選択でき、1 を選択すると、プレーヤーはゲーム インターフェイスに入ります。
3. ゲームの実装
#define ROWS 11 //初始化的行列
#define COLS 11
#define ROW 9 //打印的行列
#define COL 9
#define easy_count 9 //雷的数量
1. ボードの初期化
まず、2 つのチェス盤を初期化する必要があります。地雷ボード内の地雷の分布は、プレイヤーには見えません。地雷ボードは、地雷以外の周囲の 8 か所にある地雷の数を数え、それらをショー ボードに割り当てます。印刷するプレーヤー。プレーヤーに表示されます。
char mine[ROWS][COLS] = {
0 };
char show[ROWS][COLS] = {
0 };
Init_board(mine, ROWS, COLS, '0');
Init_board(show, ROWS, COLS, '*');
void Init_board(char board[ROWS][ROWS], int rows, int cols, char s)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = s;
}
}
}
この関数は、パラメーター 's' を使用して 11 行 11 列のチェス盤を初期化し、最初のチェス盤をすべて 0 に初期化し、2 番目のチェス盤をすべて * に初期化します。
2.市松模様印刷
Display_board(show, ROW, COL);
void Display_board(char board[ROWS][COLS], int row, int col)
{
printf("\t\t-------------------------------------\n\n\t\t\t");
for (int i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("\t\t\t");
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n\t\t-------------------------------------\n\n");
}
この機能は、11 行 11 列のチェス盤の中央の 9 行 9 列を印刷することです。
3. 地雷を配置する
Set_mine(mine, ROW, COL);
void Set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = easy_count;
while (count)
{
int x = rand() % row + 1;//随机生成布置雷的位置
int y = rand() % col + 1;
if (mine[x][y] != '1')
{
mine[x][y] = '1';
count --;
}
}
}
この機能は地雷盤のみで、盤面全体に9個の地雷が配置されています。
4.掃海艇
Find_mine(mine, show, ROW, COL);
//获取mine棋盘中非雷处的周围八处有多少个雷
int get_mine_num(char mine[ROWS][COLS],int x,int y)
{
return 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] - 8 * '0';
}
//排雷
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
Display_board(show, ROW, COL);
int x, y = 0;
int win = 0;
while (win < (row*col-easy_count))//已获取非雷处的数量
{
printf("\n\t\t\t请输入选择的位置:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')//表示此处是否已经被排过 *代表还未排过
{
if (mine[x][y] != '1')//判断此处是否是雷 1代表雷
{
int num = get_mine_num(mine, x, y);
show[x][y] = num + '0';
win++;
}
else //踩中雷
{
system("cls");
printf("\n\n\t\t\t--- Game Over! ---\n");
Sleep(1000);
Display_board(mine, ROW, COL);
break;
}
}
else
{
printf("\n\n\t\t\t该坐标已被排查过,请重新选择!\n");
Sleep(1000);
}
}
else
{
printf("\n\n\t\t\t输入错误,请重新选择!\n");
Sleep(1000);
}
system("cls");
Display_board(show, ROW, COL);
}
if (win == (row*col - easy_count))//当所有的非雷处都被您找出
{
printf("\t\t\t恭喜您,排雷成功!\n");
}
printf("\t\t\t3秒后自动退出至主页面\n");
Sleep(3000);
system("cls");
}
2. ソースコード表示
1.test.c
#include "game.h"
void menu()
{
printf("\n\n\t\t\t-------------欢迎使用------------\n\n");
printf("\t\t\t☆☆ 扫雷 ☆☆\n\n");
printf("\t\t\t☆☆ 1.play ☆☆\n\n");
printf("\t\t\t☆☆ 0.exit ☆☆\n\n");
printf("\t\t\t---------------------------------\n\n");
}
void game()
{
//初始化棋盘
char mine[ROWS][COLS] = {
0 };
char show[ROWS][COLS] = {
0 };
//初始化棋盘
Init_board(mine, ROWS, COLS, '0');
Init_board(show, ROWS, COLS, '*');
printf("\n\n\t\t\t2秒后进入游戏界面!\n");
Sleep(2000);
system("cls");
//打印棋盘
//Display_board(mine, ROW, COL);
//Display_board(show, ROW, COL);
//布置雷
Set_mine(mine, ROW, COL);
//Display_board(mine, ROW, COL);
//排查雷
Find_mine(mine, show, ROW, COL);
}
int main()
{
system("color 5E");
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("\t\t\t请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("\n\n\t\t\t退出成功!\n");
break;
default:
printf("\n\n\t\t\t选择错误,请重新输入!\n");
Sleep(2000);
system("cls");
}
} while (input);
return 0;
}
2.ゲーム.c
#include "game.h"
void Init_board(char board[ROWS][ROWS], int rows, int cols, char s)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
board[i][j] = s;
}
}
}
void Display_board(char board[ROWS][COLS], int row, int col)
{
printf("\t\t-------------------------------------\n\n\t\t\t");
//printf("\n\n\t\t\t");
for (int i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("\t\t\t");
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n\t\t-------------------------------------\n\n");
}
void Set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = easy_count;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] != '1')
{
mine[x][y] = '1';
count --;
}
}
}
int get_mine_num(char mine[ROWS][COLS],int x,int y)
{
return 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] - 8 * '0';
}
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
Display_board(show, ROW, COL);
int x, y = 0;
int win = 0;
while (win < (row*col-easy_count))
{
printf("\n\t\t\t请输入选择的位置:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')
{
if (mine[x][y] != '1')
{
int num = get_mine_num(mine, x, y);
show[x][y] = num + '0';
//Display_board(show, ROW, COL);
win++;
}
else
{
system("cls");
printf("\n\n\t\t\t--- Game Over! ---\n");
Sleep(1000);
Display_board(mine, ROW, COL);
break;
}
}
else
{
printf("\n\n\t\t\t该坐标已被排查过,请重新选择!\n");
Sleep(1000);
}
}
else
{
printf("\n\n\t\t\t输入错误,请重新选择!\n");
Sleep(1000);
}
system("cls");
Display_board(show, ROW, COL);
}
if (win == (row*col - easy_count))
{
printf("\t\t\t恭喜您,排雷成功!\n");
}
printf("\t\t\t3秒后自动退出至主页面\n");
Sleep(3000);
system("cls");
}
3.game.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define ROWS 11
#define COLS 11
#define ROW 9
#define COL 9
#define easy_count 9
void Init_board(char board[ROWS][ROWS], int rows, int cols, char s);
void Display_board(char board[ROWS][COLS], int row, int col);
void Set_mine(char mine[ROWS][COLS], int row, int col);
void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);