在 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。 (示例:如果向上、向下和向左都是可能的,则数组将包含 updownleft(invalid)。计数将为 n = 3。 )
  • if n == 0(全部阻塞)终止循环
  • 得到一个从0n - 1的随机数(例子:0..2
  • select数组的方向(例子:随机数1会selectdown
  • 向 selected 方向移动(之前已经检查过它是可能的)