WarCraft 3: 2. Условный оператор, циклы, итераторы

WurstScript

Условный оператор IF/ELSE IF/ELSE

Достаточно простой и понятный пример условного оператора:
if x > y
    // Блок кода условного оператора открывается за счет дополнительной табуляции
    ...
else if x < y 
    ...
else
    ...
// Закрываем блок условного оператора, путем возврата к исходному соблюдению отступов
...
if x > y or x <= z and "blub" != "blah"
    print("if is true")
print("if done.")
if GetSpellAbilityId() == 'A000'
    AddSpecialEffect( GetSpellTargetX(), GetSpellTargetY(), FX_PATH )

Оператор множественного выбора SWITCH

// Переменная i имеет тип int
switch i
    case 1
        print("1")
    case 3
        print("3")
    case 88
        print("88")
    default
        print("not implemented")
Как видно из примера, switch оператор, это лишь более удобная альтернатива множественному else if.

Циклы WHILE/FOR

while a > b // цикл while - продолжается, пока a > b
    ...

for int i = 0 to 10 // цикл for — переменная i примет все значения от 0 до 10
    ...

for int i = 0 to 10 step 2 // цикл for с шагом 2
    ...

for int i = 10 downto 0 // цикл for от большего к меньшему
    ...
Цикл for так же может использовать переменную без явного объявления ее типа
for i = 0 to 10
	...

Циклы FOR в группах

Циклы for поддерживают работу с группами, посредством операторов in и from, позволяя обойти каждый элемент коллекции
for unit u in someGroup
    ...
for unit u from someGroup
    …
Оба представленных выше цикла обойдут группу someGroup, присваивая переменной u следующего юнита на каждой итерации, с одной лишь разницей — оператор from удалит выбранного юнита из группы.

Итераторы

Цикл for позволяет выполнять итерацию любого объекта, определяющего итератор. Так например, указанный выше цикл for-in
for unit u in someGroup
    ...
может быть представлен циклом while
let iterator = someGroup.iterator()
while iterator.hasNext()
    unit u = iterator.next()
    ...
iterator.close()
После использования, итератор должен быть закрыт вручную, вызовом метода close()
Прим. Пер.: представленный выше итератор определен в стандартной библиотеке, соответственно, для воссоздания этого примера необходимо ее наличие.

Wurst позволяет определить итератор для желаемого типа посредством набора специальных методов, наличие которых позволит применять цикл for к экземпляру этого типа:
function hasNext() returns boolean // Возвращает true если в коллекции есть еще один элемент
function next() returns TYPE       // Возвращает следующий элемент типа TYPE из коллекции)
При наличии этих двух методов вы получите итератор, пригодный для применения в цикле for-from
Для применения итератора в цикле for-in необходимо так же определить следующий метод:
function iterator() returns Iterator // Возвращает новый экземпляр итератора
Вашему итератору так же необходимо определить метод close(), который отвечает за освобождение ресурсов, выделенных при создании экземпляра итератора.
Ранее представленный итератор группы определен в стандартной библиотеке, давайте посмотрим как это выглядит:
// Внутри пакета Group
public function group.iterator() returns group
    // Возвращает копию группы
    bj_groupAddGroupDest = CreateGroup()
    ForGroup(this, function GroupAddGroupEnum)
    return bj_groupAddGroupDest

public function group.hasNext() returns boolean
    return FirstOfGroup(this) != null

public function group.next() returns unit
    let u = FirstOfGroup(this)
    GroupRemoveUnit(this, u)
    return u

public function group.close()
    DestroyGroup(this)
Как можно видеть, в качестве итератора типа group выступает сам тип group, дополненный за счет расширяющих функций (см. «Расширяющие функции»)

Просмотров: 79

Это сообщение удалено