Архив SS13 · Форум · Вики по состоянию на

Kawaiidesu Guide 3

Материал из Animus Station 13
Версия от 19:34, 28 января 2016; Michael Shepard (обсуждение | вклад)

Этой страницы нет на живой вики. Удалена 11:51, 2 марта 2016 участником MasterOfDmx с комментарием «содержимое: «{{Удалить}}»».

Текст версии от 19:34, 28 января 2016 утрачен (известна только по журналу патрулирования). Показана ближайшая более ранняя сохранившаяся версия — от 02:27, 24 марта 2014.

Эта версия удалена с живой вики и восстановлена по сохранённой Wayback Machine копии страницы (вид, а не исходный текст). Источник: снимок.

Перейти к: навигация, поиск

Это руководство по программированию в BYOND для начинающих от Kawaiidesu.

Оригинал статьи находится на нашем форуме.

Другие руководства по программированию в BYOND на русском языке вы можете найти в раздале All about the code.

Списки

Здравствуйте, с вами снова я и сегодня мы разберём list, его возможности и особенности.

Ну-с, начнём.

list - как ни удивительно, один из краеугольных камней бьёнда и, как я считаю, высокоуровневого программирования в целом. Листом является коллекция, группа элементов, последовательно соединённая друг за другом. Первый элемент имеет ссылку на второй, второй на третий и так далее. Также к листу можно обращаться как к массиву, используя квадратные скобки и адрес.

Теория-теория~~~~~

Лист может хранить в себе числа, строки, ссылки на объекты и много другое. Попробуем сделать свой первый лист.

/obj/tutorial_item
  var/list/test_list = list()

Один важный ньюанс: лист является не переменной, а объектом, следовательно его необходимо создать. Есть много способов сделать это, но list() я нахожу самым удобным.

Вот мы и создали лист, воспользуемся же им.

/obj/tutorial_item
  var/list/test_list = list()

  proc/AddItem()
    test_list += 1
    test_list.Add(1)

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

После всех этих операций мы получили лист, который содержит две единицы, так как добавляли двумя способами. Они хранятся отдельно друг от друга и не ни коим образом не взаимодействуют (list(1, 1)).

  proc/RemoveItem()
    test_list -= 1

Здесь же мы убрали один элемент из списка, получив list(1). Заметьте, пропали не оба, а лишь один элемент, который стоял в начале списка.

Точно также можно работать и с обычными объектами:

/obj/tutorial_item
  var/list/test_list = list()
  var/obj/item

  New()
    ..()
    item = new /obj(usr)

  proc/AddItem()
    test_item += item

  proc/RemoveItem()
    test_item -= item

Однако есть несколько важных замечаний: ссылка на один и тот же объект спокойно записывается в лист несколько раз. Как этого избежать, будет позже. Также, по причинам, описанным далее, даже если вы сделаете объекты полностью идентичными, удаление из листа не сработает, имейте это ввиду.

Перейдём к чему-то посложнее.

Бинарные операции с листами

Выполняются практически так же, как и операции добавления и удаления, но выглядят чуть по-другому.

  proc/AddItem()
    test_item |= item
    test_item |= item

  proc/RemoveItem()
    test_item &= !item

В чём их соль? Они позволяют гарантировано держать в листе лишь один экземпляр объекта, то есть в листе этот объект будет фигурировать лишь однажды. Логика их проста:

  • сложение это создать лист из текущего листа ИЛИ этого объекта.
  • вычитание это создать лист из текущего листа И всех объектов кроме данного.

Я уверен, большинство тут знает конъюнкцию, дизъюнкцию и прочие страшные слова.

  var/list/a = list(1, 2, 2)
  var/list/b = list(2, 3)

  var/list/sum = a + b   // 1, 2, 2, 2, 3
  var/list/sub = a - b   // 1, 2
  var/list/binary_sum = a | b   // 1, 2, 2, 3
  var/list/binary_sub = a & b   // 2

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

Почему же в бинарном сложении осталось две двойки? Ответ прост: новый лист записывается бинарным сложением каждого из элементов второго листа к первому листу. То есть вышеописанная операция может выглядеть как:

  var/list/binary_sum = a
  a |= 2
  a |= 3

С вычитанием всё немного по-другому. Сравниваются все элементы между листами и все повторяющиеся элементы записываются.

Что же, с математикой мы закончили, перейдём к кое-чему другому.

Во-первых, к листу можно обращаться как к массиву:

  var/list/a = list()
  a["first"] = 1
  a["second"] = 2
  a[/mob] = 3
  //a[-1] = 4 NOWAY

Это позволяет сделать некий словарь или таблицу хешей, которые возвращают значение по входным данным. Однако будьте осторожны, тут есть свои ньюансы: если записывать через сложение - будет возвращаться значение, но если записывать через индекс, будет возвращаться именно значение индекса, а не значение массива по индексу.

В-третьих, лист обладает длиной, что позволяет обрабатывать его как обычный массив:

  var/list/a = list(1, 3, 4)
  var/sum = 0
  for(var/i = 1; i <= a.len; i++)
    sum += a[i] //8

Что ж, я думаю, что написал тут основу для понимания всего величия листа и надеюсь, что вам было понятно и интересно, хоть он и не такой длинный, как остальные.

З.Ы. Написано с большим перерывом