Intereting Posts
Как преобразовать целочисленный массив в строку без использования библиотеки Схема памяти объединения члена разного размера? Наиболее эффективное умножение матрицы в C с использованием fork () и IPC глубокая копия Linkedlist без уничтожения исходного списка и дополнительного пространства для хранения (с использованием ANSI C) Функция main (), определенная без возвращаемого типа, дает предупреждение Поверните строку C с NULL байтами в массив символов Указатели, многомерные массивы и адреса std :: bad_alloc после замены boost: shell функции python с API Python / C Сокращение использования стека во время рекурсии с помощью GCC + ARM почему прозрачный флаг интерприта вызывает ошибку сегментации в C? Как объявить массив с произвольным размером Функция в C с неограниченными аргументами? OSX: CGGlyph для UniChar Определение функции внутри другого определения функции: действительно ли это? Связь клиента с клиентом с помощью функции select () в c

Случайное перемещение по массиву 10×10

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

http://sofru.miximages.com/c/X70nX.png

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

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

РЕДАКТИРОВАТЬ после многого исправления, но делает это редко, но редко вызывает какие-либо идеи?

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

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

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

     ,  ,  ,  ,  ,
     ,  ,  B.  ,
     ,  EAC.
     ,  ,  D.  ,
    

    Даже когда вы обновляете row и col внутри цикла (и исправляете ошибку == ), вам приходится решать проблему: предположим, что первое место («A») – это верхний левый угол, а следующие случайные направления: Восток, Юг , Юг, Запад и Север. … что теперь? 🙂

     AB.
     ФК.
     ED.
     ,  ,  ,
    

    Когда вы находитесь в цикле.

    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; 

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

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

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

    из того, что я вижу с первого взгляда, является то, что у вас есть шанс, что It_that_walks встанет на свои места от ведьмы,

     ABCD . . IJE . . HGF . 

    где после J?

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

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

    Не рекомендуется «перезапускать» случайное число, когда вы обнаруживаете, что не можете идти в определенном направлении, потому что, если вам не повезло, вы получаете одинаковый номер дважды (или даже 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 } }