XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
vfinsider

offline
Опыт: 740
Активность:
Случайный герой
Вот у меня вопрос как можно выбирать случано например из 10 героев когда 5 из них уже взяты.
Т.е например герои под номером 1,5,7,8,9 уже взяты, а 6 игрок берет рандомом героя из оставшегося списка.
Если давать ему рандомом от (1 до 10) то ведь рандом может попасть как раз уже взятых персов.
Даже если будем продолжать цикл до того момента пока рандом не попадет в оставшихся героев, которые еще имеются в таверне, то сколько он может совершить бессмысленных циклов.
Думаю это не совсем оптимально. Есть ли другой способ?
Старый 08.02.2012, 16:51
ScorpioT1000
Работаем
online
Опыт: отключен
Если уже есть взятые, сначала сделай (из твоего примера):
call SaveRandMem(1)
call SaveRandMem(5)
call SaveRandMem(7)
call SaveRandMem(8)
call SaveRandMem(9)
а это сам пример рандома с памятью
// SaveRandMem вызывать не надо - он сам её вызывает, надо только если вручную
set heroid[6] = GetRandomIntMem(1,10) // игрок 6
set heroid[7] = GetRandomIntMem(1,10) // игрок 7
set heroid[8] = GetRandomIntMem(1,10) // игрок 8
// ...
// в результате им выдастся, к примеру: 6, 10 и 3

call ClearRandomIntMem()

Отредактировано ScorpioT1000, 08.02.2012 в 17:31.
Старый 08.02.2012, 17:08
Dartek
Welcome "Deep place"
offline
Опыт: 6,537
Активность:
Каждый раз составлять новую таблицу, сделать таблицы на все случаи жизни.
И как вариант - например если при проверке выясняется что такой герой уже взят - бери героя из следующей/предыдущей ячейки, если она тоже занята - опять следующая, и т.д.
Но вариант ScorpioT1000'а лучше, если понимаешь джасс - юзай его.
Старый 08.02.2012, 17:11
vfinsider

offline
Опыт: 740
Активность:
ScorpioT1000, я как понял ты берешь например число от 1 до 10 и перезаписываешь все исключая числа (1 5 7 8 9)
1- 2
2- 3
3- 4
4- 6
5- 10
и потом зная сколько чисел было исключено это (5) ты просто рандомишь дальше но уже с перезаписаными данными от 1 до (10-5(исключено))
т.е от 1 до 5?
или я не так понял?
vfinsider добавил:
Я вот думал чтобы занести всех героев в массив зная сколько героев всего на карте.
Первый кто пикает ему рандомится герой GetRandomInt(1,количество всех героев на карте)
Потом массив перезаписывается исключая выбранного героя из массива и когда следующий будет рандомить рандом уже пойдет на -1 меньше GetRandomInt(1,количество всех героев на карте-1)
И при этом не будет пустых ячеек из за которых появляются бессмысленные циклы во время проверки рандома.
Старый 08.02.2012, 18:03
ScorpioT1000
Работаем
online
Опыт: отключен
Там всё чуть сложнее,
  1. Сначала генерируется рандомное число. Его копия запоминается в tmp
  2. Потом сверяется - если такое уже есть в памяти и оно большеравно tmp, он его плюсует на 1 и переходит снова в п.2
  3. Если число выше верхней границы, оно бекапится из tmp и минусуется на 1 и го в п.2
  4. Если такое уже есть в памяти и оно меньше tmp, минусует на 1 и го в п.2
  5. Если число меньше нижней границы - значит, все числа заняты, делаем сброс памяти и начинаем с п. 1
  6. В конце просто сохраняем число в памяти и возвращаем
Другими словами, если простой рандом вернул число, которое уже было, мы ищем числа рядом с ним. Это сильно снижает нагрузку в отличие от полного рандома, а шанс заметить "неполность" этого рандома невелик.
Лучше присвой каждому типу героя какой-то номер и потом просто юзай систему выше) если хочешь, конечно... она хорошо работает

Отредактировано ScorpioT1000, 08.02.2012 в 18:23.
Старый 08.02.2012, 18:11
vfinsider

offline
Опыт: 740
Активность:
а понял ты рандомишь таким способом.
если рандом попадает в пустую (уже используюнную) ячейку "I" то рассматривается ячейка выше если эта грань, то рассматривается ячейка нижей "I". (ну или наоборот можно сделать кому как нравиться)
ну и сооствественно если соседние ячейки заняты то рассматриваются соседи соседей?
ну а потом логически идет все дальше пока все ячейки не будут пустыми.
vfinsider добавил:
если по проще то
Dartek, "И как вариант - например если при проверке выясняется что такой герой уже взят - бери героя из следующей/предыдущей ячейки, если она тоже занята - опять следующая, и т.д.
Но вариант ScorpioT1000'а лучше, если понимаешь джасс - юзай его."
тоже самое
Старый 08.02.2012, 18:24
ScorpioT1000
Работаем
online
Опыт: отключен
vfinsider, да, либо если всё занято - аварийная очистка =)
ScorpioT1000 добавил:
"И как вариант - например если при проверке выясняется что такой герой уже взят - бери героя из следующей/предыдущей ячейки, если она тоже занята - опять следующая, и т.д.
тут отличие в том, что я пытаюсь брать рандомное число, а в предложении Dartek он просто перебирает с начала. Ну и плюс это всё грамотно написано с минимумом операций.
Это можно сравнить с падением шариков - если под лежащим шаром что-то уже лежит, он падает рядом)
Ну и можно юзать отрицательные числа...
Старый 08.02.2012, 18:25
vfinsider

offline
Опыт: 740
Активность:
но еще лучше если определять рандомо идти ли нам +1 или на -1 это думаю будет еще рандомнее
vfinsider добавил:
ладно спс ты мне помог определится.
а написать я напишу сам и немного по другому.
тему можно закрывать.
Старый 08.02.2012, 18:40
ScorpioT1000
Работаем
online
Опыт: отключен
но еще лучше если определять рандомо идти ли нам +1 или на -1 это думаю будет еще рандомнее
тогда надо будет дополнительную память, "куда мы уже сходили до этого" (сейчас хватает тока tmp)
закрыто
Старый 08.02.2012, 18:48
ScorpioT1000
Работаем
online
Опыт: отключен
alpha, автор просил снова открыть, некогда писать было...
Старый 09.02.2012, 14:25
vfinsider

offline
Опыт: 740
Активность:
Я думаю сделал по проще.
В начале заношу всех героев в массив под глобальным индексом (чтоб потом можно было ссылатся и знать сколько героев на карте)
set udg_I2=udg_I2+1
set udg_HA[udg_I2]='E00K'
set udg_I2=udg_I2+1
set udg_HA[udg_I2]='U007'
set udg_I2=udg_I2+1
set udg_HA[udg_I2]='U000'
Далее при выборе какого либо героя, зная какой это юнит и под какой ячейкой он записан, удаляем его из массива.
При этом зная сколько у нас героев на карте берем последнего и записываем в пустую ячейку, сокращяя при этом сам массив.
udg_HA[i]=udg_HA[udg_I2]
set udg_HA[udg_I2]=0
set udg_I2=udg_I2-1
То есть при следующим поиске рандомного героя не надо будет боятся пустующей клетки в массиве, мы можем также рандомить, но уже из меньшего списка на одну единицу.

Отредактировано vfinsider, 09.02.2012 в 15:46.
Старый 09.02.2012, 15:31
Dreii
define{name=Dreii age=17}
offline
Опыт: 5,246
Активность:
используем unitpool

Код:
native CreateUnitPool           takes nothing returns unitpool 
 native DestroyUnitPool          takes unitpool whichPool returns nothing 
 native UnitPoolAddUnitType      takes unitpool whichPool, integer unitId, real weight returns nothing 
 native UnitPoolRemoveUnitType   takes unitpool whichPool, integer unitId returns nothing 
 native PlaceRandomUnit          takes unitpool whichPool, player forWhichPlayer, real x, real y, real facing returns unit 
 native  SaveUnitPoolHandle    takes hashtable table, integer parentKey, integer childKey, unitpool whichUnitpool returns boolean 
 native  LoadUnitPoolHandle   takes hashtable table, integer parentKey, integer childKey returns unitpool

ф-ии которые тебе понадобятся
weight- отвеяает за частоту рандомизации с помощью ф-ии PlaceRandomUnit
Старый 09.02.2012, 19:03
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 14:36.