扫雷游戏模拟

扫雷游戏
trick 翻开后还要处理继续翻开的情况,就是如果当前左击的是空白的,
或者击开的有空白的,那么还要继续击开。
这点在左右键同时上的时候也要考虑,不然就像我的悲剧。
flag一般用的比较多,flag以后点无效的。
问号用的比较少,有问号,双击还是点不开的。
当然如果赢了或输了都是会结束的。
赢的标准可以看如果剩余的未翻开的和flag的和?的总数是否正好和雷总数一样。








#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int n,m,op;
char dd[66][66];
int mark[66][66];
int mask[66][66];
int idx[8][2]={
	{-1,-1},{-1,0},{-1,1},
	{0,-1},{0,1},
	{1,-1},{1,0},{1,1}
};
int all;
int input(){
	int i;
	if(scanf("%d %d %d",&n,&m,&op) != 3)
		return 0;
	memset(dd,0,sizeof(dd));
	for(i = 0; i < n;){
		scanf("%s",dd[i]);
		if(dd[i][0] == '*' || dd[i][0] == '.')
			i++;
	}
	memset(mark,0,sizeof(mark));/*数组标记*/
	memset(mask,0,sizeof(mask));/*是否被打开,或者标记,或者有x的填x*/
	return 1;
}
int check(int x,int y){
	if(x >= 0 && x < m && y >= 0 && y < n)
		return 1;
	else return 0;
}
void init(){/*计算周围的雷数量*/
	int i,j,k,tx,ty;
	for(i = 0; i < n; i++){
		for(j = 0; j < m; j++){
			for(k = 0; k < 8; k++){
				tx = j + idx[k][1];
				ty = i + idx[k][0];
				if(check(tx,ty) && dd[ty][tx] == '*'){
					mark[i][j]++;
				}
			}
		}
	}
}
int fankai(int x,int y){
	int i,j,tx,ty,chk,ret;
	if( mask[y][x] =='@')
		return 1;
	if(dd[y][x] == '*'){
		mask[y][x] = '*';
		return 0;
	}
	
	chk = 1;
	mask[y][x] = mark[y][x]+'0';
	if(mark[y][x] != 0)
		return 1;
	for(i = 0; i < 8; i++){
		tx = x + idx[i][0];
		ty = y + idx[i][1];

		if(check(tx,ty)&& mask[ty][tx] == 0  ){
			if(dd[ty][tx] == '*'){
				mask[ty][tx] = '*';
				chk = 0;
			}
			mask[ty][tx] = mark[ty][tx]+'0';
			if(mark[ty][tx] != 0){
			}
			else{
				ret = fankai(tx,ty);
				if(ret == 0)
					chk = 0;
			}
		}
	}
	return chk;
}
int checkWin(){
	int i,j,same;
	int a,b;
	a = b = 0;
	for(i = 0; i < n; i++)
		for(j = 0; j < m; j++){
			if(mask[i][j] == '?' || mask[i][j] == '@'|| mask[i][j] == 0){
				a++;
			}
			if(dd[i][j] == '*')
					b++;
		}
		if(a!=b)
			return 0;
	for(i = 0; i < n; i++)
		for(j = 0; j < m; j++){

			if(mask[i][j] == '?' || mask[i][j] == '@'||mask[i][j] == 0){
				mask[i][j] = '@';
					
			}
		}
		return 1;
}
int fankai2(int x,int y){
	int i,j,tx,ty,flaged,win = 1;
	if(mask[y][x] == 0 || mask[y][x] == '?'){
		return 1;
	}
	flaged = 0;
	for(i = 0; i < 8; i++){
		tx = x + idx[i][0];
		ty = y + idx[i][1];
		if(check(tx,ty)){
			if( mask[ty][tx] == '@')
				flaged++;
		}
	}
	if(flaged == mark[y][x]){
		for(i = 0; i < 8; i++){
			tx = x + idx[i][0];
			ty = y + idx[i][1];
			if(check(tx,ty)){
				if(mask[ty][tx] == 0 ){
					if(dd[ty][tx] == '*'){
						mask[ty][tx] ='*';
						win = 0;
					}
					else {
						mask[ty][tx] =  mark[ty][tx] + '0' ;
						if(mark[ty][tx] == 0)
							fankai(tx,ty);
					}
				}
					
			}
		}
	}
	return win;
}

int pendL(int x,int y){
	if(fankai(x,y) == 0)
		return 0;
	else return 1;
}
int pendR(int x,int y){
	if(mask[y][x] == 0 )
		mask[y][x] = '@';
	else if(mask[y][x] == '@')
		mask[y][x] = '?';
	else if(mask[y][x] == '?')
		mask[y][x] = 0;
	return 0;
}
int work(){
	int i;
	int x,y;
	char ch;
	int win = 1;
	for(i = 0; i < op ;i++){
		scanf("%d %d %c",&y,&x,&ch);
		if(win == 1){
		if(ch == 'L'){
			if(!pendL(x,y))
				win = 0;
			if(win && checkWin()){
				win++;
			}
		}
		else if(ch == 'R'){
			pendR(x,y);
		}
		else if(ch == 'D'){
			if(!fankai2(x,y))
				win = 0;
			if(win && checkWin()){
				win++;
			}
		}
	//	assert(mask[3][7]!='2');
		}
		//end(1);
	}
	if(win == 2)
		win = 1;
	return win;
}
int end(int iswin){
	int i,j;
	for(i = 0; i < n; i++){
		for(j = 0; j < m; j++){
				if(!iswin && dd[i][j] == '*' ){
					if(mask[i][j] == 0 || mask[i][j] == '*'||mask[i][j] == '?' )
						putchar('*');
					else putchar('@');
				}
				else if(mask[i][j] == 0){
						putchar('.');
				}
				else if(mask[i][j] == '?' || mask[i][j] == '@'){
					if(!iswin)
						putchar('X');
					else putchar(mask[i][j]);
				}
				else putchar(mask[i][j]);

		}
		printf("\n");
	}
	printf("\n");
}
int main(){
	int iswin;
	freopen("d:/c2.in","r",stdin);
	freopen("d:/c3.out","w",stdout);
	while(input()){
		init();
		all = 0;
		iswin = work();
		end(iswin);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值