Всем доброго времени суток!
Расскажу вообще в чем моя задумка. Как всем известно, в ИИ-скриптах близзов прописаны четко сформированные волны атаки, по принципу 2 стрелка, 4 пехотинца и т.д. Я решил накидать свой рандомизатор атаки, который из массива с типами юнитов выбирал бы типы, а перед этой выборкой рандомно бы определял, сколько типов войск войдет в отряд атаки. К сожалению стандартный рандом совсем не оправдал моих ожиданий
Расскажу вообще в чем моя задумка. Как всем известно, в ИИ-скриптах близзов прописаны четко сформированные волны атаки, по принципу 2 стрелка, 4 пехотинца и т.д. Я решил накидать свой рандомизатор атаки, который из массива с типами юнитов выбирал бы типы, а перед этой выборкой рандомно бы определял, сколько типов войск войдет в отряд атаки. К сожалению стандартный рандом совсем не оправдал моих ожиданий
set quantityUnitTypes = GetRandomInt(1, maxQuantityUnitTypes)
где maxQuantityUnitTypes в конкретном случае на момент написания данного вопроса, 6(На основе написанного скрипта с рандомизатором я планирую писать другие скрипты, где в сам рандомизатор мне придется внести минимум изменений, меняя лишь параметры, например максимальное количество разных родов войск в волне нападения). Но стандартный рандом мне выдал следующую последовательность "случайных" значений: 1 6 6 6 6. После этого было решено придумать какие то танцы вокруг рандома, чтобы как то улучшить ситуацию. Я придумал увеличить верхнюю границу по следующей формуле: maxQuantityUnitTypes * 20. Соответственно в конкретном случае, выходит:
set quantityUnitTypes = GetRandomInt(1, 120)
(6 * 20). Суть задумки в том, чтобы создать бОльший интервал для рандома и разбить его на диапазоны, например так:
И была написана вспомогательная функция:
//============================================================================
// Определяет, входит ли значение в диапазон
//============================================================================
function ValueInRange takes integer value, integer rangeStart, integer rangeEnd returns boolean
return value >= rangeStart and value <= rangeEnd
endfunction
В итоге сейчас у меня распределение работает следующим образом:
if ValueInRange(quantityUnitTypes, 1, 10) or ValueInRange(quantityUnitTypes, 111, 120) then
set quantityUnitTypes = 1
call DisplayTextToPlayer(Player(6), 0.0, 0.0, "quantity = 1")
elseif ValueInRange(quantityUnitTypes, 11, 20) or ValueInRange(quantityUnitTypes, 101, 110) then
set quantityUnitTypes = 2
call DisplayTextToPlayer(Player(6), 0.0, 0.0, "quantity = 2")
elseif ValueInRange(quantityUnitTypes, 21, 30) or ValueInRange(quantityUnitTypes, 91, 100) then
set quantityUnitTypes = 3
call DisplayTextToPlayer(Player(6), 0.0, 0.0, "quantity = 3")
elseif ValueInRange(quantityUnitTypes, 31, 40) or ValueInRange(quantityUnitTypes, 81, 90) then
set quantityUnitTypes = 4
call DisplayTextToPlayer(Player(6), 0.0, 0.0, "quantity = 4")
elseif ValueInRange(quantityUnitTypes, 41, 50) or ValueInRange(quantityUnitTypes, 71, 80) then
set quantityUnitTypes = 5
call DisplayTextToPlayer(Player(6), 0.0, 0.0, "quantity = 5")
elseif ValueInRange(quantityUnitTypes, 51, 70) then
set quantityUnitTypes = 6
call DisplayTextToPlayer(Player(6), 0.0, 0.0, "quantity = 6")
endif
Это дало свои результаты, теперь результат меня устраивает, формируются отряды разной длины, редко когда бывает, что подряд в атаку идут отряды одной и той же длины. Однако я решил так же попробовать такой вариант распределения диапазонов:
и алгоритмизировать это дело, чтобы в последствии можно было менять лишь параметры. Для второго способа мне понадобилось определять четность числа, в связи с чем родился данный вопрос. Я нашел лишь xgm.guru/p/wc3/189541, но там функция, которая не работает в ИИ-потоке, и её вообще нет в common.j. Возможно она была добавлена в последних патчах от близзард, я же до сих пор на 1.26 и не признаю существование патчей выше. Да, пишу на чистом jass, если это имеет значение. Собственно вопрос в том, можно ли средствами jass определить четность числа? И может я вообще напрасно страдаю и есть какой то другой способ добиться более адекватного разброса случайных значений?
Всех тех, кто смог осилить весь этот текст заранее благодарю за ответы.
Принятый ответ
- Я бы просто брал большой диапазон рандома (порядка 1000) и потом просто делил результат для получения нужного элемента. Этого обычно более чем хватает - условия и вспомогательные функции не нужны, только арифметика.
- Раз уж в дело пошли диапазоны - можно сразу запилить взвешенный рандом вместо обычного - когда у каждого элемента в списке есть свой вес примерно определяющий насколько чаще других этот элемент будет выбираться.
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Ред. MpW
10/2=5 8/2=4 и др
у не четных чисел бывает дроби.
5/2=2.5 31/2=15.5
r = 25.5
r1 = R2I(r) получили 25
r2 = r - I2R(r1) = 0.5
Или отделить дробную и целую часть, и попытаться сделать как с целыми числами.
Я определял четное или нечётное число этой функцией
Ред. prog
Выберу пожалуй ответ prog, так как он ответил по пунктам, что выглядит более наглядно для человека, который в последствии может найти этот вопрос. Но, повторюсь, другие ответы так же полезны и достойны. В данный момент я использую функцию rsfghd, возможно временно, после работы попробую взять больший интервал, как посоветовал prog.
Ред. PT153