アレイ(3)-マインスイーパ
序文
次に、この記事では、マインスイーパゲームを例として、以前に学んだ知識を確認します。
1.掃海とは何ですか?
Baidu百科事典:「Minesweeper」は、1992年にリリースされた人気のパズルゲームです。ゲームの目的は、クリックされたグリッドに表示される数字に従って、最短時間ですべての非地雷グリッドを見つけることです。同時に、雷を踏まないようにします。雷を踏むと、ゲーム全体が失われます。 。
2.プログラムフレームワーク
プログラムの全体的なフレームワークは、前のセクションのフレームワークから適応させることができ、このフレームワークは一般的な形式としても使用できます。
2.1主な機能
int main()
{
int input = 0;
srand((unsigned int)time(NULL));//产生随机数
do
{
menu();//菜单提示
printf("请输入 ==> ");//输入1或0,
scanf("%d", &input);
switch (input)//根据输入选择是否玩游戏
{
case 1:
game();//玩游戏的具体实现
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择!\n");
break;
}
} while (input);
return 0;
}
2.2機能メニュー
プロンプトメニューを出力して、プレーヤーに思い出させます。1はゲームをプレイすること、0はゲームを終了することです。
void menu()
{
printf("******************************\n");
printf("********* 1. play ********\n");
printf("********* 0. exit ********\n");
printf("******************************\n");
}
2.3ファンクションゲーム
配列鉱山、文字「0」で初期化
- 地雷配列の後には10個の地雷が続き、地雷がある位置は文字「1」で表され、地雷がない位置は文字「0」のままです。
- 10の鉱山の場所はランダムに生成されます
配列show、文字'*'で初期化
- キャラクター「*」は、地雷が生成される位置をブロックして、プレイヤーがそれを見ることができないようにすることです。
- show arrayは、特定の座標周辺の地雷に関する情報をチェス盤に配置します
- 座標の周囲に地雷がある場合は、地雷の数がカウントされ、この座標に表示されます
void game()
{
printf("开始玩游戏!\n");
//扫雷游戏的实现
//mine数组是用来存放布置好的雷的信息
//就10个雷在什么位置
char mine[ROWS][COLS] = {
0 };//'0'
//show数组是用来存放排查出的雷的信息
//坐标周围有几个雷
char show[ROWS][COLS] = {
0 };//'*'
//初始化棋盘
init_board(mine, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*');
//打印棋盘
//show_board(mine, ROW, COL);//全是字符'0'
//show_board(mine, ROW, COL);//全是'*'
//布置雷
set_mine(mine, ROW, COL);//雷的数组
//show_board(mine, ROW, COL);这是显示10个雷在哪里
show_board(show, ROW, COL);//输出*暂时掩盖雷在哪里
//排查雷
find_mine(mine, show, ROW, COL);
}
2.3.2関数init_board
init_board初期化パラメータは、チェス盤全体が文字「0」と「*」を表示するようにチェス盤を初期化することです。
//初始化棋盘 参数:行数 列数 行数 列数 字符0或*
void init_board(char arr[ROWS][COLS], int rows, int cols, char set)
{
//set表示初始化传进来的字符是0 还是 *
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
arr[i][j] = set;
}
}
}
2.3.3関数show_board
show_boardはチェス盤を表示するためのもので、チェス盤内の地雷の情報と、その後の掃海中のチェス盤の特定の状態を確認できます。
//展示棋盘
void show_board(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("------------扫雷------------\n");
for (i = 0; i <= col; i++)
{
printf("%d ", i);//列号,棋盘首先打印列数
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);//行前面的数字,行号
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);//打印棋盘每个元素
}
printf("\n");
}
printf("------------扫雷------------\n");
}
2.3.4関数set_mine
関数set_mineは地雷を配置し、チェス盤の10の座標位置に地雷をランダムに生成します。
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;//布置10个雷
int x = 0;//行坐标
int y = 0;//列坐标
while (count)//直到10个雷布置完成,退出循环
{
x = rand() % row + 1;//取模是0-8,加1就是1-9
y = rand() % col + 1;
if (mine[x][y] == '0')//是空的,就放雷,否则重新随机产生坐标位置
{
mine[x][y] = '1';//布置雷
count--;
}
}
}
2.3.5関数find_mine
関数find_mineは地雷をチェックすることで、プレイヤーが地雷をクリアするたびに、最初に座標を入力し、次に座標上のキャラクターが1であるかどうかを判断します。
- 1は私のもので、ゲームは終了しました
- 1ではなく、座標の周りの8つの位置にある地雷の数を数え、それらを文字の形式で座標に表示します
//排查雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;//代表玩家排雷的次数
while (win < row*col - EASY_COUNT)//小于雷的个数,说明雷还没排完
{
printf("请输入要排查的坐标 ==> ");
scanf("%d %d", &x, &y);//玩家输入坐标
if (x >= 1 && x <= row && y >= 1 && y <= col)//在1-9的坐标范围内
{
if (mine[x][y] == '1')//确定坐标为字符'1',就是雷
{
printf("很遗憾,被炸死了\n");
show_board(mine, ROW, COL);//显示所有雷的位置
break;
}
else//不是字符1,坐标就不是雷,显示坐标周围有雷的个数
{
int count = get_mine_count(mine, x, y);//函数计算类的个数
show[x][y] = count + '0';//周围有雷的个数+'0'就转换成字符了
show_board(show, ROW, COL);//打印出来,每次扫雷后的棋盘
win++;//扫了一次雷就++
}
}
else//超过坐标范围
{
printf("坐标非法,重新输入\n");
}
}
if (win == row * col - EASY_COUNT)//扫雷次数==9*9-10 71次就结束
{
printf("恭喜你,排雷成功\n");
show_board(mine, ROW, COL);//显示雷的信息
}
}
2.3.6関数get_mine_count
関数get_mine_countは、地雷の数をカウントします。
- 文字「1」は雷があることを意味し、文字「0」はいいえを意味し、「1」-「0」は数字の1であり、1つの雷を表します
- 座標の周りの8つの座標に文字を追加します-8*'0'、結果は地雷の数であり、整数です
//统计坐标周围有雷的个数
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
//坐标周围的8个地方减去'0',再相加的个数就是类的个数
return mine[x - 1][y] +
mine[x - 1][y - 1] +
mine[x][y - 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] +
mine[x][y + 1] +
mine[x - 1][y + 1] - 8 * '0';
}
3.ヘッダーfile.h
#include <stdio.h>
#include <stdlib.h>//库函数
#include <time.h>//与系统时间相关
#define ROW 9//棋盘真实的行数
#define COL 9
#define ROWS ROW+2 //棋盘放大范围,便于棋盘边的位置遍历
#define COLS COL+2
#define EASY_COUNT 10 //10个雷的个数
//初始化
void init_board(char arr[ROWS][COLS], int rows, int cols, char set);
//打印
void show_board(char arr[ROWS][COLS], int row, int col);
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col);
4.ゲームをプレイする
実行結果を下図に示します。これは基本的にゲーム機能を満たしています。
完全なコードはgiteeにあります:
要約する
この記事では、より基本的な掃海ゲームについてのみ説明します。後でより複雑な知識を学んだ後、掃海ゲームを改善することができます。マインスイーパゲームの全体的な執筆アイデアは、スリーピースゲームを参照して実現できます。
配列に関する知識は基本的に終わり、次の記事では演算子に関する知識を学び始めます。