中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

c語言怎么實現含遞歸清場版掃雷游戲

發布時間:2021-11-24 10:21:05 來源:億速云 閱讀:454 作者:iii 欄目:開發技術

這篇文章主要介紹“c語言怎么實現含遞歸清場版掃雷游戲”,在日常操作中,相信很多人在c語言怎么實現含遞歸清場版掃雷游戲問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”c語言怎么實現含遞歸清場版掃雷游戲”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    一,設計思路

    想必大家都玩過掃雷

    c語言怎么實現含遞歸清場版掃雷游戲

     這便是一個標準的掃雷,換做代碼實現,我們需要考慮以下幾點:

    1.棋盤的設計與初始化

    2.在棋盤中放入雷

    3.統計雷數

    4.如何實現“一片”的效果

    5.輸贏的判斷

    接下來我們進行具體操作。

    二.實現方式

    1.菜單的打印

    對任意一個游戲,菜單是必不可少的,也是最簡單的部分,直接上代碼

    void menu()
    {
    	printf("------------------掃雷------------------\n");
    	printf("---------------1.開始游戲---------------\n");
    	printf("---------------0.退出游戲---------------\n");
    }
    int main()
    {
    	srand((unsigned int)time(NULL));
    	int a = 0;
    	do
    	{
    		menu();
    		scanf("%d", &a);
    		if (a == 0)
    		{
    			break;
    		}
    		game();
    	} while (a);
    	return 0;
    }

    其中srand是為了求隨機值,用來布置雷

    2.game函數

    主菜單完后進入game函數,在game函數里我們就要開始主要的游戲部分,如棋盤初始化與打印等,當然這些步驟都依靠函數完成,game函數只相當于集合了一系列的游戲模塊

    void game()
    {
    	char mine[ROWS][COLS];
    	char show[ROWS][COLS];
    	initeboard(mine, ROWS, COLS, '0');
    	initeboard(show, ROWS, COLS, '*');//初始棋盤
    	displayboard(show, ROW, COL);//打印棋盤
    	mine_make(mine, ROW, COL);//設置雷
    	//displayboard(mine, ROW, COL);
    	find_mine(mine, show, ROWS, COLS);//排查雷
     
    }

    3.棋盤的初始化與打印

    可以看到,我在game函數里初始了兩個棋盤,為什么要兩個呢?

    其實,一個是為了放置了雷,一個為了展示給玩家,為什么不用一個呢,我們要在放雷處用'1',表示不放雷處用‘0',這樣計算一個坐標周圍雷的數量就會更簡單,接下來看一段代碼:

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define ROW 10
    #define COL 10
    #define ROWS ROW+2
    #define COLS COL+2

    這里我們看到定義了一個ROWS和COLS這又是為何呢?

     掃雷時當你確認一個點時,它會對此點周圍的八個點進行排查看是否有淚,當坐標位于紅線處時沒有無法判斷八個,因此有了ROWS與COLS,這時,有人就會問了:那埋雷的地方用ROW COL就可以了,還不用擔心雷跑到外邊我們加的框,想法很好,但我們有兩個棋盤,必須對應,而且也不存在跑出雷的情況,往下分析你就會知道

    void initeboard(char board[ROWS][COLS], int cols, int rows,char s)//棋盤初始化,此處用了個節省步驟的方法,不用兩個棋盤依次初始化
    {
    	int i = 0;
    	int j = 0;
    	for (i = 0; i < rows; i++)
    	{
    		for (j = 0; j < cols; j++)
    		{
    			board[i][j] = s;
    		}
    	}
    }
    void displayboard(char board[ROWS][COLS], int row, int col)//棋盤打印
    {
    	int i = 0;
    	int j = 0;
    	printf(" ");//與行中打印的0%d對應
    	for (j = 0; j <=col; j++)
    	{
    		printf(" %d  ", j);
    	}
    	printf("\n");
    	printf("-");
    	for (j = 1; j <= col + 1; j++)
    	{
    		printf("---");
    		printf("|");
    	}
    	printf("\n");//列對應打印完成
    	for (i = 1; i <= row; i++)
    	{
    		if (i <= 9)
    		{
    			printf(" 0%d ", i);
    		}
    		else
    		printf(" %d ", i);
    		printf("|");
    		for (j = 1; j <= col; j++)
    		{
    			printf(" %c ", board[i][j]);
    			printf("|");
    		}
    		printf("\n");
    		printf("-");
    		for (j = 1; j <= col+1; j++)
    		{
    			printf("---");
    			printf("|");
    		}
    		printf("\n");//行對應嵌套在內部 打印的數前加0是為了讓當行數大于9時能夠對應 如09與10
    	}
    }

    棋盤的打印做了行列對應,所以可能有點不明顯

     4.雷的放置,雷的個數

    雷的放置很簡單,在棋盤‘0',處放置就行,因為我們對隨機數的算式使隨機數只會出現在0-9沒有跑出的情況

    mine_make(char mine[ROWS][COLS], int row, int col)//設置雷
    {
    	int count = 10;
    	while (count)
    	{
    		int x = rand() % 10;
    		int y = rand() % 10;
    		if (mine[x][y] == '0')
    		{
    			mine[x][y] = '1';
    			count--;
    		}
    	}
    }

    雷的個數就需要一定考慮了:

    首先,我們需要把周圍八個位置是否有雷,有多少個雷判斷出來,這時我們設計‘0' ‘1'類型就排上用場了,但是注意,這是字符,不是數字

    當然返回的數字記得轉成字符類型

    int get_mine(char mine[ROWS][COLS], int i, int j)//得到一個坐標附近雷的個數
    {
    	return mine[i - 1][j - 1] + mine[i - 1][j] + mine[i - 1][j + 1] +
    		mine[i][j - 1] + mine[i][j + 1] +
    		mine[i + 1][j - 1] + mine[i +1 ][j] + mine[i + 1][j + 1] - 8 * '0';//此處我們的數字其實是字符,用此方法可以轉為數字整形
    }

    5.遞歸實現一片效果

    當不為雷是會展開附近一片不為雷,提高游戲效率

    void spread(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)//遞歸方法實現一大片
    {
    	show[x][y] = ' ';//先讓輸入金的坐標處變為空格,因為已經判定過雷所以可以直接轉空格
    	int i = 0;
    	int j = 0;
    	int ret = 0;
    	for (i = x - 1; i <= x + 1; i++)
    	{
    		for (j = y - 1; j <= y + 1; j++)//嵌套for循環表示輸入坐標包括自生及周圍八個
    		{
    			if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1' && show[i][j] == '*')//防止出現負坐標,避免有雷,避免輸入重復
    			{
    				ret = get_mine(mine, i, j);//判斷ret是0或非0,并得出周圍雷數
    				if (!ret)//如果ret=0,!ret便是非0;為真
    				{
    					spread(show, mine, i, j);//遞歸
    				}
    				if (ret)//ret!=0時為真,便打印數
    				{
    					show[i][j] = ret + '0';//使數字轉成對應字符
    				}
    			}
     
    		}
    	}
    }

     6.排查雷

    負責判斷是否被炸死及游戲勝利

    void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//排查雷
    {
    	printf("請輸入坐標\n");
    	int i = 0;
    	int j = 0;
    	int win = 0;
    	while (row*col-10)//因為是十個雷,所以是—10,因為下總數減10就贏了,所以可以以此跳出循環,當然要是雷部位10,定一個變量就行,此處就不改了
    	{
    		scanf("%d %d", &i, &j);
    		if (mine[i][j] == '1')
    		{
    			printf("你掛了\n");
    			displayboard(mine, ROW, COL);
    			break;
    		}
    		else
    		{
    			show[i][j] = get_mine(mine, i, j)+'0';
    			spread(show,mine, i, j);
    			displayboard(show, ROW, COL);
    			win++;
    		}		
    	}
    	if (win ==row * col - 10)
    	{
    		printf("恭喜你,成功了\n");
    		displayboard(mine, ROW, COL);
    	}
    }

    具體注釋都在代碼里了

    正常情況把打印雷盤注釋就行,就可以正常游戲了

     三.完整代碼

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define ROW 10
    #define COL 10
    #define ROWS ROW+2
    #define COLS COL+2
    void menu()
    {
    	printf("------------------掃雷------------------\n");
    	printf("---------------1.開始游戲---------------\n");
    	printf("---------------0.退出游戲---------------\n");
    }
    void initeboard(char board[ROWS][COLS], int cols, int rows,char s)//棋盤初始化,此處用了個節省步驟的方法,不用兩個棋盤依次初始化
    {
    	int i = 0;
    	int j = 0;
    	for (i = 0; i < rows; i++)
    	{
    		for (j = 0; j < cols; j++)
    		{
    			board[i][j] = s;
    		}
    	}
    }
    void displayboard(char board[ROWS][COLS], int row, int col)//棋盤打印
    {
    	int i = 0;
    	int j = 0;
    	printf(" ");//與行中打印的0%d對應
    	for (j = 0; j <=col; j++)
    	{
    		printf(" %d  ", j);
    	}
    	printf("\n");
    	printf("-");
    	for (j = 1; j <= col + 1; j++)
    	{
    		printf("---");
    		printf("|");
    	}
    	printf("\n");//列對應打印完成
    	for (i = 1; i <= row; i++)
    	{
    		if (i <= 9)
    		{
    			printf(" 0%d ", i);
    		}
    		else
    		printf(" %d ", i);
    		printf("|");
    		for (j = 1; j <= col; j++)
    		{
    			printf(" %c ", board[i][j]);
    			printf("|");
    		}
    		printf("\n");
    		printf("-");
    		for (j = 1; j <= col+1; j++)
    		{
    			printf("---");
    			printf("|");
    		}
    		printf("\n");//行對應嵌套在內部 打印的數前加0是為了讓當行數大于9時能夠對應 如09與10
    	}
    }
    mine_make(char mine[ROWS][COLS], int row, int col)//設置雷
    {
    	int count = 10;
    	while (count)
    	{
    		int x = rand() % 10;
    		int y = rand() % 10;
    		if (mine[x][y] == '0')
    		{
    			mine[x][y] = '1';
    			count--;
    		}
    	}
    }
    int get_mine(char mine[ROWS][COLS], int i, int j)//得到一個坐標附近雷的個數
    {
    	return mine[i - 1][j - 1] + mine[i - 1][j] + mine[i - 1][j + 1] +
    		mine[i][j - 1] + mine[i][j + 1] +
    		mine[i + 1][j - 1] + mine[i +1 ][j] + mine[i + 1][j + 1] - 8 * '0';//此處我們的數字其實是字符,用此方法可以轉為數字整形
    }
    void spread(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)//遞歸方法實現一大片
    {
    	show[x][y] = ' ';//先讓輸入金的坐標處變為空格,因為已經判定過雷所以可以直接轉空格
    	int i = 0;
    	int j = 0;
    	int ret = 0;
    	for (i = x - 1; i <= x + 1; i++)
    	{
    		for (j = y - 1; j <= y + 1; j++)//嵌套for循環表示輸入坐標包括自生及周圍八個
    		{
    			if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != '1' && show[i][j] == '*')//防止出現負坐標,避免有雷,避免輸入重復
    			{
    				ret = get_mine(mine, i, j);//判斷ret是0或非0,并得出周圍雷數
    				if (!ret)//如果ret=0,!ret便是非0;為真
    				{
    					spread(show, mine, i, j);//遞歸
    				}
    				if (ret)//ret!=0時為真,便打印數
    				{
    					show[i][j] = ret + '0';//使數字轉成對應字符
    				}
    			}
     
    		}
    	}
    }
    void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)//排查雷
    {
    	printf("請輸入坐標\n");
    	int i = 0;
    	int j = 0;
    	int win = 0;
    	while (row*col-10)//因為是十個雷,所以是—10,因為下總數減10就贏了,所以可以以此跳出循環,當然要是雷部位10,定一個變量就行,此處就不改了
    	{
    		scanf("%d %d", &i, &j);
    		if (mine[i][j] == '1')
    		{
    			printf("你掛了\n");
    			displayboard(mine, ROW, COL);
    			break;
    		}
    		else
    		{
    			show[i][j] = get_mine(mine, i, j)+'0';
    			spread(show,mine, i, j);
    			displayboard(show, ROW, COL);
    			win++;
    		}		
    	}
    	if (win ==row * col - 10)
    	{
    		printf("恭喜你,成功了\n");
    		displayboard(mine, ROW, COL);
    	}
    }
    void game()
    {
    	char mine[ROWS][COLS];
    	char show[ROWS][COLS];
    	initeboard(mine, ROWS, COLS, '0');
    	initeboard(show, ROWS, COLS, '*');//初始棋盤
    	displayboard(show, ROW, COL);//打印棋盤
    	mine_make(mine, ROW, COL);//設置雷
    	displayboard(mine, ROW, COL);
    	find_mine(mine, show, ROWS, COLS);//排查雷
     
    }
    int main()
    {
    	srand((unsigned int)time(NULL));
    	int a = 0;
    	do
    	{
    		menu();
    		scanf("%d", &a);
    		if (a == 0)
    		{
    			break;
    		}
    		game();
    	} while (a);
    	return 0;
    }

    到此,關于“c語言怎么實現含遞歸清場版掃雷游戲”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    北碚区| 保山市| 沂水县| 商城县| 江西省| 澄城县| 那坡县| 增城市| 上杭县| 密云县| 沙洋县| 阿拉尔市| 那坡县| 吴旗县| 肥西县| 乌鲁木齐县| 乐安县| 施秉县| 浑源县| 虎林市| 靖西县| 株洲市| 红河县| 江口县| 临桂县| 都匀市| 黎平县| 三台县| 鹤山市| 阿尔山市| 读书| 囊谦县| 宜良县| 通许县| 漳浦县| 二手房| 博白县| 昌江| 常宁市| 镇赉县| 泗水县|