Random walk on 10x10 Array
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;
}
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 . . . .
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
}
}
When you're in for loop.
- Draw a possible direction
int direction = rand()%4;
- 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;
}
}
- If there's no valid move end the for loop>
if( i == 4 ) {
break;
}
- 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.
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.
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)
精彩评论