Случайная прогулка по массиву 10х10 - PullRequest
1 голос
/ 04 апреля 2011

У меня проблема с выяснением алгоритма для этой проблемы, пытался в течение нескольких дней безуспешно, вот картинка того, что я пытаюсь получить:

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

Вот мой код, пробовал много разных решений, но всегда застреваю в одной и той же точке: (Извините за смешанный язык, важная часть на английском)

п.с. я не должен использовать функции для решения этой проблемы только циклы и массив.

EDIT после долгих исправлений он делает прогулку, но редко падает есть идеи?

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

Ответы [ 5 ]

4 голосов
/ 04 апреля 2011

Вам необходимо обновить row и col внутри цикла. В противном случае вы всегда будете пытаться идти с позиции «А».

... и как только все 4 направления заполнены, вы застряли в бесконечном цикле

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

Даже когда вы обновляете row и col внутри цикла (и исправляете ошибку ==), вы должны решить проблему: предположим, что первая точка ('A') - это верхний левый угол следующие случайные направления: восток, юг, юг, запад и север. ... что теперь? :)

A B .
F C .
E D .
. . .
1 голос
/ 04 апреля 2011

Когда вы в цикле.

  1. Нарисуйте возможное направление

int direction = rand()%4;
  1. Проверить все возможные направления, если нарисованное является недопустимым (не в массиве или не ".")

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. Если нет действительного хода, завершите цикл for>

if( i == 4 ) {
    break;
}
  1. В противном случае напишите письмо в ячейку таблицы и обновите положение строки / столбца.

box[row][col] = letter;

И ... это все, что я думаю. Это жадный алгоритм, поэтому вам не нужно никаких оптимизаций (по крайней мере, я не вижу никаких требований в упражнениях.

0 голосов
/ 04 апреля 2011

Не рекомендуется «перебирать» случайное число, когда вы обнаружите, что не можете двигаться в каком-то направлении, потому что, если вам не повезло, вы получаете одно и то же число дважды (или даже 3, 4 или более раз) -так что даже если вы сгенерировали 4 случайных числа и все они потерпели неудачу, это не значит, что вы застряли.

Вы можете решить эту проблему, сгенерировав одно число и попробовав все 4 возможных направления, начиная с него:

Если генератор случайных чисел возвратил 0: проверьте 0, 1, 2, 3

Если генератор случайных чисел возвратил 1: проверьте 1, 2, 3, 0

Если генератор случайных чисел возвратил 2: проверка 2, 3, 0, 1

Если генератор случайных чисел возвратил 3: проверка 3, 0, 1, 2

Реализуется следующим кодом:

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
}

Обратите внимание, что этот алгоритм не очень случайный: если вы не можете подняться вверх, есть большая вероятность того, что вы пойдете вниз, чем вправо или влево.Если вы хотите исправить это, вы можете выбрать случайную перестановку из 4 направлений вместо последовательной проверки направлений:

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
    }
}
0 голосов
/ 04 апреля 2011

где именно он ломается?

Из того, что я могу сразу увидеть, я вижу, что у вас есть шанс, что It_that_walks встанет на позицию, с которой он никуда не может пойти:

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

где после J?

Нет необходимости в && (box[row][col-1]= '.')

Кроме того, это неправильно (назначение вместо сравнения), оно должно быть: && (box[row][col-1]== '.') (но вам оно вообще не нужно)

0 голосов
/ 04 апреля 2011

Похоже, что вы отказываетесь от своего оператора switch, если вы пытаетесь пойти в направлении, которое недопустимо, но вы все равно увеличиваете свой счетчик. Попробуйте проверить другое случайное направление, если это произойдет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...