写的扫雷递归感觉没错,但是报错

真的不知道错哪了


void get_put(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y,int z)
{
    for (int i = x - 1; i <= x + 1; i++)
    {
        for (int j = y - 1; j <= y + 1; j++)
        {
            if (mine[i][j] == '1')
            {
                z++;
            }
        }
    }
    if (z == 0)
    {
        for (int i = x - 1; i <= x + 1; i++)
        {
            for (int j = y - 1; j <= y + 1; j++)
            {
                get_put(mine, show, i, j, z);
            }
        }
    }
    show[x][y] = z + '0';
    extern int q;
    q++;
}


img

在递归函数中,如果当前格子周围没有雷(z==0),会再次调用get_put函数进行递归。但是,您没有判断周围的格子是否越界,可能会导致数组越界错误。因此,需要添加判断语句来确保周围的格子不会越界。

在递归函数中,您传递的参数z应该是当前格子周围的雷数,而不是一开始传递的0。因为z的值应该是动态变化的,随着递归的进行而改变。因此,在调用递归函数时,应该传递当前格子周围的雷数。

在递归函数中,您需要判断当前格子是否已经被翻开,如果已经翻开则不需要再次翻开。因为如果已经翻开,则说明当前格子周围的雷数已经被计算出来了,不需要再次递归计算。

最后,根据您提供的代码,似乎您没有对扫雷游戏进行初始化操作。在开始游戏前,需要将雷的位置随机生成,并将show数组初始化为未翻开状态。


void get_put(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y)
{
int z = 0;
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (i >= 0 && i < ROWS && j >= 0 && j < COLS && mine[i][j] == '1' && show[i][j] != '*')
{
z++;
}
}
}
if (z == 0)
{
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (i >= 0 && i < ROWS && j >= 0 && j < COLS && show[i][j] == '-')
{
get_put(mine, show, i, j);
}
}
}
}
show[x][y] = z + '0';
extern int q;
q++;
}
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7789898
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:【课设作业】通讯录管理系统,还不知道怎么写课设的赶快来了
  • 除此之外, 这篇博客: 猜数字游戏的实现,包含随机数的使用方法中的 猜数字游戏 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 题目内容:
    用C语言实现一个猜数字游戏。
    进入程序,先打印菜单给出提示,1.玩游戏,0.退出程序。当输入0的时候,退出程序。输入1,则继续,然后随机产生一个数字,输入数字猜这个数字的大小,直到猜中这个数字。当你输入的这个数字小于这个随机数,提示猜小了,当你输入数字大于这个随机数,则提示猜大了。直到猜中这个随机数,输出恭喜你猜中了,并结束程序。
    具体实现:

    #define _CRT_SECURE_NO_WARNINGS 1
    //猜数字游戏的实现
    #include <stdio.h>
    #include <stdlib.h>
    void menu()
    {
    	printf("*******************************\n");
    	printf("********    1 .play    ********\n");
    	printf("********    0 .exit    ********\n");
    	printf("*******************************\n");
    }
    void game()
    {
    	int random_num = rand() % 100 + 1;//产生一个随机数用rand函数
    	int input = 0;
    	printf("%d", random_num);//为了方便猜,可以将这个随机数打印出来
    	while (1)
    	{
    		printf("请输入你猜的数字:\n");
    		scanf("%d", &input);
    		if (input > random_num)
    		{
    			printf("猜大了\n");
    		}
    		else if (input<random_num)
    		{
    			printf("猜小了\n");
    
    		}
    		else
    		{
    			printf("恭喜你,猜中了\n");
    		}		
    	}
    }
    
    int main()
    {
    	int input = 0;
    	do
    	{
    		menu();//打印菜单
    		printf("请输入你需要的选项:\n");
    		scanf("%d", &input);
    		switch (input)
    		{
    		case 1:
    			game();//调用game函数
    			break;
    		case 0:
    			printf("退出成功!\n");
    			break;
    		default:
    			printf("输入错误,请重新输入\n");
    			break;
    		}
    	} while (input);//输出为0,即终止循环
    
    	return 0;
    }
    

    进入程序,先给出提示:
    输入0,直接结束程序:在这里插入图片描述
    输入1,进入程序
    并打印出这个随机数在这里插入图片描述
    猜数字:
    在这里插入图片描述
    如果猜的次数多了,会发现产生的随机数,会一直是一个数(我这里就一直是42),这样很容易就猜到了,这样的解决办法如下:
    加入以下代码,并使用#include<time.h>的头文件

    srand((unsigned)time(NULL));

    time_t time(time_t *time);该函数返回自计算机计时的某个时刻起到现在所过去的秒数。
    一般是返回自1970年1月1日00:00:00以来,到调用函数的时刻所累积的秒数。
    srand((unsigned)time(NULL));
    这语句的含义就是以自1970年1月1日00:00:00以来,到调用函数的时刻所累积的秒数作为
    产生随机数算法的种子seed。
    没有语句会对程序产生什么影响:
    如果在程序运行时没有自主设置种子的话,用函数rand产生的随机数序列会是一样的。
    而用srand设置随机数种子后,可能产生不同的随机序列

    如下:3次的随机数不同:
    在这里插入图片描述
    这里除了随机数,还有do…while循环,这个循环是不管怎样都会先走一次,走完在判定while中的循环条件,如果满足再走,不满足就结束。

  • 您还可以看一下 张传波老师的软件设计是怎样炼成的?课程中的 详细设计使用招数小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    该问题需要提供代码才能进行调试。以下是一些可能出现问题的原因和解决方案:

    1. 内存泄漏:需要在适当的位置释放内存,可以使用malloc()和free()等函数来分配和释放内存。

    2. 指针问题:可能需要检查指针数组和指针参数的传入,以保证没有越界并且没有出现空指针等问题。

    3. 逻辑错误:需要检查递归过程中的条件判断是否正确,可以使用调试工具在不同的状态下打印变量值来进行分析。

    调试技巧:

    1. 使用断点:在函数的可