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

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

Результаты опроса: Работает?
Да 1 100.00%
Нет 0 0%
Голосовавшие: 1. Вы еще не голосовали в этом опросе

Ответ
 
nic666

offline
Опыт: 5,612
Активность:
Randomize
Собственно в некоторых языках есть такая процедура randomize, которая устанавливает величину randseed в зависимости от текущего времени суток. Соответственно при каждом запуске программы, при использовании randomize, генератор случайных чисел выдает разную последовательность....


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


Знаю что есть в jass такая штука SetRandomSeed(N), можно установить ГСЧ на N, но где взять это случайное N? То есть: где взять время суток?
Или может в jass есть аналог randomize?
подскажите пожалуйста...

Не стоит писать всё название большими буквами.

Отредактировано DioD, 01.09.2006 в 11:19.
Старый 01.09.2006, 09:28
DotA_DR

offline
Опыт: 103
Активность:
Randomize
А разве при каждом запуске эта последовательность не разная?
Старый 01.09.2006, 09:32
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
так вар автоматом походу задает random seed
Старый 01.09.2006, 10:06
DioD

offline
Опыт: 45,134
Активность:
Вар задаёт рандом сид каждый раз так что в этом нет никакой необходимости.
Старый 01.09.2006, 11:12
nic666

offline
Опыт: 5,612
Активность:
Необходимость есть!!!
Как только вы включаете режим Cinematic то тут же выполняется код функции CinematicModeBJ

В котором прописана строчка SetRandomSeed(0)
таким образом, кинематика сбрасывает randseed

nic666 добавил:
Как узнать время суток из вара?
Старый 01.09.2006, 11:48
DotA_DR

offline
Опыт: 103
Активность:
а когда выходишь из режима Cinematic он востанавливается
Код:
function CinematicModeExBJ takes boolean cineMode, force forForce, real interfaceFadeTime returns nothing
    // If the game hasn't started yet, perform interface fades immediately
    if (not bj_gameStarted) then
        set interfaceFadeTime = 0
    endif

    if (cineMode) then
        // Save the UI state so that we can restore it later.
        if (not bj_cineModeAlreadyIn) then
            set bj_cineModeAlreadyIn = true
            set bj_cineModePriorSpeed = GetGameSpeed()
            set bj_cineModePriorFogSetting = IsFogEnabled()
            set bj_cineModePriorMaskSetting = IsFogMaskEnabled()
            set bj_cineModePriorDawnDusk = IsDawnDuskEnabled()
            set bj_cineModeSavedSeed = GetRandomInt(0, 1000000)
        endif

        // Perform local changes
        if (IsPlayerInForce(GetLocalPlayer(), forForce)) then
            // Use only local code (no net traffic) within this block to avoid desyncs.
            call ClearTextMessages()
            call ShowInterface(false, interfaceFadeTime)
            call EnableUserControl(false)
            call EnableOcclusion(false)
            call SetCineModeVolumeGroupsBJ()
        endif

        // Perform global changes
        call SetGameSpeed(bj_CINEMODE_GAMESPEED)
        call SetMapFlag(MAP_LOCK_SPEED, true)
        call FogMaskEnable(false)
        call FogEnable(false)
        call EnableWorldFogBoundary(false)
        call EnableDawnDusk(false)

        // Use a fixed random seed, so that cinematics play consistently.
        call SetRandomSeed(0)
    else
        set bj_cineModeAlreadyIn = false

        // Perform local changes
        if (IsPlayerInForce(GetLocalPlayer(), forForce)) then
            // Use only local code (no net traffic) within this block to avoid desyncs.
            call ShowInterface(true, interfaceFadeTime)
            call EnableUserControl(true)
            call EnableOcclusion(true)
            call VolumeGroupReset()
            call EndThematicMusic()
            call CameraResetSmoothingFactorBJ()
        endif

        // Perform global changes
        call SetMapFlag(MAP_LOCK_SPEED, false)
        call SetGameSpeed(bj_cineModePriorSpeed)
        call FogMaskEnable(bj_cineModePriorMaskSetting)
        call FogEnable(bj_cineModePriorFogSetting)
        call EnableWorldFogBoundary(true)
        call EnableDawnDusk(bj_cineModePriorDawnDusk)
        call SetRandomSeed(bj_cineModeSavedSeed)
    endif
endfunction
Старый 01.09.2006, 11:49
nic666

offline
Опыт: 5,612
Активность:
DotA_DR Ну да, пожалуй ты прав.
А все таки принудительно нельзя никак сделать типа randomize?

nic666 добавил:
Просто я хочу сделать в карте чтобы задавался ключ командой -mapkey NNN
или командой -randomize задавался случайный ключ.
Старый 01.09.2006, 11:58
Mefist
Is it cocktail hour yet?
offline
Опыт: 98,190
Активность:
может можно как то вытащить время игровых суток вара, хз
Старый 01.09.2006, 12:49
DioD

offline
Опыт: 45,134
Активность:
function GetTimeOfDay takes nothing returns real
return GetFloatGameState(GAME_STATE_TIME_OF_DAY)
endfunction
Для этого вообще требуется стэк таймеров, объясняю как он работает.
loop
exitwhen I = 10
call TimerStart(timer[I],999999,false,null)
call TriggerSleepAction(Random(1-100))
set I = I+1
endloop
ВСЕ ТАЙМЕРЫ БУДУТ ПОКАЗЫВАТЬ РАЗНЫЕ ЧИСЛА
Потом мы вытаскивем один таймер берём прошедшее время и устанавливаем сид, ОН никогда не повториться так как таймеры идут вверх.
Можно сделать таймеры периодическими.
запускаем пачку таймеров на случайные периоды 1-10 а в действие добовляем сид ресет.
Старый 01.09.2006, 13:03
nic666

offline
Опыт: 5,612
Активность:
Что то мудренное...
1) я имел ввиду не игровое "время суток", а реальное системное время суток... в игровых сутках нет никакого толку ...
2) стек таймеров... ?
Мне хватило бы и одного таймера и по сравнению с этим, - стек таймеров - просто бесполезное расточительство. Результат ведь одинаковый, проблема в том, что таймер будет всегда стартовать при загрузке карты с одинакового числа, и значит разброса значений не будет...
Даже если это число генерится с помощью Random - это ничем не лучше,...чем просто Random

Можно вообще засекать время пока юзер обдумывает ответ в диалоге-менюшке, ну например при выборе сложности... но время реакции юзера - стремиться к минимуму, и это тоже не подходит...

Единственным решением было бы "внешнее число", именно реальная дата и время суток... но к сожалению не знаю как ее получить...

nic666 добавил:
Может быть, действительно решение: сохранять randseed при старте карты и отсчитывать прочие от этого сохраненного.
Старый 01.09.2006, 13:20
DioD

offline
Опыт: 45,134
Активность:
Таймеры в стеке стартуют не с начала мэп инита, и числа всегда разные.
Старый 01.09.2006, 13:42
nic666

offline
Опыт: 5,612
Активность:
Цитата:
числа всегда разные

но то что написано здесь не "разные"
Цитата:
call TriggerSleepAction(Random(1-100))


чтобы устанавливать random не надо использовать сам random, иначе получиться тавтология, то же самое... и никакое количество таймеров это не исправит.
Идея со стеком таймеров скрывает проблему от самого разработчика карты, но нисколько не решает проблему. Просто запутывает человека...
Старый 01.09.2006, 13:52
DioD

offline
Опыт: 45,134
Активность:
Ты не понмаешь, система таймеров запускается до изменения рандом сида и сохраняет его внутри.
Таким образом числа будут случайными даже если рандом сид изменён.
Просто надо делать таймер стэк, тоесть один таймер запускает другой другой третий и при завершении одного он ресктит еще какойто что ресетит еще один, это очень сложно объяснить, да и сделать сложно.
НО ЭТО РАБОТАЕТ.
Старый 01.09.2006, 14:15
nic666

offline
Опыт: 5,612
Активность:
может и работает но это все лишнее... одного таймера достаточно
Старый 01.09.2006, 15:42
DioD

offline
Опыт: 45,134
Активность:
Ну делай через один раз хочешь.
Старый 01.09.2006, 15:53
nic666

offline
Опыт: 5,612
Активность:
Короче последнее к чему я пришел, выглядит примерно так:
  1. в инициализации сохраняем randseed
  2. там же запускаем таймер
  3. далее в качестве стартового значения ГСЧ для randomize используем SaveRandSeed+TimeExpired
Учитывая то что вар сам инициализирует randseed, получается одного таймера достаточно....
А стек таймеров, по моему мнению, это от лукавого, просто кажется более случайным, и по моему мнению, именно только кажется...
P.S.
Если повезет то скоро мапу доделаю, эдак к 1 октябрю :)
Старый 01.09.2006, 19:26
DioD

offline
Опыт: 45,134
Активность:
Стэк таймеров позволяет использовать его в качестве рандома не применяя каких либо рандомом из нативок вара, но это очень сложно настраивать.
Старый 01.09.2006, 20:17
nic666

offline
Опыт: 5,612
Активность:
ну если говорить о формулах случайного генератора, то можно предложить несколько, например
Xi+1=Sin(Xi+Pi)^5
Xi+1=((Xi+M) mod N)/N, где M и N простые числа желательно 1<N/M<2
и т.п.
замен для штатного ГСЧ можно изобрести предостаточно... и для этого таймеров не нужно вообще...
Я все таки о том "с чего начать", т.е. о стартовом числе для ГСЧ...
Старый 01.09.2006, 21:30
Ответ

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

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

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

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



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