欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

思路

清晰的邏輯

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

在排雷的時候為了方便,我們需要將每一行每一列對應(yīng)的行數(shù),列數(shù)打印出來。

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

菜單

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

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

棋盤

1.雷盤

2.棋盤

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

兩個棋盤初始化

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

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

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

因為兩個的初始化方式不同,所以我們采用傳參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;
		}
	}

布置雷

布置的雷放置需要隨機,所以采用兩個隨機數(shù)來定位坐標。

 
//布置雷
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);//用于測試
}

排雷

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

//玩家盤
static int Get_num(char arr1[ROWS][LOWS],int x, int y)//獲得當前坐標周圍雷的個數(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;
}
//判斷是否展開,實現(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';//記錄雷的個數(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ù)排雷。

贏:當玩家將所有的非雷的區(qū)域都排查出來時,判斷為贏。(這里采用一個計數(shù)器,沒排一次雷計數(shù)器就++一下,當計數(shù)器與總的非雷的區(qū)域數(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("請輸入坐標:>");
		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("輸入錯誤!\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實現(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("選擇錯誤\n");
			break;
		}
		}
	} while (input);
 
	return 0;
}

game.c實現(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;
}
//判斷是否展開,實現(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("請輸入坐標:>");
		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("輸入錯誤!\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實現(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.每一次遞歸都會向這個條件靠攏。

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

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

停止條件:當前這個坐標是已被排查過的,就停止遞歸。

因為每一次排查都會的一個標記,所以這就是那個不斷向停止條件靠攏的過程。

//判斷是否展開,實現(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語言實現(xiàn)遞歸版掃雷游戲?qū)嵗奈恼戮徒榻B到這了,更多相關(guān)C語言遞歸版掃雷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++入門教程之引用與指針

    C++入門教程之引用與指針

    初學(xué)C++時,很容易把指針和引用的用法混在一起,下面這篇文章主要給大家介紹了關(guān)于C++入門教程之引用與指針的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • C++函數(shù)重載介紹與原理詳解

    C++函數(shù)重載介紹與原理詳解

    這篇文章主要為大家介紹了C++函數(shù)重載介紹與原理,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • C++初階之list的模擬實現(xiàn)過程詳解

    C++初階之list的模擬實現(xiàn)過程詳解

    在C++中我們經(jīng)常使用STL,那個在那些我們常用的數(shù)據(jù)結(jié)構(gòu)vector,list的背后,又是如何實現(xiàn)的呢?這篇文章主要給大家介紹了關(guān)于C++初階之list的模擬實現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • C++實現(xiàn)單詞管理系統(tǒng)

    C++實現(xiàn)單詞管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C++實現(xiàn)單詞管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 利用C語言實現(xiàn)猜數(shù)字小游戲

    利用C語言實現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細介紹了利用C語言實現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++關(guān)于類結(jié)構(gòu)體大小和構(gòu)造順序,析構(gòu)順序的測試詳解

    C++關(guān)于類結(jié)構(gòu)體大小和構(gòu)造順序,析構(gòu)順序的測試詳解

    這篇文章主要介紹了C++類結(jié)構(gòu)體大小和構(gòu)造順序,析構(gòu)順序的測試,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • C語言直接選擇排序算法詳解

    C語言直接選擇排序算法詳解

    直接選擇排序就是遍歷整個數(shù)組,每遍歷一遍的目的是找出該數(shù)組中的最大數(shù)和最小數(shù)對應(yīng)的下標,然后將最小數(shù)和數(shù)組的第一個數(shù)進行交換,最大數(shù)和數(shù)組的最后一個數(shù)進行交換,然后縮小范圍再次遍歷
    2022-08-08
  • c語言循環(huán)加數(shù)組實現(xiàn)漢諾塔問題

    c語言循環(huán)加數(shù)組實現(xiàn)漢諾塔問題

    本文主要介紹了c語言循環(huán)加數(shù)組實現(xiàn)漢諾塔問題,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++實例講解四種類型轉(zhuǎn)換的使用

    C++實例講解四種類型轉(zhuǎn)換的使用

    在C++語言中新增了四個關(guān)鍵字static_cast、const_cast、reinterpret_cast和dynamic_cast。這四個關(guān)鍵字都是用于類型轉(zhuǎn)換的,類型轉(zhuǎn)換(type cast),是高級語言的一個基本語法。它被實現(xiàn)為一個特殊的運算符,以小括號內(nèi)加上類型名來表示,接下來讓我們一起來詳細了解
    2022-06-06
  • C++實現(xiàn)字符串和整數(shù)的相互轉(zhuǎn)換

    C++實現(xiàn)字符串和整數(shù)的相互轉(zhuǎn)換

    這篇文章主要為大家詳細介紹了C++實現(xiàn)字符串和整數(shù)的相互轉(zhuǎn)換的方法,文中的示例代碼講解詳細,對我們學(xué)習(xí)C++有一定的幫助,需要的可以參考一下
    2023-01-01

最新評論