【C言語】マインスイーパゲーム(超詳しい)


序文

以前に 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);

おすすめ

転載: blog.csdn.net/weixin_47648037/article/details/127154195