Выбор случайных символов из массива символов? - PullRequest
1 голос
/ 07 октября 2019

Я очень новичок в C ++ и на этой неделе у меня будет довольно сложное задание. Я не буду вдаваться в подробности, так как не хочу, чтобы работа выполнялась для меня, но может ли кто-нибудь указать мне правильное направление относительно того, как бы я выбрал случайные символы из многомерного массива строк?

char gameZero[16][6] = { {'A','A','C','I','O','T'}, {'A','H','M','O','R','S'}, {'E','G','K','L','U','Y'}, {'A','B','I','L','T','Y'}, {'A','C','D','E','M','P'}, {'E','G','I','N','T','V'}, {'G','I','L','R','U','W'}, {'E','L','P','S','T','U'}, {'D','E','N','O','S','W'}, {'A','C','E','L','R','S'}, {'A','B','J','M','O','Q'}, {'E','E','F','H','I','Y'}, {'E','H','I','N','P','S'}, {'D','K','N','O','T','U'}, {'A','D','E','N','V','Z'}, {'B','I','F','O','R','X'} };

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

Любой совет / советы о том, как это сделать, будет принята с благодарностью - спасибо!

РЕДАКТИРОВАТЬ:

Я попал в точку, где я могу генерировать случайные индексы из обоих массивов, однако текущий способ, которым я это делаю, выводит только один символ, тогда как мне нужен ОДИН символ изкаждый из 16 ассортиментов в массиве. Любые идеи о том, как я могу вывести один из каждого? Я полагаю, что я должен поместить генераторы индекса в какой-то цикл.

mt19937 gen(time(nullptr)); // random number generator

// used to generate random number in specific range 
uniform_int_distribution<int> random_outer(0, outer_size - 1);
uniform_int_distribution<int> random_inner(0, inner_size - 1);

int index_outer = random_outer(gen); // used to generate random outer index
int index_inner = random_inner(gen); // used to generate random inner index

cout << gameZero[index_outer][index_inner] << endl;

Ответы [ 4 ]

2 голосов
/ 07 октября 2019

Вы можете использовать следующий алгоритм:

  • генерировать случайное число x в интервале [0, std::size(gameZero )[
  • генерировать случайное число y в интервале [0, std::size(gameZero[0])[
  • Доступ gameZero[x][y] для случайного символа двумерного массива.
0 голосов
/ 07 октября 2019

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

void shuffleDice() { // shuffles Game #0 dice. 

mt19937 gen(time(nullptr));
uniform_int_distribution<int> random_inner(0, inner_size - 1);

int n = random_inner(gen); // generates random number for inner array 
for (int i = 0; i < 16; i++) // loops through outer array
{
    cout << gameZero[i][n] << '\n';
}

Имейте в виду, я новичок в программировании / C ++, поэтому он может быть не самым красивым, но, тем не менее, работает.

0 голосов
/ 07 октября 2019

Учитывая ваш gameZero типа char[16][6], вам нужно только сгенерировать одно случайное число, которое представляет смещение от начала gameZero в диапазоне (0, sizeof gameZero). Массив любого фундаментального типа (char, int, double, etc...) гарантированно является последовательным в памяти. Кроме того, в вашем случае с типом char каждый char равен 1 байту. Таким образом, вы можете получить доступ к любому из символов в gameZero, вычислив смещение от начала массива.

Как вы обнаружили, C ++ обеспечивает собственную генерацию псевдослучайных чисел . Вы можете выбрать любой из механизмов распространения, чтобы создать случайное распределение. Когда вам нужно получить случайное число из вызова, используя ваш дистрибутив, передавая движок, вы создали экземпляр в качестве аргумента. Например, чтобы использовать создание случайного распределения с помощью std :: mersenne_twister_engine , вы можете сделать:

#include <random>
...
    char gameZero[16][6] = {{'A','A','C','I','O','T'}, 
    ...
    std::random_device rd;              /* random device/seed */
    std::mt19937 gen(rd());             /* standard mersenne_twister_engine */
    std::uniform_int_distribution<> dist(0, sizeof gameZero);    /* dist */

Затем, чтобы выбрать случайный элемент, представляющий смещение в gameZero, выпросто запросите случайное число, используя:

        int off = dist(gen);        /* get random offset in gameZero */

Из смещения элемент [x][y] в gameZero может быть вычислен просто с использованием количества столбцов в вашем массиве (6 в вашем случае)Например,

        int x = off / 6,            /* compute row from offset */
            y = off - 6 * x;        /* compute col from offset */

( примечание: целочисленное деление является преднамеренным при вычислении значения x (строка) выше)

Youзатем можно получить доступ к случайному элементу просто с помощью gameZero[x][y].

Например, если в цикле вы запрашиваете случайное смещение и вычисляете индексы [x][y], как описано выше, вы можете вывести смещение, вычисленные индексы и символ в этом индексе, как показано ниже:

$ ./bin/randarr2d
92 - gameZero[15][2] = F
 9 - gameZero[ 1][3] = O
14 - gameZero[ 2][2] = K
91 - gameZero[15][1] = I
86 - gameZero[14][2] = E
46 - gameZero[ 7][4] = T
92 - gameZero[15][2] = F
33 - gameZero[ 5][3] = N
87 - gameZero[14][3] = N
57 - gameZero[ 9][3] = L
87 - gameZero[14][3] = N
50 - gameZero[ 8][2] = N
10 - gameZero[ 1][4] = R
23 - gameZero[ 3][5] = Y
...

Поймите, вы можете напрямую получить доступ к элементу только с помощью смещения, но это может привести к техническому нарушению границ массива. (например, *(*gameZero + off)) Краткий рассказ о том, что двумерный массив на самом деле представляет собой массив одномерных массивов . Когда вы обращаетесь к массиву, он преобразуется в указатель на его 1-й элемент. В случае двумерного массива это указатель на первый массив . (1-й массив из 6 символов в вашем случае), поэтому, если вы применяете смещение более 5, вы технически обращаетесь к элементу за пределами 1-го массива 1D, даже если вы все еще находитесь в пределах вашего 2D-массива,Вычисление индексов x, y из единого смещения устраняет эту проблему.

Просмотрите все и дайте мне знать, если у вас возникнут дополнительные вопросы.

0 голосов
/ 07 октября 2019
  • предоставить список int с 6 элементами.
  • инициализировать его значениями индекса от 0 до 5.
  • для каждой ячейки на доске: //from 0 - 15.
    • перемешать list-of-int.
    • для каждой доски 4x4: // скажем, максимум 6.
      • установить текущую ячейку текущей доски с элементом в list-of-int на индекс iBoard.
        • //example: board[iBoard][iCell] = listInt[iBoard]
...