Условия, циклы в 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 в них можно записывать все что угодно. Кстати, подобных
переменных на самом деле довольно много.