4. Условия, циклы в jass Рассмотрим такой пример: имеется фрагмент триггерного действия For each (Integer i) from 1 to 10, do (Actions) Цикл If (All Conditions are True) then do (Then Actions) else do (Else Actions) Условие i равно 1 Действие Set s = (s + 2) Иначе Set s = (s + 1) Цикл по i от 1 до 10 и условие внутри цикла. Во что превратится это действие, когда мы переведем его в jass? Создай в редакторе такой триггер и проверь. Действие превратится в следующий фрагмент set udg_i = 1 loop exitwhen udg_i > 10 if ( Trig_____________________________________001_Func001Func001C() ) then set udg_s = ( udg_s + 2 ) else set udg_s = ( udg_s + 1 ) endif set udg_i = udg_i + 1 endloop Думаю, что пока не очень понятно, что здесь за что отвечает. Начнем с оператора if. Очевидно, он превратился в строки: if ( Trig_____________________________________001_Func001Func001C() ) then set udg_s = ( udg_s + 2 ) else set udg_s = ( udg_s + 1 ) endif Все что ниже первой строки - понятно, но почему вместо нормального условия в первой строке стоит "( Trig_____________________________________001_Func001Func001C() )"? Дело в том, что редактор триггеров довольно глупо переводит условия из триггеров или триггерных действий. После такого перевода часто приходится исправлять и оптимизировать код. В нашем случае, редактор создал специальную функцию с именем Trig_____________________________________001_Func001Func001C() для того, чтобы проверить нужное нам условие, что i=1. Эту функцию ты можешь увидеть вверху триггера: function Trig_____________________________________001_Func001Func001C takes nothing returns boolean if ( not ( udg_i == 1 ) ) then return false endif return true endfunction Пока не будем вдаваться в то, что это за функция и что она делает. Самое главное - эта функция возвращает значение true (истина) если i=1, или ложь, если i не равно 1. Возникает вопрос: что же, при каждом применении оператора if нам придется создавать какую-то функцию? Ничего подобного - можно обойтись и без нее! Стираем эту ненужную функцию, а в строчку вносим изменения: if (udg_i == 1) then И все. остальное оставляем неизменным. У нас получится фрагмент кода: set udg_i = 1 loop exitwhen udg_i > 10 if (udg_i == 1) then set udg_s = ( udg_s + 2 ) else set udg_s = ( udg_s + 1 ) endif set udg_i = udg_i + 1 endloop Теперь ты знаешь, что такое оптимизация :). Но остается открытым вопрос: что же такое мы вставили в условие оператора if. Это просто проверка, равна ли переменная i единице. В jass есть специальные значки для проверки условий равенства или неравенства: == (два знака равно) переводится как равно != переводится как не равно < меньше > больше <= меньше или равно >= больше или равно. Т.е. если мы хотим записать условие **i[.b] не равно 10, то оно будет выглядеть i!=10 Теперь ты можешь сам разобраться с условным оператором в jass: if (udg_i == 1) then set udg_s = ( udg_s + 2 ) else set udg_s = ( udg_s + 1 ) endif Переводится как "Если i=1 то делать то-то иначе делать то-то". Хорошо, с условным оператором разобрались. А как насчет циклов? К оператору цикла относятся следующие строки: set udg_i = 1 loop exitwhen udg_i > 10 ... set udg_i = udg_i + 1 endloop ... - это могут быть любые действия, которые происходят внутри цикла Итак, перед началом цикла переменной i присваивается значение 1 - это начальное значение для нашего цикла. loop - ключевое слово, означающее начало цикла endloop - конец цикла Т.е. действия между loop и endloop будут повторяться. Но сколько раз они должны повторяться? Вообще говоря, 10. Но в jass все циклы устроены более универсально, чем в триггерах. Тут циклы повторяются не ОПРЕДЕЛЕННОЕ ЧИСЛО РАЗ, а ДО ТЕХ ПОР, ПОКА НЕ БУДЕТ ВЫПОЛНЕНО ТАКОЕ-ТО УСЛОВИЕ. За проверку этого условия отвечает строка: exitwhen <УСЛОВИЕ> - переводится как выйти из цикла, когда выполнено УСЛОВИЕ. exitwhen udg_i > 10 - переводится как выйти из цикла, когда переменная i станет больше 10. Мы могли бы к примеру написать условие exitwhen udg_i == 10- выйти из цикла, когда iстанет равно 10. Тогда в цикле будет выполнено на одно действие меньше. Итак, вся наша структура set udg_i = 1 loop exitwhen udg_i > 10 ... set udg_i = udg_i + 1 endloop имеет следующий смысл. Переменная i приравнивается к 1. На каждом витке цикла проверяется, не стала ли переменная i больше 10. Если не стала, производится какое-то действие и затем переменная i увеличивается на 1. И так до тех пор, пока не будет выполнено условие окончания цикла. Итоги: Условный оператор при переводе триггера в jass не очень удобен, т.к. его приходится оптимизировать. Оператор цикла в jass более универсальный, т.к. действие производится не фиксированное число раз, а до тех пор, пока не выполнится условие. Кроме того, переменную цикла в триггерах можно увеличивать только на 1, а в jass - ее можно изменять произвольным образом. Читатель, про циклы можно сказать еще следующее. Если ты попробуешь перевести в текст действие For each (Integer A) from 1 to 10, do (Actions) ... (т.е. воспользуешься одним из циклов с Integer A или Integer B, то на выходе получишь: set bj_forLoopAIndex = 1 set bj_forLoopAIndexEnd = 10 loop exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd ... set bj_forLoopAIndex = bj_forLoopAIndex + 1 endloop Что такое bj_forLoopAIndex и bj_forLoopAIndexEnd? Оказывается это специальные глобальные переменные, которые используются для проверки условий окончания такого вида цикла. Обычные переменные типа integer. Проверь сам - действие в цикле будет выполнено ровно 10 раз. Отсюда вывод: хочешь ты того или нет, но редактор всегда вставляет в твой сценарий 4 специальных глобальных переменных: set bj_forLoopAIndex set bj_forLoopAIndexEnd set bj_forLoopBIndex set bj_forLoopBIndexEnd В принципе они предназначены для циклов, а на самом деле при помощи jass в них можно записывать все что угодно. Кстати, подобных переменных на самом деле довольно много.