2

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?

Humble
  • 39
  • 9
  • 2
    First of all indent your code. Poorly indented code is hard to debug. – Jabberwocky Apr 02 '20 at 08:13
  • 4
    You are going out of bounds when e.g. `playeri` is 0 and you do `playeri-1` and the program crashes. – rustyx Apr 02 '20 at 08:15
  • 1
    Thank you! will edit it rn. – Humble Apr 02 '20 at 08:15
  • 1
    @rustyx not quite true, the program doesn't crash, but rather the program has undefined behaviour that _might_ lead to all kinds of strange things including a crash. – Jabberwocky Apr 02 '20 at 08:16
  • 2
    @Humble be aware that correctly indented code is not so much for us but for rather for _you_ – Jabberwocky Apr 02 '20 at 08:16
  • 4
    What is the expected end condition for the walk? All positions visited? No possible way to continue? Please [edit] your question to explain this. – Bodo Apr 02 '20 at 08:16
  • I have edited the question.please check – Humble Apr 02 '20 at 08:22
  • Is that the real program? It does not compile: a closing `)` seems missing – Mathieu Apr 02 '20 at 08:23
  • it is a real program but it seems I have missed a ( , while trying to indent the program.Sorry for the inconvenience. – Humble Apr 02 '20 at 08:24
  • 7
    "If all four directions are blocked, the program must terminate." - you haven't implemented this. – Rup Apr 02 '20 at 08:25
  • the ( is missing in the first for loop where i assigned the array element with a dot ' . ' – Humble Apr 02 '20 at 08:25
  • 4
    You should check the index first before accessing the array to avoid out-of-bounds access, e.g. `if (playeri != 0 && a[playeri - 1][playerj] == '.') {`. I guess in some cases you end up in a position that has no adjacent position with a dot, so there is no way to continue. As `visited` does not get incremented your loop will not end in this case – Bodo Apr 02 '20 at 08:26
  • Thank you Rup and Bodo i wrote an if condition above the code in while loop which checks if there are any directions available and it runs!! thank you – Humble Apr 02 '20 at 08:39

1 Answers1

4

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)
Bodo
  • 9,287
  • 1
  • 13
  • 29
  • Thank you! I checked with an if condition inside the while loop that,if there are any direction possible to move.Now the code is not running into an infinite loop. – Humble Apr 02 '20 at 09:02
  • I just added this if condition if(a[playeri-1][playerj]=='.' || a[playeri+1][playerj]=='.' || a[playeri][playerj+1]=='.' || a[playeri][playerj-1]=='.') and kept the rest of the code it is now running. Thanks again . – Humble Apr 02 '20 at 09:02
  • 1
    @Humble Sure it works with your minimal change. You may not notice it, but it can happen that you have a field with only one possible direction and you might have many loops in which you get random numbers that select blocked directions. With my proposed algorithm the program would never try to choose blocked directions. – Bodo Apr 02 '20 at 11:42
  • Thanks! I just noticed it sometimes my program run into problems but the frequency of this happening is low ,that's why I thought my code is running fine. – Humble Apr 02 '20 at 18:15