首頁 > 軟體

C語言詳細講解通過遞迴實現掃雷的展開

2022-05-19 13:00:28

使用者選擇選單

void menu()
{
	printf("****************************n");
	printf("********  1.play  **********n");
	printf("********  0.exit  **********n");
	printf("****************************n");
}

使用者按1進入遊戲

棋盤初始化

void Itnboard(char board[ROWS][COLS], int rows, int cols,char c)
{
	int i, j;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j <cols; j++)
		{
			board[i][j] = c;
		}
	}
}

建立陣列,並對其進行初始化

佈置雷(隨機佈置)

void Setboard(char board[ROWS][COLS], int row, int col)
{
	int count = Easy_count;
	while (count)
	{
		int x = rand() % row+1;
		int y = rand() % col+1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

用time函數產生隨機值

列印棋盤

void Displayboard(char board[ROWS][COLS], int row, int col)
{
	int i, j;
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
}

列印棋盤

玩家下棋

void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = 0;
	while (1)
	{
		printf("請排雷:n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
		{
			if (board[x][y] == '0')
			{
				Openboard(show, board, x, y);
				Displayboard(show, ROW, COL);
			}
			else if (board[x][y] == '1')
			{
				printf("你死了n");
				break;
			}
		}
		else
		{
			printf("請重新輸入");
		}
		int i, j;
		for (i = 1; i <= row; i++)
		{
			for (j = 1; j <= col; j++)
			{
				if (show[i][j] == '*')
				{
					count++;
				}
			}
		}
		if (count == Easy_count)
		{
			printf("成功n");   //這裡的判斷條件是遍歷整個陣列,統計雷的個數,如果雷的個數等於所剩餘未排的*,說明排雷成功
			break;
		}
	}
}

使用者輸入值,並進行判斷,如果該位置沒有雷,我們進入展開函數

棋盤展開

void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col)
{
	if (row >= 1 && row <= ROW && col >= 1 && col <= COL)
	{
		int count=sum(board, row, col);
		if (count != 0)
		{
			show[row][col] = count + '0';
		}
		else if (show[row][col] != '_')
		{
			show[row][col] = '_';
			int i = 0, j = 0;
			for (i = row - 1; i <= row + 1; i++)
			{
				for (j = col - 1; j <= col + 1; j++)
				{
					Openboard(show, board, i,j);
				}
			}
		}
		else
		{
			return;
		}
	}
}

如果使用者輸入的這個位置沒有雷,我們對其周圍8個位置進行判斷是否有雷,若有雷,我們把雷的個數顯示在該位置上,若其周圍8個位置沒有雷並且不是下劃線,我們把這個位置賦值為下劃線,然後並對其8個位置進行同樣的判斷,如果周圍沒雷,而且周圍的棋子也不是下劃線,我們對其進行返回。

展開部分思維導圖

展開函數最後一個else return 作用

這裡我們show棋盤有三種情況,

1.該位置是*

2.該位置是下劃線

3.該位置是雷的個數

else

return;

這裡是作用:如果是下劃線,我們就返回上一層函數。因為如果這裡不是下劃線,我們會在else return 之前的語句中進行判斷,並對其周圍8個位置進行操作,然後再對這8個棋子各個周圍8個位置進行判斷並操作,如果這裡是下劃線,就說明由這個位置為中心的周圍8個棋子已經判斷過了,並且以這8個位置為中心,已經遞迴過了,我們不需要再進行判斷,所以直接返回就行

周圍雷個數判斷

int sum(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y - 1] +
		board[x - 1][y] +
		board[x - 1][y + 1] +
		board[x][y - 1] +
		board[x][y + 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] - 8 * '0');
}

test.c

#include"game.h"
void menu()
{
	printf("****************************n");
	printf("********  1.play  **********n");
	printf("********  0.exit  **********n");
	printf("****************************n");
}
void game()
{
	char board[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	Itnboard(board, ROWS, COLS,'0');  //初始化棋盤
	Itnboard(show, ROWS, COLS, '*');
	Setboard(board, ROW, COL);   
	Displayboard(board, ROW, COL);
	Player(board, show, ROW, COL);            //玩家輸入
}
int main()
{
	int input=1;
  srand((unsigned int)time(NULL));
	do{
		menu();
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		game();
		break;
	case 0:
		break;
	default:
		printf("輸入錯誤請重新輸入:n ");
	}
	} while (input);
}

game.c

#include"game.h"
void Itnboard(char board[ROWS][COLS], int rows, int cols,char c)
{
	int i, j;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j <cols; j++)
		{
			board[i][j] = c;
		}
	}
}
void Displayboard(char board[ROWS][COLS], int row, int col)
{
	int i, j;
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("n");
	}
}
void Setboard(char board[ROWS][COLS], int row, int col)
{
	int count = Easy_count;
	while (count)
	{
		int x = rand() % row+1;
		int y = rand() % col+1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}
int sum(char board[ROWS][COLS], int x, int y)
{
 
	return (board[x - 1][y - 1] +
		board[x - 1][y] +
		board[x - 1][y + 1] +
		board[x][y - 1] +
		board[x][y + 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] - 8 * '0');
}
void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = 0;
	while (1)
	{
		printf("請排雷:n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
		{
			if (board[x][y] == '0')
			{
				Openboard(show, board, x, y);
				Displayboard(show, ROW, COL);
			}
			else if (board[x][y] == '1')
			{
				printf("你死了n");
				break;
			}
		}
		else
		{
			printf("請重新輸入");
		}
		int i, j;
		for (i = 1; i <= row; i++)
		{
			for (j = 1; j <= col; j++)
			{
				if (show[i][j] == '*')
				{
					count++;
				}
			}
		}
		if (count == Easy_count)
		{
			printf("成功n");
			break;
		}
	}
}
void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col)
{
 
	if (row >= 1 && row <= ROW && col >= 1 && col <= COL)
	{
		int count=sum(board, row, col);
		if (count != 0)
		{
			show[row][col] = count + '0';
		}
		else if (show[row][col] != '_')
		{
			show[row][col] = '_';
			int i = 0, j = 0;
			for (i = row - 1; i <= row + 1; i++)
			{
				for (j = col - 1; j <= col + 1; j++)
				{
					
					Openboard(show, board, i,j);
				}
			}
		}
		else
		{
			return;
		}
	}
}

game.h

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define Easy_count 10
void Itnboard(char board[ROWS][COLS], int rows, int cols,char c);
void Displayboard(char board[ROWS][COLS], int row, int col);
void Setboard(char board[ROWS][COLS], int row, int col);
void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col);

到此這篇關於C語言詳細講解通過遞迴實現掃雷的展開的文章就介紹到這了,更多相關C語言掃雷內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com