[VarScript 0.5] Ветвления, циклы, обработка массивов

Статус
Закрыто для дальнейших ответов.

DPOH-VAR

Старожил
Пользователь
Баллы
153
Версия плагина устарела!
Используйте VarScript более поздней версии и учите Groovy :good:


-----------------------------------------------------
Разработка VarScript 0.5 (ссылки на другие уроки, полезные функции, и т.д.)
VarScript на dev.bukkit.org (скачать можно тут)
-----------------------------------------------------
Это третий тутор по плагину VarScript 0.5
В нем будут рассмотрены некоторые логические конструкции языка.
Предполагается, что все действия пишутся в текстовом файле.

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

Существует две формы этого оператора:
(условие) IF (действие) THEN
(условие) IF (действие1) ELSE (действие2) THEN

Сразу привожу пример:

ME ^DIRT 2 HASITEMS IF ## если у игрока есть 2 блока земли
ME ^GLASS TAKE ## дать ему блок стекла​
ELSE ## а иначе
ME KILL ## убить​
THEN

Условием может быть любое выражение или любой объект
Правила, по которому происходит конвертирование в Boolean:
Null -> false
Число -> true, если оно не равно нулю
Строка -> true, если она не пустая
Entity -> true, если он жив
Vector -> true, если он не нулевой
Block -> true, если не воздух
Inventory -> true, если содержит хоть один предмет
Массив, набор, map -> true, если не пустой.
в другом случае -> true​
Таким образом, для проверки наличия игроков на сервере, следующее условие
PLAYERS SIZE 0 > IF ... (размер массива игроков больше нуля)​
можно заменить на такое:
PLAYERS IF ... (массив игроков не пуст)​

Конструкции с IF можно вкладывать друг в друга, глубина не ограничена.
оператора ELSEIF не существует.

Цикл BEGIN - REPEAT

Самая простая реализация цикла - это бесконечный цикл. Выглядит он таким образом:
BEGIN (действие) REPEAT
Действие будет исполняться до следующей перезагрузки сервера/плагина/окружения или до принудительной остановки программы.
И сразу пример:

BEGIN ## начало цикла
"Hello world" BROADCAST ## вывести в чат Hello world
1200 TICKS ## подождать минуту
​
REPEAT ## повторяем все сначала

Эта программа будет выводить в чат "Hello world" раз в минуту

Завершить этот цикл можно тремя способами:
- остановить программу
- остановить поток
- командой RUNTIME::disable остановить все программы

Циклы были бы бесполезны, если бы не было выхода по условию:
BEGIN (условие) WHILE (действие) REPEAT
Действие будет исполняться до тех пор, пока условие истинно
Еще один пример:

BEGIN ## начало цикла
ME HEALTH 5 > ## пока у игрока больше 5 жизней​
WHILE
ME 1 DAMAGE DROP ## наносим 1 ед. урона
20 TICKS ## ждем секунду
​
REPEAT

Программа каждую секунду наносит игроку 1 ед. урона, пока его hp больше пяти.
Допускаются следующие конструкции:
BEGIN (условие1) WHILE (условие2) WHILE (действие) REPEAT
И даже такие
BEGIN (действие) (условие1) WHILE (условие2) WHILE (действие) REPEAT
Как только хотя бы одно условие окажется ложным, цикл завершается

Цикл BEGIN - UNTIL

Этот цикл аналогичен предыдущему, за исключением того, что в конце добавляется проверка условия. Имеет такой вид:
BEGIN (действие) (условие) UNTIL
В данной конструкции (действие) обязательно исполнится хотя бы однажды.
В этом цикле также допускается использование оператора WHILE:
BEGIN (условие1) WHILE (действие) (условие2) UNTIL
причем, как и в предыдущем, можно WHILE использовать более одного раза.
Циклы можно вкладывать друг в друга.

Управление циклами

Для управления циклами BEGIN - UNTIL и BEGIN - REPEAT существуют такие команды:
CONTINUE - начать цикл сначала
BREAK - принудительно завершить цикл

Цикл со счетчиком

Цикл со счетчиком полезен, когда нужно выполнить функцию определенное количество раз. Имеет такой вид:
Конец Начало @DO{ (действие) }
Внутри цикла используется оператор I чтобы получить значение счетчика
Вот пример:

5 0 @DO{ ## цикл с 5 до 0
I PRINT ## напечатать значение счетчика​
}

результат будет такой:
t1.png
Счетчик после каждой итерации увеличивается на единицу. Счетчик в обратную сторону не предусмотрен.
В случае вложенности команда I будет брать счетчик последнего цикла. Чтобы получить значение предыдущего счетчика, нужно заблаговременно записать его в переменную:

5 0 @DO{ ## внешний цикл с 5 до 0
I %%i ## записываем счетчик внешнего цикла в переменную i
3 0 @DO{ ## внутренний цикл с 3 до 0
I %%j ## записываем счетчик внутреннего цикла в переменную j
"i = " @i S+ PRINT "выводим значение переменной i"

"j = " @j S+ PRINT "выводим значение переменной j"​
}​
}
 
Последнее редактирование:
Циклы по элементам массива

varscript может обработать каждый элемент из данного массива.
Для этого предусмотрены такие конструкции:

1. Цикл EACH
Массив :EACH{ (действие) }
действие применяется к каждому элементу массива.
Пример: MOBS:EACH{REMOVE}
Удалит всех мобов на сервере
Сокращенная форма:
Массив :@{ (действие) }

2. Цикл MAP
Массив :MAP{ (действие) }
Над каждым элементом массива производится действие, результат кладется в новый массив.
Примеры:
PLAYERS PRINT ## напечатает на экране всех игроков
PLAYERS:MAP{HEALTH} PRINT ## напечатает на экране жизни игроков
PLAYERS:MAP{NAME} PRINT ## напечатает имена игроков
PLAYERS:MAP{KILL} PRINT ## убьет каждого игрока, а затем напечатает всех
Сокращенная форма:
Массив :{ (действие) }

3. Цикл SELECT
Массив :SELECT{ (условие) }
внутри цикла проверяется условие. Если оно истинно - текущий элемент добавляется в новый массив. Если ложно - элемент игнорируется
Примеры:
PLAYERS PRINT ## напечатает на экране всех игроков
MOBS:SELECT{HEALTH 10 <} PRINT ## напечатает всех мобов, у которых количество хит-пойнтов меньше 10
MOBS:SELECT{HEALTH 10 <}:EACH{KILL DROP} ## убить каждого моба, у которого количество хит-пойнтов меньше 10
PLAYERS:SELECT{ISOP}:MAP{NAME} PRINT ## распечатает имена операторов
Сокращенная форма:
Массив:?{ (условие) }

4. Цикл FILTER
Массив :FILTER{ (условие) }
Команда аналогична предыдущей, за исключением того, что изменяется исходный массив.

5. Циклы SORT
Массив :SORT{(критерий)}
Происходит сортировка исходного массива по возрастанию на основании критерия.
Внимание! все критерии должны быть одного типа и сравнимы между собой.
Примеры:
[1,-4,2,10,5]:SORT{} PRINT## выведет [-4, 1, 2, 5, 10]
MOBS:SORT{HEALTH} PRINT ## отсортирует мобов по количеству hp
PLAYERS:SORT{HEALTH}:EACH{PRINT}## распечатает каждого игрока из списка игроков, в порядке возрастания его hp
PLAYERS:SORT{UPPERCASE NAME}:EACH{NAME PRINT}## напечатать имя каждого игрока из списка в алфавитном порядке независимо от регистра
Другая форма записи: SORTASC
Также есть команда SORTDESC для сортировки по убыванию.

6. Свертка массива
Иногда требуется привести массив к одному конкретному значению.
Для этого предназначена команда FOLD, которая производит свертку влево.
Массив :FOLD{(действие)}
Примеры:
[1,2,10,5]:FOLD{+} PRINT ## выведет 18 (сумму всех элементов)
[1,2,10,5]:FOLD{MAX} PRINT ## выведет 10 (максимальное число)
PLAYERS:FOLD{SWAP SETPASSENGER} ## посадить всех игроков друг на друга
 
Что насчёт Skript?)

В любом случае тема хорошая, и просто *джекичанхватаетсязаголову* непонятно почему тут за неделю нет ни одного коммента.

Автору удачи в его начинаниях, действительно полезная вещь (хотя с велосипедами надо кончать).
 
Что насчёт Skript?)
на сКрипте не получится написать Helljump,
так что,
Я уделал его в пух и прах :p
Автору удачи в его начинаниях, действительно полезная вещь (хотя с велосипедами надо кончать).
Спасибо.
Плагин уже закончен для буккита, делаю туториалы и порт на мсрс+
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх