Search code examples
crandom-walk

Random walk in a 10X10 array


Write a C program that generates a random walk across a 10x10 array. Initially, the array will contain only dot characters. The program must randomly “walk” from element to element, always going up, down, left, or right by one step. The elements visited by the program will be labeled with the letters A through Z, in the order visited.

It doesn't take the walk to an element that has already a letter assigned (blocked element).If all four directions are blocked, the program must terminate.

I wrote the code for the above question but sometimes the output is just blank, it is just showing a black screen.

#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");
      }
    }

My guess is that the program is stuck in an infinte loop, if so, how do I solve this problem?


Solution

  • Your program has undefined behavior if you access array a out of bounds. This can happen when the random direction is impossible because you reached the borders of the 10x10 array. To avoid this change the order of the conditions to check the index first, e.g.

              if (playeri != 0 && a[playeri - 1][playerj] == '.') {
    

    In some cases you probably end up in a position that has no adjacent positions with a dot, so there is no way to continue. As visited does not get incremented in this case, your loop will not terminate.

    An additional check that there is at least one direction not blocked will fix the endless loop, but is not an optimal solution.

    Your implementation that generates a random direction and then checks if this direction is possible may need several attempts when more fields get blocked. Although it is very unlikely you might even get random numbers that denote blocked ways for a long time.

    To implement the requirement to terminate the program when all directions are blocked and to improve the behavior when many directions are blocked, I suggest to change the algorithm.

    Proposed algorithm:

    • check all 4 directions if it is possible to walk, put all possible directions into an array of at most 4 elements and count the possible directions as n. (Example: if up, down and left are possible, the array will contain up, down, left, (invalid). The count will be n = 3.)
    • if n == 0 (all blocked) terminate loop
    • get a random number from 0 to n - 1 (Example: 0..2)
    • select the direction from the array (Example: random number 1 will select down)
    • move in the selected direction (it has been checked before that it is possible)