C語言的小掃雷

前言:
之前一直想實現下掃雷,偶然在貼吧裏看到有人出題,於是心血來潮就寫了下。

題目:

掃雷遊戲是Windows裏一款十分經典的單機小遊戲,請你用C程序自己建立一個掃雷小遊戲。
系統可以隨機產生一個m行n列的雷區,包含若干顆地雷,用戶可以挖開一個區域,如果是地雷,遊戲結束,失敗;
如果不是,顯示出它周圍的地雷個數,如果能把所有安全的地區找出來,獲勝。 注:每個格子周圍格有八個:上、下、左、右、左上、右上、左下、右下。
運行結果:
請輸入雷區的範圍:
3 5
X X X X X
X X X X X
X X X X X
請輸入安全的位置:
2 2
X X X X X
X 3 X X X
X X X X X
請輸入安全的位置:
3 4
X X X X X
X 3 X X X
X X X O X
很不幸,你踩到雷了,遊戲結束!

代碼:

#include<stdio.h>
#include <stdlib.h>
#include <time.h>

int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int around[8][2] = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int x,y,z; //行 列 雷 
int *map; //雷區
char *view; //玩家視野 

//初始化雷區 
void init()
{
	for(int i=0;i<x*y;i++)
		map[i]=0;
	for(int i=0;i<x*y;i++)
		view[i]='O';
	
	srand((unsigned)time(NULL));
	int n = z>x*y?x*y:z; 
	while(n--)
	{
		int r = rand()%(x*y);
		while(map[r])
			r = rand()%(x*y);
		map[r] =1;
	} 
}

//周圍雷數 
int checkMine(int px, int py)
{
	int count = 0;
	for(int i=0;i<8;i++)
	{
		int nx = px+around[i][0];
		int ny = py+around[i][1];
		if(nx>=0&&nx<x&&ny>=0&&ny<y&&map[y*nx+ny]==1)
			count++;
	}
	return count;
}

//排雷 
void clearMine(int px, int py)
{
	int num = checkMine(px,py);
	view[y*px+py]=num==0?'.':'0'+num;
	for(int i=0;num==0&&i<4;i++)
	{
		int nx = px+dir[i][0];
		int ny = py+dir[i][1];
		if(nx>=0&&nx<x&&ny>=0&&ny<y&&map[y*nx+ny]==0&&view[y*nx+ny]=='O')
			clearMine(nx,ny);
	}
}

//檢查是否獲勝 
int checkWin()
{
	int n=0;
	for(int i=0;i<x*y;i++)
		if(view[i]=='O')
			n++;
	return n==z;
}


//雷區視圖
void mapScreen()
{
	printf("\n"); 
	for(int i=0; i<x*y;i++)
	{
		printf("%d ",map[i]);
		if((i+1)%y==0) printf("\n");
	}
}

//玩家視圖 
void viewScreen()
{
	for(int i=0; i<x*y;i++)
	{
		printf("%c ",view[i]);
		if((i+1)%y==0) printf("\n");
	}
}

int main()
{
	printf("請輸入雷區參數(行 列 地雷數):\n"); 
	scanf("%d %d %d",&x,&y,&z);
	map = (int *) malloc(sizeof(int)*x*y);
	view = (char *) malloc(sizeof(char)*x*y);
	
	init(); //生成雷區
	viewScreen(); //打印玩家視圖
	//mapScreen(); //查看雷區(作弊)
	
	int px,py,isWin;
	while(1)
	{
		printf("請輸入安全的位置:\n"); 
		scanf("%d %d",&px,&py);
		px--; py--;
		if(px<0||px>=x||py<0||py>=y)
		{
			printf("範圍有誤!\n");
			continue;
		}
		
		//若踩雷遊戲結束 
		if(map[y*px+py]){
			//將所有地雷顯示出來
			for(int i=0; i<x*y;i++)
			{
				if(map[i]==1)
					printf("X ");
				else
					printf("%c ",view[i]);
				if((i+1)%y==0) printf("\n");
			}
			isWin = 0;
			break;
		}
		
		//否則對安全座標排雷 
		if(view[y*px+py]=='O')
			clearMine(px,py);
			
		viewScreen(); //打印玩家視圖
		
		//判斷是否獲勝
		if(checkWin()) 
		{
			isWin = 1;
			break;
		}
	}
	
	if(isWin)
		printf("恭喜獲勝!");
	else
		printf("很不幸,你踩到雷了,遊戲結束!");
		
	return 0;
}

效果圖:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章