最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言實(shí)現(xiàn)遞歸版掃雷游戲?qū)嵗?/h1>
 更新時(shí)間:2022年01月25日 10:09:46   作者:紳士·永  
大家好,本篇文章主要講的是C語言實(shí)現(xiàn)遞歸版掃雷游戲?qū)嵗?,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下

思路

清晰的邏輯

為方便將其分為三個(gè)文件:text.c(測試) game.c(函數(shù)實(shí)現(xiàn)) game.h(頭文件聲明)

在排雷的時(shí)候?yàn)榱朔奖?,我們需要將每一行每一列對?yīng)的行數(shù),列數(shù)打印出來。

#define LEI 10
#define ROW 10
#define LOW 10
 
#define ROWS ROW+2
#define LOWS LOW+2
//在定義棋盤的長寬時(shí),特意加上2,便于標(biāo)記行數(shù)列數(shù)。

菜單

打印的菜單只需要有開始游戲、退出游戲的選項(xiàng)即可

void menu()
{
	printf("*************************************\n");
	printf("************1.開始游戲***************\n");
	printf("************0.退出游戲***************\n");
	printf("*************************************\n");
 
}

棋盤

1.雷盤

2.棋盤

掃雷需要先記錄雷的信息再進(jìn)行排雷,如果使用一個(gè)棋盤太過于復(fù)雜,所以我們使用兩個(gè)棋盤,一個(gè)用于布置雷,一個(gè)用于玩家排雷。

兩個(gè)棋盤初始化

布置雷的棋盤初始化,將字符‘0’作為非雷,字符‘1’作為雷。

玩家盤將字符‘*’作為還沒有掃的地方

    board(arr1, ROWS, LOWS, '0');//雷盤
	board(arr2, ROWS, LOWS, '*');//玩家盤

因?yàn)閮蓚€(gè)的初始化方式不同,所以我們采用傳參ret初始化

//初始化棋盤
void board(char arr1[ROWS][LOWS], int rows, int lows, char ret)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < lows; j++)
		{
			arr1[i][j] = ret;
		}
	}

布置雷

布置的雷放置需要隨機(jī),所以采用兩個(gè)隨機(jī)數(shù)來定位坐標(biāo)。

 
//布置雷
void Get_lei(char arr1[ROWS][LOWS], int row, int low)
{
	int count = LEI;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % low + 1;
		if (arr1[x][y] == '0')
		{
			arr1[x][y] = '1';
			count--;
		}
	}
	//displayboard(arr1, ROW, LOW);//用于測試
}

排雷

當(dāng)我們輸入一個(gè)坐標(biāo)時(shí),我們需要知道這個(gè)坐標(biāo)周圍雷的個(gè)數(shù),定義一個(gè)Get_num函數(shù)來獲取雷個(gè)數(shù)。但此時(shí)只能獲取一個(gè)坐標(biāo)的信息,我們知道一般的掃雷,如果當(dāng)前坐標(biāo)雷的個(gè)數(shù)為0,就會展開,這個(gè)過程較為復(fù)雜,所以我們使用遞歸來實(shí)現(xiàn)

//玩家盤
static int Get_num(char arr1[ROWS][LOWS],int x, int y)//獲得當(dāng)前坐標(biāo)周圍雷的個(gè)數(shù)
{
	int count = 0;
	int i = 0;
	for (i = x - 1; i <= x + 1; i++)
	{
		int j = 0;
		for (j = y - 1; j <= y + 1; j++)
		{
			if (arr1[i][j] == '1')
			{
				count++;
			}
		}
 
	}
	return count;
}
//判斷是否展開,實(shí)現(xiàn)函數(shù)
static void Judge(char arr2[ROWS][LOWS], char arr1[ROWS][LOWS], int x, int y)
{
	if (x > 0 && x <= ROW && y > 0 && y <= LOW)
	{
		int ret = Get_num(arr1, x, y);
		if (ret != 0)
			arr2[x][y] = ret + '0';//記錄雷的個(gè)數(shù)
		//遞歸散開
		else if (arr1[x][y] != ' ')
		{
			arr2[x][y] = '0';
			arr1[x][y] = ' ';
			int i = 0;
			for (i = x - 1; i <= x + 1; i++)
			{
				int j = 0;
				for (j = y - 1; j <= y + 1; j++)
				{
					Judge(arr2, arr1, i, j);
				}
			}
		}
		else
		{
			return;
		}
	}
}

判斷輸贏

輸:即每排一次雷,檢查一下雷盤對應(yīng)的信息,如果是雷,就被炸死,如果不是,就繼續(xù)排雷。

贏:當(dāng)玩家將所有的非雷的區(qū)域都排查出來時(shí),判斷為贏。(這里采用一個(gè)計(jì)數(shù)器,沒排一次雷計(jì)數(shù)器就++一下,當(dāng)計(jì)數(shù)器與總的非雷的區(qū)域數(shù)目相同時(shí),判斷為贏)

void Out_lei(char arr2[ROWS][LOWS], int row, int low, char arr1[ROWS][LOWS])
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("請輸入坐標(biāo):>");
		scanf("%d,%d", &x, &y);
		if (x >= 1 && x <= ROW && y >= 1 && y <= LOW)
		{
			if (arr1[x][y] == '1')
			{
				arr2[x][y] = '#';
				displayboard(arr2, ROW, LOW);//排雷
				printf("遺憾你輸了\n");
				break;
			}
			else
			{
				Judge(arr2, arr1, x, y);
				displayboard(arr2, ROW, LOW);//排雷
			}
		}
		else
		{
			printf("輸入錯(cuò)誤!\n");
		}
 
		//判斷掃雷是否贏
		int i = 0, flag = 0;
		for (i = 1; i <= ROW; i++)
		{
			int j = 0;
			for (j = 1; j <= LOW; j++)
			{
				if (arr2[i][j] != '*')
				{
					flag++;
				}
			}
		}
		if (flag == ROW*LOW - LEI)
		{
			printf("你贏了!\n");
			break;
		}
	}
}

text.c實(shí)現(xiàn)

#define  _CRT_SECURE_NO_WARNINGS 1
 
#include "game.h"
//菜單
void menu()
{
	printf("*************************************\n");
	printf("************1.開始游戲***************\n");
	printf("************0.退出游戲***************\n");
	printf("*************************************\n");
 
}
 
 
void game()
{
	//初始化棋盤
	char arr1[ROWS][LOWS] = { 0 };//雷盤
	char arr2[ROWS][LOWS] = { 0 };//玩家盤
	board(arr1, ROWS, LOWS, '0');
	board(arr2, ROWS, LOWS, '*');
	//打印棋盤
	//displayboard(arr1, ROW, LOW);//布置雷
	displayboard(arr2, ROW, LOW);//排雷
	//布置雷
	Get_lei(arr1,ROW,LOW);
	//排雷
	Out_lei(arr2,ROW,LOW, arr1);
 
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("請選擇:>");
		scanf("%d",&input);
		switch (input)
		{
		case 1:
		{
			printf("掃雷\n");
			game();
			break;
		}
		case 0:
		{
			printf("退出游戲\n");
			break;
		}
		default:
		{
			printf("選擇錯(cuò)誤\n");
			break;
		}
		}
	} while (input);
 
	return 0;
}

game.c實(shí)現(xiàn)

#define  _CRT_SECURE_NO_WARNINGS 1
 
#include "game.h"
 
//初始化棋盤
void board(char arr1[ROWS][LOWS], int rows, int lows, char ret)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < lows; j++)
		{
			arr1[i][j] = ret;
		}
	}
}
 
//打印棋盤
void displayboard(char arr1[ROWS][LOWS], int row, int low)
{
	printf("<———掃雷游戲———>\n");
	int i = 0;
	for (i = 1; i <= row; i++)
	{
		int j = 0;
		if (i == 1)
		{
			for (j = 0; j <= low; j++)
			{
				printf("%2d ", j);
			}
			printf("\n");
		}
 
		for (j = 1; j <= low; j++)
		{
			if (j == 1)
			{
				printf("%2d ", i);
			}
			
			printf("%2c ", arr1[i][j]);
		}
		printf("\n");
	}
	printf("<———掃雷游戲———>\n");
 
}
 
//布置雷
void Get_lei(char arr1[ROWS][LOWS], int row, int low)
{
	int count = LEI;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % low + 1;
		if (arr1[x][y] == '0')
		{
			arr1[x][y] = '1';
			count--;
		}
	}
	//displayboard(arr1, ROW, LOW);
}
//玩家盤
static int Get_num(char arr1[ROWS][LOWS],int x, int y)
{
	int count = 0;
	int i = 0;
	for (i = x - 1; i <= x + 1; i++)
	{
		int j = 0;
		for (j = y - 1; j <= y + 1; j++)
		{
			if (arr1[i][j] == '1')
			{
				count++;
			}
		}
 
	}
	return count;
}
//判斷是否展開,實(shí)現(xiàn)函數(shù)
static void Judge(char arr2[ROWS][LOWS], char arr1[ROWS][LOWS], int x, int y)
{
	if (x > 0 && x <= ROW && y > 0 && y <= LOW)
	{
		int ret = Get_num(arr1, x, y);
		if (ret != 0)
			arr2[x][y] = ret + '0';
		//遞歸散開
		else if (arr1[x][y] != ' ')
		{
			arr2[x][y] = '0';
			arr1[x][y] = ' ';
			int i = 0;
			for (i = x - 1; i <= x + 1; i++)
			{
				int j = 0;
				for (j = y - 1; j <= y + 1; j++)
				{
					Judge(arr2, arr1, i, j);
				}
			}
		}
		else
		{
			return;
		}
	}
}
void Out_lei(char arr2[ROWS][LOWS], int row, int low, char arr1[ROWS][LOWS])
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("請輸入坐標(biāo):>");
		scanf("%d,%d", &x, &y);
		if (x >= 1 && x <= ROW && y >= 1 && y <= LOW)
		{
			if (arr1[x][y] == '1')
			{
				arr2[x][y] = '#';
				displayboard(arr2, ROW, LOW);//排雷
				printf("遺憾你輸了\n");
				break;
			}
			else
			{
				Judge(arr2, arr1, x, y);
				displayboard(arr2, ROW, LOW);//排雷
			}
		}
		else
		{
			printf("輸入錯(cuò)誤!\n");
		}
 
		//判斷掃雷是否贏
		int i = 0, flag = 0;
		for (i = 1; i <= ROW; i++)
		{
			int j = 0;
			for (j = 1; j <= LOW; j++)
			{
				if (arr2[i][j] != '*')
				{
					flag++;
				}
			}
		}
		if (flag == ROW*LOW - LEI)
		{
			printf("你贏了!\n");
			break;
		}
	}
}
 
 

game.h實(shí)現(xiàn)

#pragma once
 
#include <stdio.h>
#include <stdlib.h>
 
#define LEI 10
#define ROW 10
#define LOW 10
 
#define ROWS ROW+2
#define LOWS LOW+2
 
//初始化棋盤
void board(char arr1[ROWS][LOWS],int rows,int lows,char ret);
 
//打印棋盤
void displayboard(char arr1[ROWS][LOWS], int row, int low);
 
//布置雷
void Get_lei(char arr1[ROWS][LOWS], int row, int low);
//玩家盤
void Out_lei(char arr2[ROWS][LOWS], int row, int low, char arr1[ROWS][LOWS]);

遞歸部分詳解

遞歸條件:1.有停止的條件。2.每一次遞歸都會向這個(gè)條件靠攏。

那么這里的停止條件是什么呢?

遞歸:當(dāng)返回雷的個(gè)數(shù)為0時(shí),就符合繼續(xù)遞歸的條件,我們需要將當(dāng)前坐標(biāo)周圍的點(diǎn)全部排除。且需要將已經(jīng)排查了的坐標(biāo)做一個(gè)標(biāo)記,否則就會不停的排查下去,就會形成死遞歸。所以

停止條件:當(dāng)前這個(gè)坐標(biāo)是已被排查過的,就停止遞歸。

因?yàn)槊恳淮闻挪槎紩囊粋€(gè)標(biāo)記,所以這就是那個(gè)不斷向停止條件靠攏的過程。

//判斷是否展開,實(shí)現(xiàn)函數(shù)
static void Judge(char arr2[ROWS][LOWS], char arr1[ROWS][LOWS], int x, int y)
{
	if (x > 0 && x <= ROW && y > 0 && y <= LOW)
	{
		int ret = Get_num(arr1, x, y);
		if (ret != 0)
			arr2[x][y] = ret + '0';
		//遞歸散開
		else if (arr1[x][y] != ' ')
		{
			arr2[x][y] = '0';//玩家盤
			arr1[x][y] = ' ';//雷盤
			int i = 0;
			for (i = x - 1; i <= x + 1; i++)
			{
				int j = 0;
				for (j = y - 1; j <= y + 1; j++)
				{
					Judge(arr2, arr1, i, j);
				}
			}
		}
		else
		{
			return;
		}
	}
}

總結(jié)

到此這篇關(guān)于C語言實(shí)現(xiàn)遞歸版掃雷游戲?qū)嵗奈恼戮徒榻B到這了,更多相關(guān)C語言遞歸版掃雷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解析C++中的虛擬函數(shù)及其靜態(tài)類型和動(dòng)態(tài)類型

    解析C++中的虛擬函數(shù)及其靜態(tài)類型和動(dòng)態(tài)類型

    虛擬函數(shù)(Visual Function)亦常被成為虛函數(shù),是C++中的一個(gè)重要特性,本文我們就來解析C++中的虛擬函數(shù)及其靜態(tài)類型和動(dòng)態(tài)類型
    2016-06-06
  • opengl實(shí)現(xiàn)直線掃描算法和區(qū)域填充算法

    opengl實(shí)現(xiàn)直線掃描算法和區(qū)域填充算法

    這篇文章主要為大家詳細(xì)介紹了opengl實(shí)現(xiàn)直線掃描算法和區(qū)域填充算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言?詳解如何刪除有序數(shù)組中的重復(fù)項(xiàng)

    C語言?詳解如何刪除有序數(shù)組中的重復(fù)項(xiàng)

    數(shù)組不擅長插入(添加)和刪除元素。數(shù)組的優(yōu)點(diǎn)在于它是連續(xù)的,所以查找數(shù)據(jù)速度很快。但這也是它的一個(gè)缺點(diǎn)。正因?yàn)樗沁B續(xù)的,所以當(dāng)插入一個(gè)元素時(shí),插入點(diǎn)后所有的元素全部都要向后移;而刪除一個(gè)元素時(shí),刪除點(diǎn)后所有的元素全部都要向前移
    2022-03-03
  • 電腦開機(jī)時(shí)間的計(jì)算代碼

    電腦開機(jī)時(shí)間的計(jì)算代碼

    這幾天我琢磨著一件事,那就是怎么計(jì)算我的PC從開機(jī)到現(xiàn)在的總時(shí)間。終于,看看這個(gè)函數(shù):GetTickCount();
    2013-05-05
  • Qt通過圖片組繪制動(dòng)態(tài)圖片

    Qt通過圖片組繪制動(dòng)態(tài)圖片

    這篇文章主要為大家詳細(xì)介紹了Qt通過圖片組繪制動(dòng)態(tài)圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C語言細(xì)致講解線程同步的集中方式

    C語言細(xì)致講解線程同步的集中方式

    多線程中的線程同步可以使用,CreateThread,CreateMutex 互斥鎖實(shí)現(xiàn)線程同步,通過臨界區(qū)實(shí)現(xiàn)線程同步,Semaphore 基于信號實(shí)現(xiàn)線程同步,CreateEvent 事件對象的同步,以及線程函數(shù)傳遞單一參數(shù)與多個(gè)參數(shù)的實(shí)現(xiàn)方式
    2022-05-05
  • C++回溯算法中的全排列問題分析探討

    C++回溯算法中的全排列問題分析探討

    遞歸中遇到一個(gè)問題全排列的問題,我看見回溯特別神奇,特此記錄一下。對比一下深度優(yōu)先搜索與廣度優(yōu)先搜索,個(gè)人感覺這里的回溯像是一種遞歸樹中的深度優(yōu)先搜索的算法,他不斷構(gòu)造往下延伸的深度,使其達(dá)到完全編列
    2023-03-03
  • C++數(shù)據(jù)精度問題(對浮點(diǎn)數(shù)保存指定位小數(shù))

    C++數(shù)據(jù)精度問題(對浮點(diǎn)數(shù)保存指定位小數(shù))

    這篇文章主要介紹了對浮點(diǎn)數(shù)保存指定位小數(shù)。比如, 1.123456. 要保存1位小數(shù),,調(diào)用方法后, 保存的結(jié)果為: 1.1。 再比如,1.98765, 保存2位小數(shù)的結(jié)果為: 2.00,需要的朋友可以參考下
    2017-08-08
  • 淺析VSCode launch.json中的各種替換變量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等

    淺析VSCode launch.json中的各種替換變量的意思 ${workspaceFolder} ${file} $

    這篇文章主要介紹了VSCode launch.json中的各種替換變量的意思 ${workspaceFolder} ${file} ${fileBasename} ${fileDirname}等,非常不錯(cuò)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Qt在vs2019中使用及設(shè)置方法

    Qt在vs2019中使用及設(shè)置方法

    這篇文章主要介紹了Qt在vs2019中使用及設(shè)置方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評論

循化| 卓尼县| 阳高县| 宁乡县| 佛山市| 九寨沟县| 壤塘县| 安乡县| 滦平县| 旌德县| 思茅市| 仁布县| 清苑县| 睢宁县| 佳木斯市| 桃源县| 淅川县| 武陟县| 东兰县| 中江县| 剑阁县| 甘南县| 永和县| 河曲县| 西吉县| 永胜县| 依兰县| 深泽县| 基隆市| 琼海市| 滦南县| 浠水县| 嵊泗县| 偏关县| 南昌县| 崇礼县| 麻栗坡县| 贺州市| 扶风县| 光山县| 法库县|