-1

我为我的项目编写了一个随机路径生成器,当它工作时,它按预期工作。然而,它有时只起作用。

在我的 main 函数中,我有一个简单的 switch 语句来调用这个项目的三个任务。

while(Continue)
{

switch(Example_number)
    {
    default: printf("No such program exists.\n");
             break;
    case 1:  path();
             break;
    case 2:  Caesar_cipher();
             break;
    case 3:  anagram();
             break;
    }

    printf("Would you like to test another?(Y/N)\n");
    scanf("\n%c",&ch);
    if(ch == 'Y' || ch == 'y')
    {
        NULL;
    }
    else
    {
        Continue = false;
    }
}

当你输入 1 时,它会调用这个函数,它会创建一个数组并调用其他两个函数。

void path(void)
{
    //Creates the array walk.
    char walk[10][10] = {{'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'},
                         {'.','.','.','.','.','.','.','.','.','.'}};

//Creates a randomly generated path to travel along walk.
generate_path(walk);
print_array(walk);
}

生成路径的函数。

void generate_path(char walk[10][10])
{
int move_n = 0;
int row, column, i;
const char alph[] = {'B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
//Array that holds all previous data.
int move[3][25] = {0};
bool block = false;

//Allows for a random variable.
srand((unsigned) time(NULL));

row = rand() % 10;
column = rand() % 10;

while(!block)
{
    walk[row][column] = 'A';
    for(i = 0; i < 25; i++)
    {
        //goto comes here
        restart:
        move_n = rand() % move_dir;
        //If space is open continue the alph array one row below.
        if(move_n == 0 && walk[row+1][column] == '.' && row+1 < 10)
        {
            row += 1;
            move[0][i] = i;
            move[1][i] = row;
            move[2][i] = column;
            walk[row][column] = alph[i];
        }
        else if(move_n == 1 && walk[row][column+1] == '.' && column+1 < 10) //If space is open continue the alph array one column to the right. 
        {
            column += 1;
            move[0][i] = i;
            move[1][i] = row;
            move[2][i] = column;
            walk[row][column] = alph[i];
        }
        else if(move_n == 2 && walk[row-1][column] == '.' && row-1 >= 0) //If space is open continue the alph array one row above.
        {
            row -= 1;
            move[0][i] = i;
            move[1][i] = row;
            move[2][i] = column;
            walk[row][column] = alph[i];
        }
        else if(move_n == 3 && walk[row][column-1] == '.' && column-1 >= 0) //If space is open continue the alph array one column to the left.      
        {
            column -= 1;
            move[0][i] = i;
            move[1][i] = row;
            move[2][i] = column;
            walk[row][column] = alph[i];
        }
        else if((walk[row][column-1] == '.') || (walk[row-1][column] == '.') || (walk[row][column+1] == '.') || (walk[row+1][column] == '.')) 
        {
            if(i == 25)
                break;
            goto restart;
        }
        else
        {
            //Resets data to point such that the path can continue.
            row = move[1][i-1];
            column = move[2][i-1];
            i--;
            walk[row][column] = '.';
        }
    }
    block = true;
}
}

以及打印数组功能。

void print_array(char walk[10][10])
{
int i = 0;
int k = 0;
for(i = 0; i < 10; i++)
{
    for(k = 0; k < 10; k++)
    {
        printf(" %c", walk[i][k]); 
    }
    printf("\n");
}
}

但是由于某种原因,在 switch 语句中输入 1 时,它有时只能工作。每次调用任何其他函数都可以完美运行。

4

2 回答 2

3

您的问题很可能与if您在 generate_path() 中的语句有关。

您访问walk[row+1][column]等并生成walk[row][column+1]. 因此,值可以是或在某些时候,当访问索引等时,它将访问数组边界之外,这可能会导致各种问题。rowcolumnrand()%10rowcolumn 09row-1 column+1

于 2013-03-01T20:19:56.693 回答
2

来自 30 年 C 编程老手的一些建议...

  1. 不要使用关键字作为变量名。“继续”会使其他程序员感到困惑,因为“继续”是一个关键字。
  2. 我建议首先在 path() 函数的 if 堆栈中进行边界检查。这样,如果边界检查失败,其他测试(包括越界内存访问)将不会发生。
  3. path() 中 if 堆栈的“重启”路径没有边界检查!

最后,我根据您的代码示例构建了一个项目,我发现它在 path() 中的 if 堆栈的 else 分支中“卡住”了。这似乎正在发生,因为外部循环计数器 (i) 递减,行和列更新,然后循环迭代。这会导致 i 递增,并且如果已选择的行/列也是无法继续的点,则循环将无限重复。

--修正--

我已经在http://www.svalli.com/files/path.7z上发布了我根据您的代码示例构建的程序,以便您可以检查以确保我没有改变您的逻辑。这是我得到的输出(包括我添加的一些调试以显示循环挂起的位置/原因):

    Path -----------------------
     . . . . . . . . . .
     . . . . . F E . A .
     . . . I H G D C B .
     . . . J K . . . . .
     P O N M L . . . . .
     Q R S . . . . . . .
     . . T U . . . . . .
     . . . V . . . . . .
     . . X W . . . . . .
     . Z Y . . . . . . .
    Would you like to test another?(Y/N)
    y

    row 2/col 6
    Path -----------------------
     . . . . P O N M L K
     . . . . Q T U H I J
     . . . . R S . G . .
     . . . . . D E F . .
     . . . A B C . . . .
     . . . . . . . . . .
     . . . . . . . . . .
     . . . . . . . . . .
     . . . . . . . . . .
     . . . . . . . . . .
    Would you like to test another?(Y/N)

如果在检测到挂起时我的调试没有中断,那么第二次运行将永远挂起,试图找到离开单元 2,6 的方法。我希望这可以帮助您找出逻辑错误——我没有试图理解您的路径算法,只是为了找到它挂在哪里以及挂起条件是什么。除非我彻底改变了某些东西(我怀疑),否则这是你的问题。我希望它有所帮助。哦,如果你发现我无意中改变了你的逻辑,请告诉我如何/在哪里,好吗?我也很想知道。

- 更多的 -

对于任何感兴趣的人,我将路径生成器包装在一个 Win32 程序中,以便它每 1/2 秒执行一次迭代并在屏幕上更新路径。它用红色字符绘制“正常”路径。如果它卡住了,它会用黄色绘制它检查的最后一个字符,然后,如果它一直卡住,它会用黄色和绿色交替绘制一个加号,直到它解开。选择生成!从菜单中将始终启动一个新的、干净的路径序列并按停止!卡住时将停止它(生成!当然,退出程序。)您可以在此处获取可执行文件: http ://www.svalli.com/files/maze.7z 看着它工作很有趣,很容易看出它为什么/如何卡住。由此,我相信有人会弄清楚如何修复路径生成器,使其永远不会卡住。或者也许我为检测“卡住”情况而投入的调试代码就足够了?它只是生成了一条可能无法继续的短路径。

于 2013-03-01T20:50:27.127 回答