2 wse320 wse320 于 2015.06.11 19:08 提问

C语言编写扫雷的小白问题

#include
#include
#include
#include
/*这是一个简单的基于控制台界面的扫雷小游戏*/
char display[9][9];/*定义显示用数组display*/
char control[9][9];/*定义核心内容数组control*/
void output(char a[9][9]);
void output1(char a[9][9]);
void scan_mine(int x,int y);
void nine();
int num=0;/*定义全局变量num用于统计判断过周边雷数的格子数量*/
int main()
{
printf("**********************\n");
printf("*这是一个扫雷小游戏!*\n");/*欢迎界面*/
printf("**********************\n");
printf("\n欢迎!\n");
nine();

return 0;

}
void nine()
{
int i,j;/*循环变量i,j*/
int x,y;/*坐标变量x,y*/
int x1,y1;
srand((int)time(0));
for(i=0;i<9;i++)
{
control[rand()%10][rand()%10]='#';/*使用rand函数在9*9的矩阵内随机为10个元素赋值#,#代表地雷*/
}

for(i=0;i<9;i++)
    for(j=0;j<9;j++)
        {
            if(control[i][j]!='#')/*对除去被设定为地雷的元素以外赋值0*/
                control[i][j]='0';
        }

for(i=0;i<9;i++)
    for(j=0;j<9;j++)
        {
            display[i][j]='*';/*对显示用数组display所有元素赋值'#'*/
        }

        output1(display);
        printf("请输入你要点开的坐标(x,y):");
        /*该循环用于在num计数小于格子数时反复输入坐标并且进行棋盘扫描直到胜利*/
        for(;(81-num)!=0;)
            {
                scanf("%d,%d",&x1,&y1);
                x=x1-1;
                y=y1-1;
            if(control[x][y]=='#')
            {
                printf("你踩到雷了!游戏结束!\n");/*踩到地雷时的处理*/
                printf("这是地雷的排布情况\n");
                output(control);
                getch();
                break;
            }
            else
            {
                scan_mine(x,y);         /*所选坐标并非地雷,进行棋盘扫描*/
                output1(display);
            }

            }
            printf("你胜利啦");

}

void output(char a[9][9])/*该函数用于输出9*9核心矩阵的值*/
{
int m,n;
for(m=0;m<9;m++)
for(n=0;n<9;n++)
{
printf("%3c",a[m][n]);
if(n==8)
printf("\n");/*每9个元素进行换行*/
}
}
void output1(char a[9][9])/*该函数用于输出9*9显示矩阵的值*/
{
int m,n;
printf(" 1 2 3 4 5 6 7 8 9 \n");/*输出列标*/
for(m=0;m<9;m++)
for(n=0;n<9;n++)
{
if(n==0)
printf("%d",m+1);/*输出行标*/
printf("%3c",a[m][n]);
if(n==8)
printf("\n");/*每9个元素进行换行*/
}
}
void scan_mine(int x,int y)/*该函数用于扫描所给坐标周围的地雷数目*/
{

    if(x==0&&y==0)          /*左上角的格子*/
{
    if(control[0][1]=='#') control[0][0]+=1;
    if(control[1][0]=='#') control[0][0]+=1;
    if(control[1][1]=='#') control[0][0]+=1;
    display[0][0]=control[0][0];
    num++;
}
if(x==8&&y==0)             /*左下角的格子*/
{
    if(control[8][1]=='#') control[8][0]+=1;
    if(control[7][0]=='#') control[8][0]+=1;
    if(control[7][1]=='#') control[8][0]+=1;
    display[8][0]=control[8][0];
    num++;
}
if(x==0&&y==8)             /*右上角的格子*/
{
    if(control[0][7]=='#') control[0][8]+=1;
    if(control[1][7]=='#') control[0][8]+=1;
    if(control[1][8]=='#') control[0][8]+=1;
    display[0][8]=control[0][8];
    num++;
}
if(x==8&&y==8)              /*右下角的格子*/
{
    if(control[8][7]=='#') control[8][8]+=1;
    if(control[7][7]=='#') control[8][8]+=1;
    if(control[7][8]=='#') control[8][8]+=1;
    display[8][8]=control[8][8];
    num++;
}
if(x==0&&y>0&&y<8)          /*第一行除了右上和左上的格子*/
{
    if(control[0][y]=='#') control[0][y]+=1;
    if(control[0][y-1]=='#') control[0][y]+=1;
    if(control[1][y]=='#') control[0][y]+=1;
    if(control[1][y-1]=='#') control[0][y]+=1;
    if(control[1][y]=='#') control[0][y]+=1;
    display[0][y]=control[0][y];
    num++;
}
if(x==8&&y>0&&y<8)          /*最后一行除了左下和右下的格子*/
{
    if(control[8][y]=='#') control[8][y]+=1;
    if(control[8][y-1]=='#') control[8][y]+=1;
    if(control[7][y]=='#') control[8][y]+=1;
    if(control[7][y-1]=='#') control[8][y]+=1;
    if(control[7][y]=='#') control[8][y]+=1;
    display[8][y]=control[8][y];
    num++;
}
if(y==0&&x>0&&x<8)          /*第一列除了左上和左下的格子*/
{
    if(control[x][0]=='#') control[x][0]+=1;
    if(control[x-1][0]=='#') control[x][0]+=1;
    if(control[x][1]=='#') control[x][0]+=1;
    if(control[x-1][1]=='#') control[x][0]+=1;
    if(control[x][1]=='#') control[x][0]+=1;
    display[x][0]=control[x][0];
    num++;
}
if(y==8&&x>0&&x<8)      /*最后一列除了右上和右下的格子*/
{
    if(control[x][8]=='#') control[x][8]+=1;
    if(control[x-1][8]=='#') control[x][8]+=1;
    if(control[x][7]=='#') control[x][8]+=1;
    if(control[x-1][7]=='#') control[x][8]+=1;
    if(control[x][7]=='#') control[x][8]+=1;
    display[x][8]=control[x][8];
    num++;
}
if(x>0&&x<8&&y>0&&y<8)      /*中央区域的格子*/
{
    if(control[x][y]=='#')control[x][y]+=1;
    if(control[x-1][y-1]=='#')control[x][y]+=1;
    if(control[x][y]=='#')control[x][y]+=1;
    if(control[x][y-1]=='#')control[x][y]+=1;
    if(control[x-1][y]=='#')control[x][y]+=1;
    if(control[x][y-1]=='#')control[x][y]+=1;
    if(control[x][y]=='#')control[x][y]+=1;
    if(control[x-1][y]=='#')control[x][y]+=1;
    display[x][y]=control[x][y];

    num++;

}
 if(x!=0 && display[x][y]=='0')                  scan_mine(x-1,y);
 if(x!=0 && y!=8 && display[x][y]=='0')      scan_mine(x-1,y+1);
 if(y!=8 && display[x][y]=='0')                scan_mine(x-1,y+1);
 if(x!=8 && y!=8 && display[x][y]=='0')    scan_mine(x+1,y+1);
 if(x!=8 && display[x][y]=='0')                scan_mine(x+1,y);
 if(x!=8 && y!=0 && display[x][y]=='0')      scan_mine(x+1,y-1);
 if(y!=0 && display[x][y]=='0')                  scan_mine(x,y-1);
 if(x!=0 && y!=0 && display[x][y]=='0')        scan_mine(x-1,y-1);

}
代码在这里,主要问题就是运行的时候输入坐标之后程序就立刻出现问题并终止了,通过查看任务管理器的内存占用,发现是无限递归导致的溢出,去掉scan_mine()函数中的递归部分之后程序正常,但是无法做到正常扫雷那种一点开一片的效果,我找不出这个递归部分错误在哪里,求各位程序猿巨巨解答一下,感激不尽

5个回答

u010717334
u010717334   2015.06.11 21:10

如果一直符合scan_mine里的if的条件的话就会一直递归

tongyi55555
tongyi55555   2015.06.11 21:20

大致的看了一下你的代码,你处理四周的代码不对,比如第一行除了右上和左上的格子里面有两个1,y坐标对,而且你的(0,y)坐标对是不用处理的,已经判识了该值不是雷。你试着改一下吧。

wse320
wse320   2015.06.11 21:50

谢谢各位的大力相助,已经解决了

qq_30165435
qq_30165435 哪里有问题啊?
大约 2 年之前 回复
u010655288
u010655288   2015.06.12 17:03

代码太长,看不下去 ,

henuyx
henuyx   2015.06.14 17:31

扫描给定坐标周围的地雷数目,貌似不用递归。
因为下面每个语句都会去执行,不知道会不会出现循环递归。

Csdn user default icon
上传中...
上传图片
插入图片