Всем доброго времени суток!
Расскажу вообще в чем моя задумка. Как всем известно, в ИИ-скриптах близзов прописаны четко сформированные волны атаки, по принципу 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 определить четность числа? И может я вообще напрасно страдаю и есть какой то другой способ добиться более адекватного разброса случайных значений?
Всех тех, кто смог осилить весь этот текст заранее благодарю за ответы.

  1. Я бы просто брал большой диапазон рандома (порядка 1000) и потом просто делил результат для получения нужного элемента. Этого обычно более чем хватает - условия и вспомогательные функции не нужны, только арифметика.
  2. Раз уж в дело пошли диапазоны - можно сразу запилить взвешенный рандом вместо обычного - когда у каждого элемента в списке есть свой вес примерно определяющий насколько чаще других этот элемент будет выбираться.
`
ОЖИДАНИЕ РЕКЛАМЫ...
27
по-моему, четность число определяется делением на число 2. если с целыми числами. нужно будет целое число перевести в реальное число
у четных чисел не бывает дроби.
10/2=5 8/2=4 и др
у не четных чисел бывает дроби.
5/2=2.5 31/2=15.5
Есть такая функция как R2I она отсекает дробную часть. Можно благодаря ей узнать есть ли дробная часть.
r = 25.5
r1 = R2I(r) получили 25
r2 = r - I2R(r1) = 0.5
с действительными (не целыми!!) числами можно делить до сих пор пока не станет равно 1.00 или меньше 1.00. Если 1.00 значит четная, иначе нечетная.
Или отделить дробную и целую часть, и попытаться сделать как с целыми числами.
Не нрав ну что делать, jass вообще ограниченная штука. Когда я спрашивал никто не хотел помогать, тогда и собственную библиотеку писал. В вашем способе можно было и по-другому сделать

посмотри у PT153 в либе мат функции мб есть че то.
с lua кодом с этим проблем нет. кроме метатаблиц, Есть функции математические. и там же рандом ывидел.
15
МрачныйВорон, благодарю за наводку. Луа же на 1.26 нет, его позднее завезли?
28
я полностью не осилил текст, прости)
Я определял четное или нечётное число этой функцией
код
private function OddEven takes integer i returns boolean
    local integer ii = 0
    loop
        exitwhen ii >= i
        set ii = ii + 2
    endloop
    if ii != i then
        return true
    endif
    return false
endfunction
24
  1. Я бы просто брал большой диапазон рандома (порядка 1000) и потом просто делил результат для получения нужного элемента. Этого обычно более чем хватает - условия и вспомогательные функции не нужны, только арифметика.
  2. Раз уж в дело пошли диапазоны - можно сразу запилить взвешенный рандом вместо обычного - когда у каждого элемента в списке есть свой вес примерно определяющий насколько чаще других этот элемент будет выбираться.
Принятый ответ
15
prog, звучит интересно, сейчас смутно вспоминаю, что в универе что-то такое было даже у нас. Вполне возможно, что я рассмотрю этот способ. Благодарю.
15
Парни, всех благодарю за ответы! Всем проставил плюсы) Каждый ответ хорош по-своему, к тому же у меня в вопросе сразу 2 вопроса по факту, так что даже не знаю как быть с выбором ответа.
Выберу пожалуй ответ prog, так как он ответил по пунктам, что выглядит более наглядно для человека, который в последствии может найти этот вопрос. Но, повторюсь, другие ответы так же полезны и достойны. В данный момент я использую функцию rsfghd, возможно временно, после работы попробую взять больший интервал, как посоветовал prog.
28
и её вообще нет в common.j
Потому что она в blizzard.j. А пост 2017 года, тогда из новый патчей разве что 1.27 был.

Собственно вопрос в том, можно ли средствами jass определить четность числа?
Моя либа.
function IsEven takes integer a returns boolean
    return a / 2 * 2 == a
endfunction

function IsOdd takes integer a returns boolean
    return a / 2 * 2 != a
endfunction

rsfghd, отвратительная функция.
24
По поводу взвешенного рандома, который я упоминал ранее - один из самых простых способов реализовать его выглядит так
  • при занесении элемента в список, передаем вес с которым этот элемент должен выбираться
  • ведем подсчет суммарного веса всех элементов в списке
  • для каждого элемента заносим в массив суммарный вес на момент добавления элемента
  • при выборе случайного элемента берем рандом от 0 до суммарного веса элементов
  • бинарным поиском или банальным перебором находим элемент, в диапазон которого попал рандом, используя ранее записанные в массив значения суммарного веса на момент добавления элемента
25
Мда, приехали, люди не знают что четные числа это те, которые делятся на 2 🤦
Чтобы оставить комментарий, пожалуйста, войдите на сайт.