国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

探秘C語言掃雷游戲?qū)崿F(xiàn)技巧

這篇具有很好參考價值的文章主要介紹了探秘C語言掃雷游戲?qū)崿F(xiàn)技巧。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本篇博客會講解,如何使用C語言實(shí)現(xiàn)掃雷小游戲。
探秘C語言掃雷游戲?qū)崿F(xiàn)技巧,C語言,c語言,開發(fā)語言,算法,數(shù)組,遞歸

0.思路及準(zhǔn)備工作

  1. 使用2個二維數(shù)組mine和show,分別來存儲雷的位置信息和排查出來的雷的信息,前者隱藏,后者展示給玩家。假設(shè)盤面大小是9×9,這2個二維數(shù)組都要開大一圈,也就是大小是11×11,這是為了更加方便的數(shù)邊角上雷的個數(shù),防止越界。
  2. mine數(shù)組中用字符1表示雷,字符0表示非雷。show數(shù)組中用*表示該位置沒有被排查過,數(shù)字字符表示周圍一圈(8個位置)有幾個雷,空格表示周圍一圈沒有雷,!表示該位置被標(biāo)記了。
  3. 如果玩家排查的位置是雷,那么,游戲失敗。當(dāng)玩家把所有非雷的位置找出來后,掃雷成功。

先定義一些符號,后面會用。

// 掃雷盤面的有效區(qū)域大小
// 雷會在該區(qū)域中生成,玩家只能在該區(qū)域內(nèi)排查或者標(biāo)記雷
// 同時是實(shí)際展示的區(qū)域大小
#define ROW 9
#define COL 9

// 實(shí)際的盤面大小
// 防止掃描周圍8個坐標(biāo)時出現(xiàn)越界訪問
// 此時哪怕掃描有效區(qū)域的周圍哪怕不進(jìn)行判斷也不會越界
// 因?yàn)樽钔饷嬗幸蝗ΡWo(hù)措施
#define ROWS   (ROW + 2)
#define COLS   (COL + 2)

// 雷的個數(shù)
#define EASY_COUNT 10 // 簡單難度

2個數(shù)組分別是:

// 存儲雷的位置信息
// '1' - 雷
// '0' - 非雷
char mine[ROWS][COLS] = { 0 };

// 展示給玩家的信息
// '*' - 未排查
// '1'~'9' - 該位置已被排查,且該位置周圍有雷
// 數(shù)字字符表示周圍雷的個數(shù)
// 空格 - 該位置已被排查,且該位置周圍沒有雷
// '!' - 該位置被玩家標(biāo)記,可能是雷,也可能不是雷
// '!'所在位置并沒有被排查,不算作已排查位置
char show[ROWS][COLS] = { 0 };

1.初始化

我們分別把mine和show數(shù)組初始化成全字符0和全*??梢岳枚S數(shù)組在內(nèi)存中連續(xù)存放的特點(diǎn),使用memset函數(shù)來設(shè)置內(nèi)存中的值。

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	// board為二維數(shù)組,在內(nèi)存中連續(xù)存放
	// 使用memset把rows*cols的空間初始化為set
	memset(board, set, rows * cols * sizeof(char));
}

2.打印盤面

打印時使用2層循環(huán)來遍歷二維數(shù)組,同時把行標(biāo)和列標(biāo)都打印出來。注意打印時,只需打印中間的9×9的位置,為了區(qū)分,我用rows和cols來表示多了一圈后的行和列,用row和col表示有效的盤面大小。

void PrintBoard(char board[ROWS][COLS], int row, int col)
{
	// 打印分割行
	printf("********* 掃雷 *********\n");

	// 打印列標(biāo),0是占位的
	for (int i = 0; i <= row; ++i)
	{
		printf("%d ", i);
	}
	printf("\n");

	// 打印數(shù)據(jù),每行前面打印行標(biāo)
	for (int i = 1; i <= row; ++i)
	{
		// 打印行標(biāo)
		printf("%d ", i);
		// 打印數(shù)據(jù)
		for (int j = 1; j <= col; ++j)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}

	// 打印分割行
	printf("********* 掃雷 *********\n");
}

打印效果:
探秘C語言掃雷游戲?qū)崿F(xiàn)技巧,C語言,c語言,開發(fā)語言,算法,數(shù)組,遞歸

3.設(shè)置雷

可以使用rand函數(shù)隨機(jī)生成10個雷,注意如果該位置已經(jīng)生成雷,就重新再生成坐標(biāo),不能重復(fù)。

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	// 待放置的雷的個數(shù)
	int count = EASY_COUNT;
	// 布置雷
	while (count)
	{
		// 產(chǎn)生隨機(jī)坐標(biāo)
		int x = rand() % row + 1; // 1~row
		int y = rand() % col + 1; // 1~col
		// 該位置如果沒有布置雷,則放雷
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			--count;
		}
	}
}

4.排查雷

排查雷的邏輯就相對復(fù)雜點(diǎn)了,這里我分以下幾點(diǎn)來敘述。

  1. 使用GetMineCount函數(shù)來獲取周圍8個位置雷的個數(shù)。只需要把周圍8個坐標(biāo)的值加起來,由于都是字符’1’或字符’0’,還需要減去8個字符’0’,得到的就是字符’1’的個數(shù)。
  2. 使用如果滿足遞歸條件,就遞歸展開。展開的思路是,如果該位置沒有越界、自己不是雷、周圍沒有雷、且沒有被排查過,則遞歸展開上下左右。
  3. 使用count變量來保存待排查的位置的個數(shù),當(dāng)count減到0,則排雷成功。
  4. 玩家輸入排查的坐標(biāo)后,需要分別檢查是否合法、該位置是否被排查過、該位置是不是雷,如果檢查過后不是雷,再進(jìn)行正常的遞歸展開等。
  5. 如果玩家選擇標(biāo)記,若該位置未被排查過,可以切換標(biāo)記狀態(tài)。
// 獲取x,y坐標(biāo)周圍8個位置的雷的個數(shù)
static int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
	// 既然只有8個坐標(biāo),直接加起來就行了
	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';
}

// 我也不想設(shè)計(jì)這么多參數(shù),但是似乎只能這樣了,沒想到更好的辦法
// x,y為排查的坐標(biāo)
// pcount指向count,count為玩家需要排查非雷位置的個數(shù)
// 當(dāng)count減到0時,玩家掃雷成功
static void ShowMessage(char mine[ROWS][COLS], char show[ROWS][COLS],
	int row, int col, int x, int y, int* pcount)
{
	// 是否展開的判斷
	if (x >= 1 && x <= row && y >= 1 && y <= col     // 坐標(biāo)合法性判斷
		&& mine[x][y] == '0'                         // 該坐標(biāo)不是雷
		&& (show[x][y] == '*' || show[x][y] == '!')) // 該位置沒有被排查過
	{
		// 獲取周圍8個坐標(biāo)雷的個數(shù)
		int mineCount = GetMineCount(mine, x, y);
		// 判斷周圍有沒有雷
		if (mineCount == 0) // 周圍沒有雷
		{
			show[x][y] = ' ';
			*pcount = *pcount - 1;
			// 遞歸展開
			ShowMessage(mine, show, row, col, x - 1, y, pcount); // 上
			ShowMessage(mine, show, row, col, x + 1, y, pcount); // 下
			ShowMessage(mine, show, row, col, x, y - 1, pcount); // 左
			ShowMessage(mine, show, row, col, x, y + 1, pcount); // 右
		}
		else // 周圍有雷
		{
			show[x][y] = mineCount + '0';
			*pcount = *pcount - 1;
		}
	}
}

// 若該位置未被排查,切換標(biāo)記狀態(tài)
// 若標(biāo)記,則取消標(biāo)記
// 若未標(biāo)記,則標(biāo)記
static void SignMine(char show[ROWS][COLS], int x, int y)
{
	if (show[x][y] == '!')
	{
		// 取消標(biāo)記
		show[x][y] = '*';
	}
	else if (show[x][y] == '*')
	{
		// 標(biāo)記
		show[x][y] = '!';
	}
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	// 坐標(biāo)
	int x = 0;
	int y = 0;
	// 存儲玩家輸入的數(shù)據(jù)
	int input = 0;
	// 玩家需要排查的位置總數(shù),即非雷的位置總數(shù)
	// 當(dāng)count減到0時,玩家掃雷成功
	int count = row * col - EASY_COUNT;

	while (count)
	{
		// 玩家輸入坐標(biāo)
		printf("請輸入坐標(biāo):>");
		scanf("%d %d", &x, &y);
		// 判斷坐標(biāo)有效性
		if (x < 0 || x > row || y < 0 || y > col)
		{
			printf("坐標(biāo)非法,請重新輸入\n");
			continue;
		}
		// 選擇排查/標(biāo)記
		while (1)
		{
			printf("你想要排查(1)還是標(biāo)記(0):>");
			scanf("%d", &input);
			// 判斷輸入有效性
			if (input == 0 || input == 1)
			{
				break;
			}
			else
			{
				printf("選擇錯誤,請重新選擇\n");
			}
		}

		if (input == 1)
		{
			// 排查
			// 檢查該坐標(biāo)是否已被排查過
			if (show[x][y] != '*' && show[x][y] != '!')
			{
				printf("該坐標(biāo)已被排查過\n");
			}
			else if (mine[x][y] == '0') // 判斷是否踩到雷
			{
				// 根據(jù)玩家排查的位置,顯示雷的信息
				ShowMessage(mine, show, row, col, x, y, &count);
				PrintBoard(show, row, col);
			}
			else // 踩到雷了
			{
				printf("你踩到雷了,掃雷失敗\n");
				break;
			}
		}
		else if (input == 0)
		{
			// 標(biāo)記
			SignMine(show, x, y);
		}
	}

	if (count == 0)
	{
		printf("恭喜你,掃雷成功!\n");
	}
}

5.測試

// 打印菜單
void menu()
{
	printf("************************\n");
	printf("****** 1. play    ******\n");
	printf("****** 0. exit    ******\n");
	printf("************************\n");
}

void game()
{
	// 存儲雷的位置信息
	// '1' - 雷
	// '0' - 非雷
	char mine[ROWS][COLS] = { 0 };

	// 展示給玩家的信息
	// '*' - 未排查
	// '1'~'9' - 該位置已被排查,且該位置周圍有雷
	// 數(shù)字字符表示周圍雷的個數(shù)
	// 空格 - 該位置已被排查,且該位置周圍沒有雷
	// '!' - 該位置被玩家標(biāo)記,可能是雷,也可能不是雷
	// '!'所在位置并沒有被排查,不算作已排查位置
	char show[ROWS][COLS] = { 0 };

	// 初始化盤面
	InitBoard(mine, ROWS, COLS, '0'); // 初始化為全'0'
	InitBoard(show, ROWS, COLS, '*'); // 初始化為全'*'

	// 隨機(jī)布置雷,只在有效區(qū)域內(nèi)
	SetMine(mine, ROW, COL);

	// 打印盤面,只打印有效區(qū)域
	//PrintBoard(mine, ROW, COL);
	PrintBoard(show, ROW, COL);

	// 玩家排查雷
	FindMine(mine, show, ROW, COL);
}

// 測試游戲的邏輯
void test()
{
	// 生成隨機(jī)數(shù)生成器起點(diǎn)
	srand((unsigned int)time(NULL));
	int input = 0; // 存儲玩家輸入的數(shù)據(jù)

	do
	{
		menu();
		printf("請選擇:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			// 游戲的邏輯
			game();
			break;
		case 0:
			printf("退出游戲\n");
			break;
		default:
			printf("選擇錯誤,重新選擇\n");
			break;
		}
	} while (input);
}

int main()
{
	test();

	return 0;
}

總結(jié)

  1. 掃雷小游戲的實(shí)現(xiàn),需要2個二維數(shù)組,需要了解二維數(shù)組的相關(guān)知識,比如在內(nèi)存中的存儲方式。
  2. 初始化盤面,利用二維數(shù)組在內(nèi)存中連續(xù)存放的特點(diǎn),使用memset一步到位。
  3. 打印盤面以及后面的一部分邏輯,遍歷二維數(shù)組時使用2層for循環(huán),是一個常見的思路。
  4. 設(shè)置雷的位置采用隨機(jī)生成的方式,需要了解C語言如何生成隨機(jī)數(shù)的知識點(diǎn),我之前寫過一篇博客講解過。
  5. 排查雷時,需要通過反復(fù)的判斷語句,防止玩家輸入的坐標(biāo)不滿足需求。
  6. 尤其需要重點(diǎn)理解遞歸的思路,遞歸有限制條件,如該位置不是雷、周圍沒有雷、該位置沒有越界、該位置沒有被排查過等,同時不斷趨近于限制條件,遞歸上下左右時一定會接近邊界。
  7. 動手寫!

感謝大家的閱讀!文章來源地址http://www.zghlxwxcb.cn/news/detail-690938.html

到了這里,關(guān)于探秘C語言掃雷游戲?qū)崿F(xiàn)技巧的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C語言之掃雷游戲?qū)崿F(xiàn)篇

    C語言之掃雷游戲?qū)崿F(xiàn)篇

    目錄 主函數(shù)test.c 菜單函數(shù) 選擇循環(huán) 掃雷游戲?qū)崿F(xiàn)分析 整體思路? 問題1 問題2? 問題3 問題4? 游戲函數(shù)(函數(shù)調(diào)用)? 創(chuàng)建游戲盤數(shù)組mine 創(chuàng)建游戲盤數(shù)組show 初始化游戲盤數(shù)組InitBoard 展示游戲盤DisplayBoard 游戲盤置雷SetMine 游戲盤排雷FindMine test.c總代碼 頭文件函數(shù)聲明game

    2024年02月11日
    瀏覽(27)
  • 【C語言】掃雷游戲完整代碼實(shí)現(xiàn)

    【C語言】掃雷游戲完整代碼實(shí)現(xiàn)

    目錄 1.game.h 2.game.c 3.progress.c 4.運(yùn)行結(jié)果

    2024年02月21日
    瀏覽(30)
  • C語言實(shí)現(xiàn)簡單的掃雷游戲

    C語言實(shí)現(xiàn)簡單的掃雷游戲

    目錄 1 - test.c 2 - game.c 3 - game.h 代碼里的注釋感覺已經(jīng)很清楚啦,就不多講解啦 感謝各位大佬的支持?。?!

    2024年01月22日
    瀏覽(48)
  • C語言:輕松實(shí)現(xiàn)掃雷小游戲

    C語言:輕松實(shí)現(xiàn)掃雷小游戲

    目錄 一、前言 二、掃雷步驟 1.創(chuàng)建項(xiàng)目 2.設(shè)計(jì)整體框架 1.定義數(shù)組長度和雷的個數(shù) 2.game函數(shù)功能 三、頭文件game.h代碼實(shí)現(xiàn)? 四、測試文件test.c代碼實(shí)現(xiàn) 五、game函數(shù)功能實(shí)現(xiàn) 1.初始化棋盤 2.打印棋盤 ?3.布置雷 4. 獲得雷的個數(shù) ?5.排查雷 6.game函數(shù)實(shí)現(xiàn)代碼 六、總結(jié) 大家好

    2024年02月03日
    瀏覽(90)
  • 【C】C語言實(shí)現(xiàn)掃雷小游戲

    相信大家一定都玩過掃雷小游戲,今天我就帶大家來用C語言實(shí)現(xiàn)一個簡易版的掃雷小游戲。 這里我們還是需要三個文件來封裝我們的寫的代碼: test.c ----- 用于我們代碼的測試,以及游戲整體框架的實(shí)現(xiàn)。 game .c ------ 用來封裝實(shí)現(xiàn)我們游戲的相關(guān)函數(shù)。 game.h ------ 主要用來

    2024年02月11日
    瀏覽(646)
  • 【C語言實(shí)現(xiàn)掃雷小游戲——可展開一片】

    【C語言實(shí)現(xiàn)掃雷小游戲——可展開一片】

    學(xué)習(xí)完了函數(shù)和數(shù)組,讓我們做個掃雷小游戲鞏固一下所學(xué)的知識把! 使用控制臺操作 通過菜單實(shí)現(xiàn)選擇 棋盤為9×9 默認(rèn)隨機(jī)布置10個雷 排查雷 如果排查的位置不是雷,就顯示周圍有幾個雷 排查位置是雷,游戲結(jié)束,玩家失敗 把10個雷全部排除,游戲結(jié)束,玩家成功 掃雷

    2024年02月08日
    瀏覽(91)
  • C語言之掃雷小游戲的實(shí)現(xiàn)【含遞歸展開】

    C語言之掃雷小游戲的實(shí)現(xiàn)【含遞歸展開】

    掃雷游戲是1992年發(fā)行的一款大眾類益智游戲,對于許多80后、90后來說都是童年的回憶。如今三十年過去了,這款游戲依舊受到很多網(wǎng)友的喜愛,今天我們一起來模擬實(shí)現(xiàn)一下掃雷游戲。 本文所用的編譯器是VS2022 這里我們使用模塊化設(shè)計(jì),模塊化設(shè)計(jì)就是把各個模塊的代碼分

    2024年02月02日
    瀏覽(92)
  • 帶你實(shí)現(xiàn)初階掃雷小游戲—【C語言】

    帶你實(shí)現(xiàn)初階掃雷小游戲—【C語言】

    ? 目錄 1. 掃雷游戲?qū)崿F(xiàn)的思路 注意點(diǎn)1? 注意點(diǎn)2? 2. 函數(shù)實(shí)現(xiàn)掃雷功能 2.1 初始化棋盤 2.2 顯示棋盤 2.3 設(shè)置雷 2.4 排查雷 2.5 返回附近雷的個數(shù) 3.源碼 3.1 game.h 3.2 game.c? 3.3 test.c 我們這里拿9*9的棋盤(其中包含10個雷)來實(shí)現(xiàn)(這里也可以自定義棋盤大小和雷的個數(shù) 》我們這

    2024年02月05日
    瀏覽(105)
  • 【C語言】代碼實(shí)現(xiàn) 掃雷 游戲及進(jìn)階功能(初學(xué)者詳解)

    【C語言】代碼實(shí)現(xiàn) 掃雷 游戲及進(jìn)階功能(初學(xué)者詳解)

    掃雷游戲的起源可以追溯到20世紀(jì)60年代,當(dāng)時這款游戲是由IBM開發(fā)出來的。在80年代初,微軟公司將其收歸旗下,并將其作為Windows操作系統(tǒng)自帶的一款游戲。自此以后,掃雷成為了Windows用戶最喜歡的休閑游戲之一,也受到了全球范圍內(nèi)的玩家喜愛。 現(xiàn)在,我們使用C語言,來

    2024年01月20日
    瀏覽(27)
  • 【C語言】萬字教學(xué),帶你分步實(shí)現(xiàn)掃雷游戲(內(nèi)含遞歸函數(shù)解析),劍指掃雷,一篇足矣

    【C語言】萬字教學(xué),帶你分步實(shí)現(xiàn)掃雷游戲(內(nèi)含遞歸函數(shù)解析),劍指掃雷,一篇足矣

    君兮_的個人主頁 勤時當(dāng)勉勵 歲月不待人 C/C++ 游戲開發(fā) Hello,這里是君兮_,今天更新一篇關(guān)于利用C語言實(shí)現(xiàn)掃雷游戲的博客。對于初學(xué)者來說,這也是一個非常容易上手的小項(xiàng)目,看完不妨自己試試哦! 廢話不多說,我們直接開始吧! 相信很多人在小時候都玩過掃雷游戲,但

    2024年02月11日
    瀏覽(32)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包