我为我的项目编写了一个随机路径生成器,当它工作时,它按预期工作。然而它有时只起作用。这可能是我要经历的很多代码。
在我的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");
}
}
但由于某些原因,在将1输入到switch语句中时,它有时会起作用。每次调用任何其他函数都能完美运行。
感谢您对此的帮助,我觉得好像发布了太多代码,但希望它是可读的。
答案 0 :(得分:3)
很可能你的问题在于你在generate_path()中的if
语句。
您访问walk[row+1][column]
,walk[row][column+1]
等row
和column
生成rand()%10
。因此row
和column
值可以 0
或9
在访问索引时row-1
column+1
等等,它将访问数组边界之外,这可能会导致各种各样的问题。
答案 1 :(得分:2)
来自C编程30年资深人士的一些建议......
最后,我从你的代码示例中构建了一个项目,我发现它在path()中的if堆栈的else分支中“卡住”了。这似乎正在发生,因为外环计数器(i)递减,行和列更新,然后循环迭代。这会导致i递增,如果已选择的行/列也是无法继续的点,则循环无限重复。
- ammendment -
我已经在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秒进行一次迭代,并在屏幕上更新路径。它用红色字符绘制“正常”路径。如果它被卡住了,它会将它检查的最后一个字符绘制为黄色然后,如果它一直卡住,它会交替显示黄色和绿色的加号,直到它被取消。挑选生成!从菜单中总是会启动一个新的,干净的路径序列并按下Stop!卡住时会停止它(因为会生成!当然,退出程序。)你可以在这里获得可执行文件:http://www.svalli.com/files/maze.7z有趣的是看它的工作原理,很容易看出为什么/如何卡住。由此,我确信有人会弄清楚如何修复路径生成器,以免它被卡住。或者我调入的用于检测“卡住”状态的代码就足够了?它只是产生了一条可能无法继续的短路径。