Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Обзор Unity.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
7.91 Mб
Скачать

Перемешивание списка

Довольно часто встречающаяся в играх механика - выбор из известного набора элементов, но со случайным порядком. Например, колода карт обычно перемешана, поэтому их не выбрать в предсказуемой последовательности. Вы можете перемешивать элементы в массиве путём “посещения” каждого из элементов и его обмена местами с другим элементом, случайно выбранным из массива:-

//JS

function Shuffle(deck: int[]) {

for (i = 0; i < deck.Length; i++) {

var temp = deck[i];

var randomIndex = Random.Range(0, deck.Length);

deck[i] = deck[randomIndex];

deck[randomIndex] = temp;

}

}

//C#

void Shuffle (int[] deck) {

for (int i = 0; i < deck.Length; i++) {

int temp = deck[i];

int randomIndex = Random.Range(0, deck.Length);

deck[i] = deck[randomIndex];

deck[randomIndex] = temp;

}

}

Выбор элементов из набора без повторений

Распространённая задача - случайно выбрать какое-то количество элементов из массива без повторного выбора одного и того же значения. Например, вы можете захотеть сгенерировать какое-то количество NPC в случайных точках генерации, но при этом вы желаете, чтобы только один NPC генерировался в каждой из точек. Это можно реализовать с помощью перебора последовательности элементов, решая для каждого случайным образом - быть ему добавленным в выбранный набор или нет. После “посещения” каждого элемента, вероятность того, что он будет выбран равна числу ещё требующихся элементов, разделённому на число оставшихся для выбора элементов.

В качестве примера, представьте, что существует десять точек генерации, но выбрать можно только пять. Вероятность выбора первого элемента будет равна 5 / 10 или 0.5. Если он выбран, то вероятность выбора второго элемента - 4 / 9, или 0.44 (то есть требуется ещё 4 элемента и ещё 9 доступно для выбора). Однако, если первый элемент не был выбран, то вероятность выбора второго элемента - 5 / 9, или 0.56 (то есть ещё требуется выбрать 5 элементов и ещё 9 доступно для выбора). Это продолжается до тех пор, пока набор не будет состоять из требуемых пяти элементов. Вы можете реализовать это в коде таким образом:-

//JS

var spawnPoints: Transform[];

function ChooseSet(numRequired: int) {

var result = new Transform[numRequired];

var numToChoose = numRequired;

for (numLeft = spawnPoints.Length; numLeft > 0; numLeft--) {

// Adding 0.0 is simply to cast the integers to float for the division.

var prob = numToChoose + 0.0 / numLeft + 0.0;

if (Random.value <= prob) {

numToChoose--;

result[numToChoose] = spawnPoints[numLeft - 1];

if (numToChoose == 0)

break;

}

}

return result;

}

//C#

Transform[] spawnPoints;

Transform[] ChooseSet (int numRequired) {

Transform[] result = new Transform[numRequired];

int numToChoose = numRequired;

for (int numLeft = spawnPoints.Length; numLeft > 0; numLeft--) {

float prob = numToChoose/numLeft;

if (Random.value <= prob) {

numToChoose--;

result[numToChoose] = spawnPoints[numLeft - 1];

if (numToChoose == 0) {

break;

}

}

}

return result;

}

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