在 10X10 阵列中随机游走
Random walk in a 10X10 array
编写一个 C 程序,生成一个 10x10 数组的随机游走。最初,该数组将仅包含点字符。程序必须随机地从一个元素“行走”到另一个元素,总是向上、向下、向左或向右一步。程序访问的元素将按访问顺序标有字母 A 到 Z。
它不会走到一个已经分配了字母的元素(阻塞元素)。如果所有四个方向都被阻塞,程序必须终止。
我为上述问题编写了代码,但有时输出只是空白,只是显示黑屏。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
char visited = 'A';
char a[10][10];
// assigning value '.' to array elements
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
a[i][j] = '.';
// the initial is set for the player.
int playeri, playerj;
srand(time(0));
// assigning numbers between 0-9
playeri = rand() % 10; playerj = rand() % 10;
a[playeri][playerj] = visited++;
int move;
// now to move the player
while (visited <= 'Z') {
// to generate numbers between 1-4
move = rand() % 4 + 1;
// to move up
if (move == 1) {
if (a[playeri - 1][playerj] == '.' && playeri != 0) {
playeri = playeri - 1;
a[playeri][playerj] = visited++;
}
}
// to move down
else if (move == 2) {
if (a[playeri + 1][playerj] == '.' && playeri != 9) {
playeri = playeri + 1;
a[playeri][playerj] = visited++;
}
}
// to move right
else if (move == 3) {
if (a[playeri][playerj + 1] == '.' && playerj != 9) {
playerj = playerj + 1;
a[playeri][playerj] = visited++;
}
}
// to move left
else if (move == 4) {
if (a[playeri][playerj - 1] == '.' && playerj != 0) {
playerj = playerj - 1;
a[playeri][playerj] = visited++;
}
}
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
printf("%c", a[i][j]);
}
printf("\n");
}
}
我的猜测是程序陷入了无限循环,如果是这样,我该如何解决这个问题?
如果您越界访问数组 a
,您的程序会出现未定义的行为。当您到达 10x10 阵列的边界而无法随机方向时,就会发生这种情况。为避免这种情况,请先更改条件顺序以检查索引,例如
if (playeri != 0 && a[playeri - 1][playerj] == '.') {
在某些情况下,您可能最终会遇到没有带点的相邻位置的位置,因此无法继续。由于 visited
在这种情况下不会增加,因此您的循环不会终止。
额外检查至少有一个方向未被阻挡将修复死循环,但这不是最佳解决方案。
您的实现生成一个随机方向,然后检查该方向是否可行,当更多字段被阻止时可能需要多次尝试。
尽管您甚至不太可能获得表示长时间阻塞方式的随机数。
为了实现当所有方向都被阻止时终止程序的要求,并改善当许多方向被阻止时的行为,我建议改变算法。
建议算法:
- 检查所有4个方向是否可以行走,将所有可能的方向放入一个最多4个元素的数组中,将可能的方向数为
n
。 (示例:如果向上、向下和向左都是可能的,则数组将包含 up
、down
、left
、(invalid)
。计数将为 n = 3
。 )
- if
n == 0
(全部阻塞)终止循环
- 得到一个从
0
到n - 1
的随机数(例子:0
..2
)
- select数组的方向(例子:随机数
1
会selectdown
)
- 向 selected 方向移动(之前已经检查过它是可能的)
编写一个 C 程序,生成一个 10x10 数组的随机游走。最初,该数组将仅包含点字符。程序必须随机地从一个元素“行走”到另一个元素,总是向上、向下、向左或向右一步。程序访问的元素将按访问顺序标有字母 A 到 Z。
它不会走到一个已经分配了字母的元素(阻塞元素)。如果所有四个方向都被阻塞,程序必须终止。
我为上述问题编写了代码,但有时输出只是空白,只是显示黑屏。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
char visited = 'A';
char a[10][10];
// assigning value '.' to array elements
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
a[i][j] = '.';
// the initial is set for the player.
int playeri, playerj;
srand(time(0));
// assigning numbers between 0-9
playeri = rand() % 10; playerj = rand() % 10;
a[playeri][playerj] = visited++;
int move;
// now to move the player
while (visited <= 'Z') {
// to generate numbers between 1-4
move = rand() % 4 + 1;
// to move up
if (move == 1) {
if (a[playeri - 1][playerj] == '.' && playeri != 0) {
playeri = playeri - 1;
a[playeri][playerj] = visited++;
}
}
// to move down
else if (move == 2) {
if (a[playeri + 1][playerj] == '.' && playeri != 9) {
playeri = playeri + 1;
a[playeri][playerj] = visited++;
}
}
// to move right
else if (move == 3) {
if (a[playeri][playerj + 1] == '.' && playerj != 9) {
playerj = playerj + 1;
a[playeri][playerj] = visited++;
}
}
// to move left
else if (move == 4) {
if (a[playeri][playerj - 1] == '.' && playerj != 0) {
playerj = playerj - 1;
a[playeri][playerj] = visited++;
}
}
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
printf("%c", a[i][j]);
}
printf("\n");
}
}
我的猜测是程序陷入了无限循环,如果是这样,我该如何解决这个问题?
如果您越界访问数组 a
,您的程序会出现未定义的行为。当您到达 10x10 阵列的边界而无法随机方向时,就会发生这种情况。为避免这种情况,请先更改条件顺序以检查索引,例如
if (playeri != 0 && a[playeri - 1][playerj] == '.') {
在某些情况下,您可能最终会遇到没有带点的相邻位置的位置,因此无法继续。由于 visited
在这种情况下不会增加,因此您的循环不会终止。
额外检查至少有一个方向未被阻挡将修复死循环,但这不是最佳解决方案。
您的实现生成一个随机方向,然后检查该方向是否可行,当更多字段被阻止时可能需要多次尝试。 尽管您甚至不太可能获得表示长时间阻塞方式的随机数。
为了实现当所有方向都被阻止时终止程序的要求,并改善当许多方向被阻止时的行为,我建议改变算法。
建议算法:
- 检查所有4个方向是否可以行走,将所有可能的方向放入一个最多4个元素的数组中,将可能的方向数为
n
。 (示例:如果向上、向下和向左都是可能的,则数组将包含up
、down
、left
、(invalid)
。计数将为n = 3
。 ) - if
n == 0
(全部阻塞)终止循环 - 得到一个从
0
到n - 1
的随机数(例子:0
..2
) - select数组的方向(例子:随机数
1
会selectdown
) - 向 selected 方向移动(之前已经检查过它是可能的)