Random walk on 10x10 Array

梦想的初衷 提交于 2020-01-03 02:48:06

问题


i am having a problem figuring out an algorithm for this problem,been trying for few days without success,here is a pic of what im trying to obtain:

http://i.stack.imgur.com/X70nX.png

Here is my code tried many differents solutions but always get stuck at the same point:(Sorry for mixed language the important part is in english)

ps im not supposed to use functions to solve this problem only loops and array.

EDIT after much fixing it does the walk but seldomly crashes any idea?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void){

char box[10][10];
int i,j;
int move,row,col;
char letter='A';
srand(time(NULL)); 

printf("\n\tSTART\n\n");

for(i=0;i < 10 ;i++)/* righe */
{
 for(j=0;j < 10;j++) /* colonne */
 {
  box[i][j] = '.'; /* assegno . a tutti gli elementi dell array */
  if(j == 9)
   printf("%c%c\n", box[i][j]); /* giustifico ogni 10 elementi dell array j(0-9) */
   else 
   printf("%c%c", box[i][j]);
  }
}


/* LETS START */ 

printf("\n\n    Inizia il gioco\n\n");

/* random place to start */

row = rand() % 9;
col = rand() % 9;
box[row][col]= 'A';


while(letter <= 'Z')
{
 if(box[row+1][col] == '.' || box[row-1][col] == '.' || box[row][col+1] == '.' || box[row][col-1] == '.' )
 {
 move=rand() % 4;
 switch(move){
              case 0: /* Going UP */
                    if((row != 0) && (box[row-1][col] == '.'))
                    {
                            box[row-1][col]=++letter;
                            box[row--][col];
                    }else{
                          move=rand() % 4;
                          }
              case 1:/* Going Down */
                   if((row != 9) && (box[row+1][col] == '.'))
                   {
                           box[row+1][col]=++letter;
                           box[row++][col];
                   }else{
                         move=rand() % 4;
                         }
              case 2: /*Going Left */
                   if((col != 0) && (box[row][col-1] == '.'))
                   {
                           box[row][col-1]=++letter;
                           box[row][col--];
                   }else{
                         move=rand() % 4;
                         }
              case 3: /* Going Right */
                   if((col != 9) && (box[row][col+1] == '.') )
                   {
                           box[row][col+1]=++letter;
                           box[row][col++];
                   }else{
                         move=rand() % 4;
                         }
              }
 }else{
        printf("\n\nBloccato a %c\n\n", letter);
        break;
 }
}


 /* FINE */

for(i=0;i<10;i++)/* righe */
{
 for(j=0;j<10;j++) /* colonne */
 {
   if(j == 9)
     printf("%c%c\n", box[i][j]); /* giustifico ogni 10 elementi dell array j(0-9) */
    else 
     printf("%c%c", box[i][j]);
 }  
}
return 0;
}

回答1:


You need to update row and col inside the loop. Otherwise you'll always attempt to walk from the position of the 'A'.

... and once all 4 directions are filled, you're stuck in a infinite loop

. . . . .
. . B . .
. E A C .
. . D . .

Even when you update row and col inside the loop (and correct the == mistake), you have to handle a problem: suppose the first spot (the 'A') is the top left corner and the next random directions are East, South, South, West, and North. ... now what? :)

A B .
F C .
E D .
. . .



回答2:


When you're in for loop.

  1. Draw a possible direction

int direction = rand()%4;
  1. Check all possible directions if the drawed one is invalid (not in array or not a ".")

int i=-1;
while( ++i < 4 )
{
    switch(direction) 
    {
        case 0:
            if( row-1 >= 0 && box[row-1][col] == '.' ) {
                --row;
                i = -1;    
            }
            break;
        case 1:
            if( col+1 < 10 && box[row][col+1] == '.' ) {
                ++col;
                i = -1;    
            }
            break;
        case 2:
            if( row+1 < 10 && box[row+1][col] == '.' ) {
                ++row;
                i = -1;
            }
            break;
        case 3:
            if( col-1 >= 0 && box[row][col-1] == '.' ) {
                --col;
                i = -1;
            }
            break;
    }

    if( i != -1 ) {
        direction = (direction+1)%4;
    }
    else {
        break;
    }
}
  1. If there's no valid move end the for loop>

if( i == 4 ) {
    break;
}
  1. Otherwise write a letter to the table cell and update row/col position.

box[row][col] = letter;

And... that's all I guess. This is greedy algorithm so you don't need any optimizations (at least I don't see any in exercise requirements.




回答3:


It looks like you are breaking out of your switch statement if you try to go in a direction that isn't valid, but you increment your counter anyway. Try to check another random direction if that happens.




回答4:


where exactly does it break?

from what I can see at a glance is that you have a chance that It_that_walks gets in position from witch it cant go anywhere:

A B C D .
. I J E .
. H G F .

where after J?

There is no need for the && (box[row][col-1]= '.')

Allso, it is wrong (assignment instead of comparison), it should be: && (box[row][col-1]== '.') (but you dont need it alltogether)




回答5:


It's not a good idea to "reroll" the random number when you discover that you cannot go in some direction, because if you have bad luck, you get the same number twice (or even 3 or 4 or more times) - so even if you generated 4 random numbers and they all failed, that doesn't mean that you're stuck.

You can solve this problem by generating one number, and trying all 4 possible directions starting from it:

If the random number generator returned 0: check 0, 1, 2, 3

If the random number generator returned 1: check 1, 2, 3, 0

If the random number generator returned 2: check 2, 3, 0, 1

If the random number generator returned 3: check 3, 0, 1, 2

Implemented by the following code:

desired_move = rand();
success = 0;
for (i = 0; i < 4 && !success; ++i)
{
    move = (desired_move + i) % 4;
    switch (move)
    {
    case 0: // Go up
        if (row > 0 && box[row - 1][col] == '.')
        {
            row = row - 1;
            success = 1;
        }
        break;
    case 1: // Go down
        ...
    }
}
if (!success) // Tried all 4 directions but failed! You are stuck!
{
    goto START_OVER; // or whatever else
}

Note that this algorithm is not very random: if you cannot go up, there is a greater chance that you go down than right or left. If you want to fix it, you can pick a random permutation of 4 directions instead of checking the directions sequentially:

const int permutation_table[24][4] = {
    {0, 1, 2, 3},
    {0, 1, 3, 2},
    {0, 2, 1, 3},
    ...
    {3, 2, 1, 0}
};
index = rand() % 24;
for (i = 0; i < 4; ++i)
{
    move = permutation_table[index][i];
    switch (move) {
    ... // As above
    }
}


来源:https://stackoverflow.com/questions/5542267/random-walk-on-10x10-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!