天天看點

用c語言寫的掃雷SDK控制台應用程式

話不多少,先看代碼

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_ROW 9
#define MAX_COL 9
#define MINE_COUNT 10
//1.使用兩個二維數組表示地圖
//show_map(char)表示翻開(數字)和未翻開('*')''表示字元""表示字元串
//mine_map(char)表示是雷('1')和不是雷('0')
//2.數組的初始化
//show_map初始化為全都是未翻開的狀态('*')
//mine_map先初始化為全都是('0')的狀态,然後随機的生成十個('1')
//3.列印地圖(show_map)
//4.提示玩家輸入一個坐标表示要翻開的位置,校驗坐标的有效性
//5.判定是不是踩雷了
//6.如果沒踩雷,判斷是不是遊戲勝利(翻開了所有不是地雷的格子)
//7.沒踩雷,就告訴玩家目前位置有幾個雷
int Menu()
{
	printf("**********************\n");
	printf("***** 1.開始遊戲 *****\n");
	printf("***** 0.遊戲結束 *****\n");
	printf("**********************\n");
	int chioce = 0;
	scanf("%d", &chioce);
	return chioce;
}
void Init(char show_map[MAX_ROW][MAX_COL], char mine_map[MAX_ROW][MAX_COL])
{
	for (int row = 0; row < MAX_ROW; ++row)
	{
		for (int col = 0; col < MAX_COL; ++col)
		{
			show_map[row][col] = '*';
		}
	}
	for (int row = 0; row < MAX_ROW; ++row)
	{
		for (int col = 0; col < MAX_COL; ++col)
		{
			mine_map[row][col] = '0';
		}
	}
	int mine_count = MINE_COUNT;
	while (mine_count > 0)
	{
		int row = rand()%MAX_ROW;
		int col = rand()%MAX_COL;
		if (mine_map[row][col] == '1')
		{
			continue;
		}
		else
		{
			mine_map[row][col] = '1';
			--mine_count;
		}
	}
}
void PrintMap(char show_map[MAX_ROW][MAX_COL])
{
	printf("  |");
	
	for (int col = 0; col < MAX_COL; ++col)
	{
		printf("%d ", col);
	}
	printf("\n");
	for (int col = 0; col < MAX_COL-2; ++col)
	{
		printf("___");
	}
	printf("\n");
	for (int row = 0; row < MAX_ROW; ++row)
	{
		printf(" %d|", row);
		for (int col = 0; col < MAX_COL; ++col)
		{
			printf("%c ", show_map[row][col]);
			
		}
		printf("\n");
	}
}
void UpdateShowMap(int row,int col,char mine_map[MAX_ROW][MAX_COL],char show_map[MAX_ROW][MAX_COL])
{
	int count = 0;
	if (row-1 >= 0 && col-1 >=0 && mine_map[row - 1][col - 1] == '1')
	{
		++count;
	}
	if (row - 1 >= 0 && mine_map[row - 1][col] == '1')
	{
		++count;
	}
	if (row - 1 >= 0 && col + 1 < MAX_COL && mine_map[row - 1][col + 1] == '1')
	{
		++count;
	}
	if (col - 1 >= 0 && mine_map[row][col - 1] == '1')
	{
		++count;
	}
	if (col + 1 < MAX_COL && mine_map[row][col + 1] == '1')
	{
		++count;
	}
	if (row + 1 < MAX_ROW && col - 1 >= 0 && mine_map[row + 1][col - 1] == '1')
	{
		++count;
	}
	if (row + 1 < MAX_ROW && mine_map[row + 1][col] == '1')
	{
		++count;
	}
	if (row + 1 < MAX_ROW && col + 1 < MAX_COL && mine_map[row + 1][col + 1] == '1')
	{
		++count;
	}
	show_map[row][col] = count + '0';
}
void Game()
{
	char show_map[MAX_ROW][MAX_COL];
	char mine_map[MAX_ROW][MAX_COL];
	Init(show_map, mine_map);
	while (1)
	{
	PrintMap(show_map);
	//提示玩家輸入,并進行校驗
	
	printf("請輸入要翻開的位址(row col)\n");
	int row = 0;
	int col = 0;
	int blank_count = 0;
	scanf("%d %d", &row, &col);
	
		if (row<0 || row>MAX_ROW || col<0 || col>MAX_COL)
		{
			printf("輸入的坐标非法,請重新輸入\n");
			continue;
		}
		if (show_map[row][col] != '*')
		{
			printf("這個位置已被翻開,請重新輸入\n");
			continue;
		}
		//判斷是否踩雷
		if (mine_map[row][col] == '1')
		{
			    show_map[row][col] = '#';
				printf("很遺憾踩雷了\n");
				PrintMap(show_map);
				return;
		}
		++blank_count;
		//判斷是否是遊戲勝利
		if (blank_count == MAX_ROW * MAX_COL - MINE_COUNT)
		{
			printf("恭喜你,掃雷成功\n");
			return;
		}
		//告訴玩家目前位置有幾顆雷
		system("cls");
		UpdateShowMap(row,col,mine_map,show_map);

	}
}
int main()
{
	srand((unsigned int)time(0));
	//int chioce = Menu();
	while (1)
	{
		int chioce = Menu();
		if (1 == chioce)
			Game();
		else if (0 == chioce)
		{
			printf("BYE BYE\n");
			break; 
		}
		else
		{
			printf("您的輸入非法請重新輸入\n");
			continue;
		}
	}
	system("pause");
	return 0;
}
           

在這裡筆者講一下遊戲的思路,首先這是一個控制台應用程式,人機互動是通過scanf()和printf()實作的,比較簡單。

做這個簡單遊戲的思路是:首先要有一個菜單,供使用者去選擇開始遊戲還是結束遊戲。這裡用的比較多的是循環結構,因為不可能玩一局電腦就自動結束。在程式設計中用的最多的是函數,因為函數可以使程式變得條理清楚大大增強了程式的可讀性,并且在寫程式的時候按照遊戲的功能分步去寫它的更符合計算機的思維。

首先來看它的功能

//1.使用兩個二維數組表示地圖

//show_map(char)表示翻開(數字)和未翻開(’’)’‘表示字元""表示字元串

//mine_map(char)表示是雷(‘1’)和不是雷(‘0’)

//2.數組的初始化

//show_map初始化為全都是未翻開的狀态(’’)

//mine_map先初始化為全都是(‘0’)的狀态,然後随機的生成十個(‘1’)

//3.列印地圖(show_map)

//4.提示玩家輸入一個坐标表示要翻開的位置,校驗坐标的有效性

//5.判定是不是踩雷了

//6.如果沒踩雷,判斷是不是遊戲勝利(翻開了所有不是地雷的格子)

//7.沒踩雷,就告訴玩家目前位置有幾個雷

if (row-1 >= 0 && col-1 >=0 && mine_map[row - 1][col - 1] == '1')
	{
		++count;
	}
           

注意到此處用到了&&這個邏輯與,涉及到短路求值的問題例如exp1&&exp2。當exp1的值是0的時候exp2的值就會不在判定。以上面那個為例。當交換exp2和exp1的位置的時候。當不滿足 mine_map[row - 1][col - 1] == '1’時結果直接就是0,而不判斷row-1 >= 0 && col-1 >=0。導緻後面的執行出錯。

遊戲的關鍵是将玩家翻開的位置顯示出附近有幾顆雷,方法是在mine_map中周遊它周圍八個位置,并且把值賦給show_map。然後下一次輸出的時候就會在show_map中看到值。

至此,掃雷遊戲已經初步完成,歡迎大家批評指教。喜歡我可以關注我。

繼續閱讀