hunnu11082 The Minesweeper Game

The Minesweeper Game
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB
Total submit users: 29, Accepted users: 27
Problem 11082 : No special judgement
Problem description
  注:以下说明来自百度百科:http://baike.baidu.com/view/30088.htm#1

 


扫雷简介



扫雷最原始的版本可以追溯到1973年一款名为“方块”的游戏。
不久之后,“方块”被改写成了游戏“Rlogic”。在“Rlogic”里,玩家的任务是作为美国海军陆战队队员,为指挥中心探出一条没有地雷的安全路线,如果路全被地雷堵死就算输。两年后,汤姆·安德森在“Rlogic”的基础上又编写出了游戏“地雷”,由此奠定了现代扫雷游戏的雏形。
1981年, 微软公司的罗伯特·杜尔和卡特·约翰逊两位工程师在Windows 3.1系统上加载了该游戏,扫雷游戏才正式在全世界推广开来。
这款游戏的玩法是在一个9*9(初级),16*16(中级),16*30(高级),或自定义大小的方块矩阵中随机布置一定量的地雷(初级为10个,中级为40个,高级为99个)。由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束。
扫雷游戏的目标是尽快找到雷区中的所有不是地雷的方块,而不许踩到地雷点开的数字是几,则说明该数字旁边的8个位置中有几个雷,如果挖开的是地雷,则会输掉游戏。

游戏玩法

启动: 
在游戏菜单上,单击开局。
要启动计时器,请单击游戏区中的任何方块。

注意:
通过单击即可挖开方块。如果挖开的是地雷,则输掉游戏。
如果方块上出现数字,则表示在其周围的八个方块中共有多少颗地雷。
要标记认为可能有地雷的方块,请右键单击它。示例游戏区包括雷区、地雷计数器和计时器。
一个未点开的方格,右键单击一次,将放上旗子,表示确定该方格是雷;再右键单击一次,将取下旗子并标记问号(?),表示该方格不确定是否为雷;第三次右键单击,则取下问号,恢复初始状态;第四次右键单击,则又放上旗子……依此类推。

自定义游戏区域:
在“游戏”菜单上,单击“自定义(选项)”。
通过指定水平和垂直显示的方块数来定制雷区尺寸,并指定雷区中放置的地雷数。
自定义游戏区域有个漏洞,可使你在10秒之内必胜。
方法如下:在自定义中输入高度、宽度随意大的数值(因为扫雷区域有限,所以会固定在高度24、宽度30的区域里),雷数自定,越少越容易,随意点击一处,然后按照普通规则继续即可。

策略技巧:
如果无法判定某方块是否有雷,请用右键单击两次给它标记一个问号 (?)。之后,可以用鼠标右键单击方块一次将该方块标记为地雷或者或用鼠标右键单击方块两次去掉标记。
如果编号方块周围地雷没有全部标记,在同时使用双击后,其他隐藏或未标记的方块将被按下一次(即闪烁一下)。

编程任务

现在是一个高度为16,宽度为30的雷区,共计99个雷。输入文件将随机生成这样一个的带有地雷的地图,当玩家第一轮单击某个方格时,请你根据游戏规则编写程序对玩家的第一轮动作做出反应。
例如下图中,玩家第一次点击了第6行第14列时,游戏程序给出了如下反应。你应该输出这个地图,该地图用一个二维字符数组表示,其中未点开的方格用'#'表示;已经点开但是八个方向都没有地雷的格子用'0'表示;已经点开但八个方向至少有一个地雷的方格用该方格八个方向地雷数之和表示,显然这个数字在1-8之间。

 

Input
  第一行,有一个正整数T,表示测试数据的组数。
接下来有T组测试数据,每组测试数据之间用一个空行隔开。
对每组测试数据:
第一行有两个正整数(x,y) ,表示玩家首次点击的方格位置为第x行第y列。输入数据保证玩家首次点击的方格一定不是地雷。
接下来是一张系统随机生成的带地雷的地图:方便起见,每张地图用一个16*30的二维字符数组表示,其中字符 '*' 表示该方格放置了地雷,字符'.'表示该方格没有放置地雷。

Output
  对每组测试数据,输出一个16*30的二维字符数组。该二维数组就是【编程任务】中所描述的二维数组。
Be Careful:各组输出数据之间用一个空行隔开,最后一组结尾没有空行。

Sample Input
2
3 24
*.*......*...*..*...........*.
....**..*..*.....*.........***
*.......***..**.....*........*
..*........*.....***.*....*...
....*...**.*........***......*
.*.*...............*......*...
.....*....*.*..****.......**..
....*.*..............*..*.**..
.............*...*...........*
...*.**.*..**.*..*......*.*.*.
...*.*........................
......*.......*......*..**..*.
...*.*................*.......
..*.**..*.........*...**..*.*.
...*.....**.*........*........
.................**..**.......

1 18
........*...*..**.............
*.*.**.......*..*......*.*..*.
.*.*..............**.*..*.....
..*..*..............*.......*.
.*....*..*...........*....*..*
......***..*..*...*..*....*..*
...*.......*..*..........**..*
....*........*..*.......*...*.
*.*..*..***.*.......*.*...*...
.*....**.*........*.*...**.*.*
..*................**.*****...
...*........*......*...*......
..*...................*......*
....*..*....*.*.....*.........
...........*.....*..*.*..*....
..*....*.......*...**.........
Sample Output
##################100000001###
##################111100001###
#####################210012###
######################3101####
#######################102####
#######################102####
#######################114####
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################

#################2############
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
##############################
算法分析:一个DFS,依次搜索周围八个点就行了
View Code
  1 #include<iostream>
2 #define N 18
3 #define M 32
4 using namespace std;
5
6 int map[N][M];
7 int p[N][M];
8 bool flag[N][M];
9 bool visited[N][M];
10
11 void output()
12 {
13 int i,j;
14 for(i=1;i<N-1;i++)
15 {
16 for(j=1;j<M-1;j++)
17 {
18 if(flag[i][j]==false)
19 {
20 cout<<'#';
21 }
22 else cout<<p[i][j];
23 }
24 cout<<endl;
25 }
26 }
27
28 void count()
29 {
30 int i,j;
31 for(i=1;i<N-1;i++)
32 {
33 for(j=1;j<M-1;j++)
34 {
35 if(map[i][j]==1)
36 {
37 p[i][j]=-1;
38 }
39 else
40 {
41 p[i][j]=map[i-1][j-1]+map[i-1][j]+map[i-1][j+1]+map[i][j-1];
42 p[i][j]+=map[i][j+1]+map[i+1][j-1]+map[i+1][j]+map[i+1][j+1];
43 }
44 }
45 }
46 }
47
48 void find(int n,int m)
49 {
50 if(n==N-1||n==0||m==0||m==M-1) return ;
51 if(p[n][m]>=1)
52 {
53 flag[n][m]=true;
54 visited[n][m]=true;
55 return ;
56 }
57 else if(p[n][m]==0)
58 {
59 visited[n][m]=true;
60 flag[n-1][m-1]=flag[n-1][m]=flag[n-1][m+1]=flag[n][m-1]=true;
61 flag[n][m+1]=flag[n+1][m-1]=flag[n+1][m]=flag[n+1][m+1]=true;
62 if(!visited[n-1][m-1]&&p[n-1][m-1]==0) find(n-1,m-1);
63 if(!visited[n-1][m]&&p[n-1][m]==0) find(n-1,m);
64 if(!visited[n-1][m+1]&&p[n-1][m+1]==0) find(n-1,m+1);
65 if(!visited[n][m-1]&&p[n][m-1]==0) find(n,m-1);
66 if(!visited[n][m+1]&&p[n][m+1]==0) find(n,m+1);
67 if(!visited[n+1][m-1]&&p[n+1][m-1]==0) find(n+1,m-1);
68 if(!visited[n+1][m]&&p[n+1][m]==0) find(n+1,m);
69 if(!visited[n+1][m+1]&&p[n+1][m+1]==0) find(n+1,m+1);
70 }
71
72 }
73
74 int main()
75 {
76 int test;
77 cin>>test;
78 while(test--)
79 {
80 int i,j,n,m;
81 char t;
82 cin>>n>>m;
83 for(i=1;i<N-1;i++)
84 {
85 for(j=1;j<M-1;j++)
86 {
87 cin>>t;
88 if(t=='*') map[i][j]=1;
89 else map[i][j]=0;
90 p[i][j]=0;
91 flag[i][j]=false;
92 visited[i][j]=false;
93 }
94 }
95 for(i=0;i<N;i++)
96 {
97 map[i][0]=0;
98 map[i][M-1]=0;
99 }
100 for(i=0;i<M;i++)
101 {
102 map[0][i]=0;
103 map[N-1][i]=0;
104 }
105 count();
106 find(n,m);
107 output();
108 if(test)cout<<endl;
109 }
110 return 0;
111 }

posted @ 2012-03-26 10:45  mtry  阅读(345)  评论(0)    收藏  举报