扫雷游戏
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;
}