Перейти к содержимому
  • На сайт
  • Главная
  • Правила форума
  • Последние
  • Популярные
  • Пользователи
  • Группы
Collapse

Форум Octothorp Team

t1m1yepT

дима черенок

@t1m1yep
Сводка
Сообщений
114
Темы
13
Репосты
0
Группы
0
Подписчики
2
Подписки
9

Сообщений

Последние Лучшие сообщения Спорные

  • Lua для чайников
    t1m1yepT t1m1yep

    Все вы, наверное, знаете его:

    lua

    Ой, не то…

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

    гайд перенесен с прошлого форума, я обьединил все три его части в одну

    Универсальный гайд по входу в кодинг на Lua

    гайд полностью написан мной (t1m1yep) при помощи своих знаний и документации Lua для octothorp team и его сообщества 🙂

    Установка IDE и Lua

    давай начнем с установк всего необходимого для разработки:
    для начала установим среду разработки - IDE (англ. интегрированная среда разработки)
    она понадобится нам чтобы писать наш код

    предлагаю тебе использовать visual studio code, но если ты знаком с любым другим IDE, можешь пользоваться им
    установить vs code
    после установки открывай visual studio code (дальше для удобства буду его называть VSC)
    в левой части интерфейса будет кнопка с квадратиками, в ней мы выберем необходимые дополнения (скриншот ниже, нажимай туда)

    в строку поиска пиши Lua и нажимай установить на расширении, показанном на скриншоте

    Описание

    делай тоже самое с расширением glua (тоже показано на скриншоте)

    Описание

    теперь установим Lua. смотреть гайд тут (НЕ МОЙ):

    видео гайд
    нужный сайт для установки

    теперь ты готов к разработке!

    учимся писать код!

    откроем папку для разработки, рекомендую создать отдельную папку (смотреть скриншот)

    Описание

    теперь создадим файл: (смотреть скриншот)

    img

    нажимаем на кнопку создать файл и вводим:

    main.lua
    

    в этом случае main - название файла, а .lua это расширение файла. название файла вы можете сделать своим, но расширение обязательно .lua

    после этого откроется окошко с вводом кода, туда мы будем писать код
    Описание

    также в VSC удобный встроенный терминал. для этого нажмите словосочетание

    CTRL + ` (апостроф)
    

    переведи курсор в верхнюю панель с кодом и готовься запоминать

    терминология

    переменная - ячейка с определенным названием и значением:

    название_переменной = значение_переменной
    

    переменные могут быть глобальными и локальными. локальные имеют перед названием слово “local”:

    local название_переменной = значение_переменной
    

    типы данных в Lua

    луа - динамически типизированный язык, поэтому тут вам не надо указывать типы, но, все же их необходимо знать для понимания языка и чтобы не допускать ошибок с этой темой

    string - строка

    моя_крутая_строка = "привет, мир!"
    

    строка ВСЕГДА обьявляется в кавычках!! это очень важно, если их не указать, компьютер будет искать переменную вместо строки, так как именно переменные указываются без кавычек!!!

    number - число

    мое_крутое_число = 5
    

    также число может быть дробью:

    моя_крутая_дробь_тоже_число = 5.5
    

    boolean - булево значение

    вы наверняка знаете “true” и “false” из учебников английского языка 5 класса 🙂

    мое_крутое_булево_значение = true
    

    и еще:

    мое_крутое_булево_значение = false
    

    если не знаете английский, true - правда, false - ложь

    nil - ничего

    nil - буквально ничего 🙂

    мое_крутое_ничего = nil
    

    function - функция

    function моя_крутая_функция(мой_крутой_аргумент_функции)
    

    пока что ты еще не знаешь о функциях, но мы поговорим о них прямо в следующем параграфе!

    в этом параграфе я рассказал тебе только о самых базовых типах, всего их восемь, об остальных мы поговорим позже

    функции

    функция имеет аргумент (иногда его не может быть) и название, также она может возвращать значение. давай посмотрим на примере:

    function название_функции(аргумент_функции) -- обьявляем функцию
          local переменная = 10 -- обьявляем переменную
          return переменная -- возвращаем переменную
    end -- обьясняем компьютеру, что наша функция закончилась
    

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

    **также функция может принимать аргументы: **

    function суммировать(а, б) -- создаем функцию
        local сумма = а + б -- создаем переменную, равную сумме аргументов а и б
        return сумма -- возвращаем нашу переменную сумма
    end -- заканчиваем функцию
    

    аргументы в функции перечисляются через запятые и могут иметь любые названия, это обычные переменные

    теперь вызовем функцию:

    суммировать(10, 50)
    

    функция должна быть обьявлена выше, чем ее вызов в коде!

    чтобы вывести результат функции, нам понадобится вызов встроенной функции print:

    print(суммировать(10, 50))
    

    также можем вывести любую другую переменную через функцию print:

    print("привет, челог!")
    

    для этого понадобится отправить строку в кавычках, как я говорил раньше в параграфе с типами данных!! если этого не сделать, компьютер будет искать переменную вместо строки

    также можно вывести переменную:

    local строка = "привет, челог!"
    print(строка)
    

    разницы между двумя верхними примерами нет

    условия

    условия позволяют выполнять определенный отрывок кода только если условие соблюдается

    условия if и else

    local a = 10 -- обьявляем переменную a
    local b = 5 -- обьявляем переменную b
    if a > b then -- говорим компьютеру: ЕСЛИ а БОЛЬШЕ б, ТОГДА печатай текст
         print("переменная а больше чем б!")
    end
    

    условие также имеет табуляции и заканчиваются с помощью end. в этом случае нам напишет строку “переменная а больше чем б!”

    но если мы поменяем переменные значениями (тоесть переменная a станет равна 5, а переменная b станет 10)

    теперь введем еще одно условие else

    local a = 10
    local b = 5 
    if a > b then 
         print("переменная а больше чем б!")
    else -- говорим компьютеру, что если условие не выполняется, то печатаем текст
        print("функция не подошла не под одно условие!!")
    end
    

    elseif

    а что если может быть еще один вариант? если переменные равны, и нам надо напечатать текст именно о том, что переменные равны? в таком случае нам поможет условие elseif

    local a = 10
    local b = 5 
    if a > b then 
         print("переменная а больше чем б!")
    else if a == b -- иначе если а == б
         print("переменная а равна б!") -- печатаем текст
    else
        print("функция не подошла не под одно условие!!")
    end
    

    вот так выглядят условия. и да, end у них один, так как они считаются одним блоком кода

    когда мы сравниваем две переменные на равенство, пишется два знака “=”, а если присваеваем переменной значение, пишется один знак “=”

    ввод и вывод

    есть три потока - stdIN, stdOUT, stdERR
    нас интересуют только первые два (пока что)
    stdin - осуществляет пользовательский ввод из консоли
    stdout - осуществляет вывод данных в консоль
    чтобы пользователь мог ввести значение переменной, рассмотрим такой код:

    local переменная = io.read()
    

    мы вызываем функцию read из библиотеки io (input/output)

    библиотека - определенный код, созданный для удобства использования заготовленных функций. язык имеет встроенные библиотеки
    а теперь выведем этот ввод:

    local переменная = io.read()
    print(переменная)
    

    массивы

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

    local массив = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    

    так создается массив, в массиве количество элементов считается от нуля, тоесть последним индексом этого массива будет 9, а первым 0
    обратимся к 5 индексу массива в этом коде (это число 6):

    local массив = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    print(массив[5]) -- в квадратных скобках после названия переменной указываем индекс переменной в массиве
    

    циклы

    циклы позволяют нам выполнять один блок кода н-нное количество раз. один такой раз называется одной ИТЕРАЦИЕЙ

    операторы (важно)

    = - оператор присваивания
    == - оператор сравнения (если переменные равны)
    ~= - оператор сравнения (если переменные не равны)
    < - оператор меньше
    > - оператор больше
    <= - оператор меньше-равно
    >= - оператор больше-равно

    while

    while переводится как “пока”, тоесть компьютер делает какой то блок кода пока условие выполняется. грубо говоря, if вместе с циклом.

    рассмотрим цикл while:

    local i = 0 -- i это общепринятое название переменной обозначающей количество итераций
    local limit = 10 -- количество итераций
    while i < limit do -- пока i меньше переменной limit (10) делай этот блок кода
         print(i) -- печатаем переменную i
         i = i + 1 -- i равняется i плюс 1
    end
    

    этот код выведет числа от 0 до 9

    repeat (repeat-until)

    repeat -- повторять
            line = io.read() -- считываем ввод от пользователя
        until line ~= "" -- если ввод пользователя не пустая строка, то повторяем еще раз
        print(line) -- печатаем последний ввод пользователя
    

    repeat перевыполняет код еще раз, если условие until выполняется. until выполняет роль if

    числовой for

    цикл for - переводится как “пока”, как и while, только используется в других целях и имеет другой вид

    for i = 1, 10 do
        print(index)
    end
    

    for делает “шаги”, после каждого автоматически прибавляя 1 к переменной i, а число 10 после запятой здесь означает количество шагов. этот код выведет числа от 1 до 10

    рядовой for

    сразу попрошу учесть что рядовой for не военный и даже не служит в армии! рядовой тут означает - по рядам

    рядовой for позволяет итерироваться (перевыполнятся) блоку кода пока в данном ему массиве имеются элементы.
    рассмотрим этот код:

    local a = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}
    for i,v in ipairs(a) do -- i (индекс обьекта в массиве) и v (значение массива с индексом i) в ipairs(массив)
        print(v) -- печатаем значение массива с индексом i
    end
    

    ipairs() - функция которая возвращает сразу два значения: индекс значения в массиве и само значение в массиве. перестает возвращать значения когда массив заканчивается, следственно, цикл тоже останавливается

    возвращать два значения легко - return первое_значение, второе_значение . просто перечисли через запятую!

    break

    break позволяет остановить цикл вне его выполнения
    рассмотрим данный код:

    local a = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}
    for i,v in ipairs(a) do -- i (индекс обьекта в массиве) и v (значение массива с индексом i) в ipairs(массив)
        if v == 50 then break end -- если значение массива равняется 50, останавливаем цикл
        print(v) -- печатаем значение массива с индексом i
    end
    

    да, условия в одну строку реализуются только если блок, выполняемый в условии однострочный: if 10 > 20 then print(“10 меньше 20!!”) end

    В этой главе:

    • таблицы
    • строки (продвинуто)
    • замыкания
    • конструкторы
    • функции (продвинуто)
    • библиотеки и require
    • работа с ошибками (error handling)
    • корутины
    • условия (продвинуто)
    • и закрепим предыдущий материал!

    таблицы

    таблица представляет из себя “массив”, который вместо индекса имеет ключ. рассмотрим на примере:

    local mytable = {} -- инициализируем пустую таблицу
    local key = "taiwan" -- создаем переменную-строку "ключ"
    mytable[key] = "roobys" - задаем значение обьекту таблицы с ключом который мы создали ранее
    print(mytable[key]) -- выводим значение обьекта таблицы  с ключом key!
    

    этот код выведет строку “roobys”. давайте немного изменим этот код, в частности, последнюю строку:

    local mytable = {} -- инициализируем пустую таблицу
    local key = "taiwan" -- создаем переменную-строку "ключ"
    mytable[key] = "roobys" - задаем значение обьекту таблицы с ключом который мы создали ранее
    print(mytable) -- выводим таблицу без ключа! саму переменную
    

    выведется что то по типу “table: 0x158e09d80”
    что это?!
    это адрес таблицы в памяти компьютера. ее местоположение, ячейка, которую она занимает в ОЗУ

    мы можем инициализировать таблицу по другому:

    local mytable = {["skumbri"]="скумбри", ["р12"]="r12", ["zverok99"]="зверек99"}
    

    в этом случае мы заранее инициализировали обьекты нашей таблицы и ключи к ним. mytable с ключом “skumbri” хранит значение “скумбри”!

    также мы можем создать таблицу-матрешку:

    local octothorp_team = {
        managers = {["inquizzy"]="инквиззи", ["vondik"]="вондик"}, 
        admins = {["skumbri"]="скумбри", ["campot"]="кампот"} 
    }
    print(octothorp_team.managers["inquizzy"])
    print(octothorp_team.admins["campot"])
    

    только в этом случае нам надо будет обращаться к под-таблицам через точку “.”

    примечание: ключи могут быть как и строками, так и числами и даже boolean’ами
    примечание: ключи в таблицах указываются в квадратных скобках, а после, через равно идет значение

    пример итерации по обьектам таблицы:

    local octothorp_team = {["doctor"]="доктор",["kilo7"]="кило-семь", ["polkin"]="полкин"}
    for key, value in pairs(octothorp_team) do 
        print(key, value)
    end
    

    в этом случае я использовал функцию pairs()
    этот код выведет:

    polkin  полкин
    kilo7   кило-семь
    doctor  доктор
    

    замыкания

    замыкания - “мини функции”
    рассмотрим на примере:

    local myfunction = function (a, b)
        return a + b
    end
    
    print(myfunction(10, 10))
    

    для удобства и чистоты кода - сделаем обьявление функции-замыкания однострочным

    local myfunction = function (a, b) return a + b end
    
    print(myfunction(10, 10))
    

    получается, что мы задаем нашей переменной myfunction значение функции. уже забыл?! функция - это тоже тип данных! я говорил об этом в первой части.

    мы можем вызывать эту переменную точно также как и функцию. рассмотрим еще один пример:

    function create_closure() 
        return function(a, b) return a + b end
    end
    
    local closure_function = create_closure()
    
    print(closure_function(1, 2))
    

    closure - замыкание по английски.
    мы создаем функцию, которая возвращает функцию-замыкание, а эта функция-замыкания суммирует два числа. получается, что функции точно также могут возвращать функции-замыкания с помощью return. прямо как обычные числа и строки!

    строки

    был бы это си… ой, что-то я замечался, продолжим!
    строки имеют свою собственную библиотеку! как бы это банально не звучало, звать ее - string!
    рассмотрим функцию gsub библиотеки string. она может заменить часть строки!

    local a = "доброград плохой сервер" -- создаем строку
    local b = string.gsub(a, "плохой", "крутой")  -- меняем часть строки и записываем в другую переменную
    print(a)       -- неправильная строка
    print(b)       -- правильная строка
    

    **выводом будет: **

    доброград плохой сервер
    доброград крутой сервер
    

    аргументы функции gsub() - первоначальная строка, с которой будут проводится манипуляции; слово которое должно быть изменено; слово НА которое надо изменить
    функция gsub() возвращает обновленную строку

    операции с задним слэшем (форматирование текста)

    задний слэш - "" в составе строки может иметь после себя определенную букву. каждая строка заканчивается на “\0” - nil символ, он обозначает конец строки. ты его даже не замечаешь! но запомни это, ведь любой инструмент может тебе пригодится (даже старая мышь, вдруг новая сломается!)

    \n - знак новой строки. все что будет после него - с новой строки
    \t - табуляция
    \r - очистить всю консоль! (не ставь это в конце, иначе ничего не увидишь 🙂 лучше ставь в начале!)
    также имеется большое количество таких операций, их ты можешь найти в интернете.

    ТВОЙ РОДНОЙ ЯЗЫК ДЖАВАСКРИПТ ЧТО ЛИ С**А?!

    наверняка многие из вас видели этот мем
    Описание
    это происходит из за сложения строк

    local яблоко = "яблоко"
    local одно = "одно"
    local одно_яблоко = одно + яблоко
    

    да, баян, но я считаю что стоит осветить эту тему 🙂
    также мы получим ошибку если попытаемся провести операцию с двумя разными типами:

    local chelog = "Дмитрий Антонов"
    local pi = 3.14
    local pichelog = chelog + pi -- выдаст ошибку, мы не можем сложить Дмитрия Антонова и 3.14
    print(pichelog) 
    

    Описание

    мы можем сложить яблоко с яблоком, но банан с яблоком не можем.

    – таинственный кодер

    конструкторы

    ты до этого применял конструкторы, с таблицами и массивами! да-да, те самые фигурные скобки при создании таблиц и массивов - конструкторы. давай посмотрим пример:

    local массив_админов = {"r12", "skumbri", "campot", "timetocoffee", "what"} 
    local таблица_админов = {["рубус"]="roobys", ["эр12"]="r12", ["скумбре"]="skumbri", ["кампот"]="campot", ["кофейня"]="timetocoffee"} 
    print(массив_админов[3]) -- выведет timetocoffee
    print(таблица_админов["эр12"]) -- выведет r12
    

    Библиотеки, require

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

    представим такую ситуацию: ты вывел в отдельный файл одну очень сложную функцию (нет) которая возвращает строку “Дмитрий Антонов” и теперь хочешь использовать эту функцию и библиотеку в основном файле. тут тебе поможет require:

    файл chelog_library.lua

    function dmitry_antonov() 
        return "Дмитрий Антонов"
    end
    

    файл main.lua

    require "chelog_library"
    
    local dima = dmitry_antonov()
    print(dima)
    

    почему ты написал только название файла в require? где расширение .lua??

    если вы импортируете локальный файл, которого нет папке всех библиотек lua, указывайте только название файла, иначе компьютер будет искать его в корне библиотек и он ее просто не найдет!

    также вы можете импортировать из папки:
    Описание
    в таком случае понадобится указать дочернюю папку в main.lua:

    require "libs/chelog_library"
    
    local dima = dmitry_antonov()
    print(dima)
    

    в файле библиотеки ничего менять не нужно.

    но что если main.lua тоже находится в папке?
    Описание
    в таком случае нам надо задать package.path перед require:

    package.path = package.path .. ";../libs/chelog_library.lua"
    require("chelog_library")
    
    local dima = dmitry_antonov()
    print(dima)
    

    Описание
    а если библиотека находится вне папки libs, а просто папкой выше main.lua, мы можем убрать из package.path путь в папку “/libs”:

    package.path = package.path .. ";../chelog_library.lua"
    require("chelog_library")
    
    local dima = dmitry_antonov()
    print(dima)
    

    условия (продвинутые)

    рассмотрим несколько условий:

    булевы значения в if
    local lovechelog = true
    if lovechelog then 
        print("i love chelog") 
    elseif not lovechelog then
        print("deleting system...")
    end
    

    выведется “i love chelog”, а если заменить lovechelog на false, выведется “deleting system…”

    ключевое слово “not” буквально обозначает “не”

    в случае с булевым значениями не обязательно указывать сравнение по типу: “if boolean == true …”, можно просто написать “if boolean …”, это будет означать одно и тоже. а если надо указать “if boolean == false …”, можно написать “if not boolean”, это означает тоже самое.

    elseif входит в состав конструкции if, так как end у них общий. elseif используется только в случае повторения условия с участием одной и той же переменной.

    “||” и “&&”

    || - “или”

    if 10 > 5 || 20 > 21 then -- выполнится только первая часть условия, но само условие выполнится
         print("octothorp team") -- надпись выведется
    end
    
    if 10 < 5 || 20 < 21 then -- выполнится только вторая часть условия, но само условие выполнится
         print("octothorp team") -- надпись выведется
    end
    

    && - “также”

    if 10 > 5 && 20 > 10 then -- условие выполнится
       print("octothorp team") -- надпись выведется
    end
    
    if 10 > 5 && 20 < 10 then -- условие не выполнится, так как вторая часть не выполнена
       print("octothorp team") -- надпись НЕ выведется
    end
    

    работа с ошибками

    каждый разработчик имеет дело с ошибками и удерживает их (нервно пытается)

    error()

    функция error() принимает строку, которую будет печатать в консоль

    error("ошибка!")
    

    выведет:
    Описание

    assert

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

    local dima = "dima"
    local num1 = 10
    local numdima = assert(type(num1) == "string", "num1 не должно быть числом") -- assert() вернет false и выключит программу
    print(numdima) -- мы никогда не узнаем...
    print(dima, num1) -- мы никогда не узнаем...
    

    Описание
    поменяем переменную num1 на строку:

    local dima = "dima"
    local num1 = "antonov"
    local numdima = assert(type(num1) == "string", "num1 не должно быть числом") -- assert() вернет true
    print(numdima) -- выведет true
    print(dima, num1) -- выведет "dima antonov"
    

    Описание

    корутины

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

    создадим корутину:

    корутина = coroutine.create(function ()
        print("привет!") -- не выведется, так как горутина запускается в другом потоке!
    end)
    print(корутина) -- выведет thread: <адрес потока в котором запускается горутина>
    print(coroutine.status(co)) -- выведет suspended, корутина приостановлена
    coroutine.resume(co) -- выведет тот самый "привет!" в консоль, однако пожертвует своей жизнью (я не шучу)
    print(coroutine.status(co)) -- выведет dead... корутина умерла..
    

    немного исправим код и добавим coroutine.yield():

    корутина = coroutine.create(function () -- создаем корутину
        for i=1,3 do -- создаем цикл, он запустится три раза
            print("корутина с числом", i) -- печатаем номер итерации цикла
            coroutine.yield() -- функция yield() делает статус suspended, тоесть приостановлена
          end
    end)
    coroutine.resume(корутина) -- теперь мы возобновим коротину. три раза. выведет число 1
    print(coroutine.status(корутина)) -- статус suspended, так как после каждой итерации корутина приостанавливает себя и ждет возобновления
    coroutine.resume(корутина) -- выведет число 2
    print(coroutine.status(корутина)) -- suspended!
    coroutine.resume(корутина) -- выведет число 3
    print(coroutine.status(корутина)) -- suspended!
    

    если мы попытаемся возобновить коротину через coroutine.resume() которая уже мертва, мы получим ошибку

    мы также можем приостанавливать и возобновлять корутину с аргументами:

    корутина = coroutine.create(function (a,b) -- коротина-замыкание с двумя аргументами
        coroutine.yield(a + b, a - b) -- приостанавливаем корутину с аргументами для возобновления
      end)
    print(coroutine.resume(корутина, 20, 10)) -- даем те самые аргументы из yield(). выведет 30
    

    также коротина может возвращать значения как обычная функция:

    корутина = coroutine.create(function ()
        return 6, 7 -- возвращаем числа 6 и 7
      end)
    print(coroutine.resume(корутина))  -- выведет "6 7"
    

    обратная связь (вопросы насчет кода)

    дискорд: t1m1yep

    Универсальный гайд по входу в кодинг на Lua

    В третьей главе:

    • деревья
    • списки (даже научимся создавать их с нуля)
    • библиотека table для работы с таблицами
    • сериализация
    • load()
    • переменная-placeholder
    • навыки гуглить

    библиотека table

    мы уже рассмотрели таблицы, а теперь перейдем к библиотеке для работы с ними. require прописывать не надо, так как библиотека стандартная

    table.insert() и table.remove
    local tbl = {["saber"]="сабер"} -- создаем таблицу
    
    table.insert(tbl, "карасик") 
    -- вставляем в таблицу строку "карасик" без ключа
    -- через table.insert() значение с ключом не вставить!
    
    print(tbl[1]) -- к значению "карасик" придется обратиться, 
    -- по его индексу, как у массива
    
    print(tbl["saber"]) -- а к значению "сабер" которому мы дали ключик, 
    -- обращаться только по ключу!
    
    print(tbl.saber) -- выпечатает сабера, 
    -- так тоже можно обращаться по ключу (через точку)
    
    print(tbl[0]) 
    -- напишет nil, так как к первому ( с нулевым индексом)
    -- которому мы задали ключ, обращаться можно только по ключу
    
    table.remove(tbl, 1)
     -- в table.remove() указать таблицу и индекс, 
    -- обьекта который мы хотим удалить
    print(tbl[1]) 
    -- выведет nil, карасика больше нет!
    
    table.remove(tbl, 0) -- попробуем удалить обьект с ключом..
    print(tbl["saber"]) 
    -- выведет сабера, 
    -- так как к обьекту с ключом по индексу не обратиться!
    
    table.remove(tbl, ["saber"])
    -- table.remove() выведет ошибку, 
    -- так как функция принимает только числа как второй аргумент!
    print(tbl["saber"]) -- мы никогда не узнаем..
    

    table.insert(таблица, индекс, обьект)
    таблица - table
    индекс - number
    обьект - any буквально любой тип, так как таблица может принимать все типы

    но… я уже указывал только таблицу и обьект?
    да, второй аргумент необязателен, поэтому если третего аргумента (обьекта который мы вставляем) нет, то вместо него становится второй аргумент

    table.remove(таблица, индекс)
    таблица - table
    индекс - number

    значения, которые создавались в паре с ключом, по индексу тронуть нельзя

    односвязный список

    односвязный список - переменная которая помимо своего значения содержит следующий элемент списка
    грубо говоря, это матрешка, которая в себе содержит свой следующий элемент

    local lst = { -- создаем список, это называется КОРНЕМ списка, первый обьект
      value = nil, -- список содержит две переменные - его "значение"
      next = nil -- и следующий элемент списка
    }
    lst.value = 10 -- задаем "значение" первого элемента списка десяти
    
    local new_lst = { -- создаем второй элемент списка
      value = nil, -- изначально переменные списка nil
      next = nil
    }
    new_lst.value = 20 -- задаем значение второго элемента двадцати
    lst.next = new_lst -- а теперь задаем в первом элементе списка, как следующий элемент второй
    
    local newnew_lst = { -- создаем третий элемент списка
      value = nil,
      next = nil 
    }
    newnew_lst.value = 30 -- значение третего элемента списка - 30
    new_lst.next = newnew_lst -- следующий список у второго - третий
    
    print(lst.value) -- первый обьект, 10
    print(lst.next.value) -- второй обьект, 20
    print(lst.next.next.value) -- третий обьект, 30
    

    используя только первый элемент, мы дошли до последнего!
    все это можно сделать удобнее, через циклы, но мне надо просто показать как это дело работаетё

    деревья

    сейчас изучим деревья. представь большое дерево, и от каждой его ветки идут еще две ветки
    Описание

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

    local tree_root = {
        value = 10
        left = nil
        right = nil
    }
    

    value - значение
    left - левая ветка
    right - правая ветка

    local tree_root = { -- создаем первую ветку дерева
      value = 10, -- на первой ветке лежит десятка
      left = nil, -- левой ветки пока что нет
      right = nil -- правой ветки пока что нет
    }
    
    local first_right = { -- создаем первую ПРАВУЮ ветку дерева
      value = 20, -- на первой ПРАВОЙ ветке дерева лежит двадцатка
      left = nil, -- левой ветки ОТ ЭТОЙ ветки пока что нет
      right = nil -- правой ветки ОТ ЭТОЙ ветки пока что нет
    }
    tree_root.right = first_right -- задаем правую ветку самой первой ветки, только что созданной веткой
    
    local first_left = { -- создаем первую ЛЕВУЮ ветку
      value = 30, -- на первой ЛЕВОЙ ветке лежит тридцатка
      left = nil, -- от первой ЛЕВОЙ ветки нет еще одной левой ветки
      right = nil -- от первой ЛЕВОЙ ветки нет еще одной правой ветки
    }
    tree_root.left = first_left -- задаем самой первой ветке левую ветку нашей только что созданной левой веткой
    
    print("первая ветка: ", tree_root.value) 
    -- выведется 10, это значение самой первой ветки
    
    print("первая левая ветка: ", tree_root.left.value) 
    -- выведется 20, это значение первой-левой ветки
    
    print("первая правая ветка: ", tree_root.right.value)
    -- выведется 30, это значение первой-правой ветки
    

    это достаточно сложная тема и мне самому понадобилось время чтобы ее понять

    на 99% собеседований на работу программистом спрашивают про деревья!

    сериализация

    сериализация - процесс преобразования объекта в форму, пригодную для сохранения или передачи

    сериализация - это когда ты сохраняешь свою таблицу в текстовый файл, чтобы отправить ее другу!

    рассмотрим пример сериализации с помощью библиотеки IO (input/output):

    local workers = {"Дмитрий Антонов", "Дезроу Дезроев", "Тимофей Коробка"}
    -- создаем массив строк "работников"
    
    save_file = io.open("workers.txt", "w")
    -- через библиотеку io открываем файл workers.txt
    
    io.output(save_file)
    -- говорим программе "дальше выводи все в save_file"
    
    for i = 1, #workers do -- запускаем цикл по всем элементам массива
      io.write(workers[i], "\n")
      -- через io печатаем каждого работника, после ставим \n (знак новой строки)
    end
    
    io.close(save_file) 
    -- обязательно закрываем файл, иначе компьютер будет ждать новых инструкций с файлом
    

    рассмотрим каждую функцию по порядку:

    io.open(название_файла, режим_файла)
    название_файла - string, просто название файла
    режим файла - string, режим открытия файла:

    r - read, только читать; w - write, переписывает весь файл; a - append (добавить), открывает или создает файл для добавления чего-то к нему; r+ - read и write; w+ - read и write, полностью переписывает файл или создает его; a+ - append и read, открывает уже созданный файл или создает новый.

    io.output(файл)
    файл - файл, который был создан с помощью io.open()
    примечание - по умолчанию io.output() - консоль

    for i = 1, #массив do …
    массив - название массива, “#” перед ним позволяет итерироваться столько раз, сколько элементов в массиве

    io.write(содержимое)
    содержимое - строка
    печатает содержимое в io.output(), по умолчанию это консоль

    io.close(файл)
    файл - файл, который был создан через io.open()
    перестает ожидать инструкций о работе с ранее открытым в io.open(). обязателен если был io.open()!!

    пауза

    вот и закончилась базовая часть Lua, теперь мы будем переходить к более сложным вопросам, но сначала я хотел бы рассказать необходимые инструменты настоящего погромиста

    google

    да, навыки гуглить тебе очень пригодятся и я хотел бы дать небольшую базу как их использовать:
    представим что я хочу найти рецепт торта медовика:
    Описание
    А ГДЕ МЕДОВИК?! ПОЧЕМУ ТУТ ВООБЩЕ НЕТ МЕДОВИКА!
    **можно сделать мой запрос таким: **
    рецепт торт "медовик" - я указал медовик в кавычках, это означает что это слово ОБЯЗАТЕЛЬНО должно быть в предложенном результате
    Описание
    результаты лучше!!

    писать на английском (если ты его знаешь)

    представим что я хочу найти как подключится к базе данных через glua:
    Описание
    на русском - результатов нет!
    попробуем на английском:
    Описание
    на английском - результаты есть!!

    переменная placeholder

    делаешь цикл через pairs, но тебе не нужно одно из значений? так просто забей хуй поставь плейсхолдер!

    local tbl = {"chelog", "dima"} -- делаем массив
    for _,v in pairs(tbl) do -- ставим вместо k плейсхолдер (_)
      print(v)
    end
    

    да-да плейсхолдер - нижнее подчеркивание
    он указывает на то, что тебе не нужно получать эту переменную
    а почему просто ничего не ставить на месте k?
    так как k - первый аргумент, v будет иметь значение, подготовленное для k просто с другим названием!

    функция load()

    универсальная и ОЧЕНЬ мощная функция, превращает ЛЮБУЮ строку которую вы ей дадите в функцию:

    local code = "local s = 'привет, мир!'; return s"
    f = load(code)
    print(f())
    

    для обозначения новой инструкции компьютеру в одну строку ставят “;”

    _G (_global)

    глобальная таблица которая позволяет нам вписывать туда новые значения с ключами:

    _G["chelog"] = "dima"
    print(_G["chelog"])
    

    также можно создать глобальную функцию:

    function _G.print_chelog()
      print("chelog")
    end
    _G.print_chelog()
    

    мы присвоили к переменной (таблице) _G функцию print_chelog() и теперь можем обращаться к ней через точку!

    читать документацию glua
    если ты закончил читать этот гайд, то ты просто монстр, спасибо

    Обратная связь:

    дискорд: t1m1yep

    Гайды одобрено

  • 100% white.
    t1m1yepT t1m1yep

    сски стиль бро 😅 https://forum.octothorp.team/topic/215/энциклопедия-по-скриншот-ситуациям/2
    посмотри гайд выше просто, там расписано как сделать

    Архив историй

  • Ликвидация Эдисон 3
    t1m1yepT t1m1yep
    1. Дмитрий Черенок
    2. STEAM_1:1:442642190
    3. t1m1yep
    4. консоль (автобан)
    5. XxAD7Zo.png
    6. 26.05.24 20:56
    7. Пришел спасать друга во время рейда нашего склада (этого, я думаю, делать не стоило), как только зашел внутрь - вооружился, ожидая встретить нескольких ВООРУЖЕННЫХ копов. Как только я зашел за угол (будучи вооруженным), я увидел порядка четырех-пяти полицейских, что были в руках с физганами (один с тараном) и сидели на коробках, ломая потолок (пытаясь найти моего друга, также это ломает стены моего жилища). Я испугался, запаниковал и открыл огонь по ним. После того как у меня закончились патроны, я начал отбегать - мне в спину открыли огонь (предположительно, с глока), я посчитал что они вооружились и еще раз вышел на них, предварительно перезарядившись - убив одного(?) безоружного (он сидел на корточках): там было достаточно темно, к тому же, когда ты сидишь на корточках - оружие намного сложнее увидеть, особенного в такой обстановке, когда я запаниковал и был испуган. Перед всеми игроками фракционной полиции, я извинился (перед муниципальной не могу, так как их контакта у меня нет)
    8. Прошу перевыдачи наказания, признаю свою вину в убийстве нескольких безоружных - из их стороны шел огонь и я не разобравшись кто вооружен, начал стрелять. Приношу извинения перед всеми игроками, которым навредил. Я осознал свою ошибку и после окончания наказания я продолжу меньше играть крайм (что я и делал в последние дни перед получением бана), разбавляя игру другими сегментами игры на Доброграде. Я активный участник сообщества, каждый день играю на Доброграде. Я содействовал бывшему техническому администратору, писал гайды и проявлял(-яю) активность на проекте
    9. https://imgur.com/a/a6CaLZ4
    10. да
      https://www.youtube.com/watch?v=OYhXJaEbw7c
    Решенные заявки отклонено

  • "Mateo Phychodelics"
    t1m1yepT t1m1yep

    OST

    deadly dose

    curtis

    1
    2
    3

    Архив историй архив

  • Семья каннибалов на Доброграде
    t1m1yepT t1m1yep

    @DEADKENNEDY все кто на его ивентах - нпс с новой технологией распознавания лиц. туда встроенны нейросети
    о данных технологиях стало известно совсем недавно когда был зафиксирован так называемый нпс-уборщик якобы стажер доброградского полицейского департумента
    собственнно обьявляю АКЦИЮ “ПОЛДЕНЬ ПРОТИВ ZEEKE”, когда будет его ивент в полдень (еще никто не знает но это так скажем инсайдерская информация), никто из НОРМАЛЬНЫХ людей что не повреждены его ПРОПАГАНДОЙ своих ИВЕНТОВ и использованием массовки - нпс с новой технологией распознавания лиц куда встроены нейросети

    ПОЛДЕНЬ ПРОТИВ ZEEKE!!!

    Творчество

  • "Mateo Phychodelics"
    t1m1yepT t1m1yep

    mateopsychodelics.blogspot.com/как-поймать-лучший-трип

    1
    2
    3
    4

    Архив историй архив

  • mateopsychodelics.blogspot.com
    t1m1yepT t1m1yep

    развитие персонажа
    автор не поддерживает и не употребляет наркотические средства
    все что написано - ic информация которая в реальной жизни не применима
    мой дискорд - t1m1yep

    header
    Блог — веб-сайт, основное содержимое которого — регулярно добавляемые пользователем записи, содержащие текст, изображения или мультимедиа.

    Матео Гиббс - известный в узких интернет блогер, ведет свой блог о психоделиках.

    Архив

  • Ликвидация Эдисон 3
    t1m1yepT t1m1yep

    @1000-7 В таком случае, также важно учесть, что данный склад на Эдисон 3 также является моим “местом”, но, согласен, так рисковать не стоило
    И еще, уточню насчет отыгровки в ПИТ - я пришел к стационарному телефону и отыграл звонок другу - он взял трубку, попросил помощи

    Решенные заявки отклонено

  • дима черенок галерея
    t1m1yepT t1m1yep

    Описание

    Творчество

  • "Mateo Phychodelics"
    t1m1yepT t1m1yep

    развитие персонажа
    автор не поддерживает и не употребляет наркотические средства
    все что написано - ic информация которая в реальной жизни не применима
    мой дискорд - t1m1yep

    Психоде́лики (от др.-греч. «душа», «сознание», «ясный») — класс психоактивных веществ, изменяющих восприятие и влияющих на эмоциональное состояние и многие психические процессы. Психоделики могут вводить человека в изменённые состояния сознания. Как правило, не считаются опасными в плане возникновения зависимости или аддикции.


    психоделики

    Архив историй архив

  • mateopsychodelics.blogspot.com
    t1m1yepT t1m1yep

    header

    ПРИВЕТ МОИ ЧИТАТЕЛИ. СЕГОДНЯ Я РАССКАЖУ ВАМ КАК ПОЙМАТЬ ЛУЧШИЙ ТРИП
    ДЛЯ НАЧАЛА НАЙДИТЕ ПСИХОДЕЛИК
    ЛСД ИЛИ ДМТ НУ Я ДУМАЮ ВЫ НЕ НАСТОЛЬКО ТУПЫЕ ХА ХА LOL
    (PS. ГРИБЫ ТОЖЕ СОЙДУТ НО Я НЕ ПРОВЕРЯЛ НЕ МОГУ НАСЧЕТ НИХ ТОЧНО СКАЗАТЬ IMHO ЛСД ЛУЧШЕ)
    СОБСТВЕННО КАК ПЛОЩАДКУ ДЛЯ ТРИПА Я РЕКОМЕНДУЮ ИСПОЛЬЗОВАТЬ ЛЮБОЕ КОМФОРТНОЕ ДЛЯ ВАС ОКРУЖЕНИЕ
    ТОЕСТЬ ВАШ ДОМ ПОЛЯНКА В ЛЕСУ МАЛЕНЬКАЯ КОМОРКА ВСЕ ЧТО УГОДНО;P
    ТАКЖЕ РЕКОМЕНДУЕТСЯ (*ВСЕМ ПОХУЙ LOL) ЧТОБЫ РЯДОМ НАХОДИЛСЯ ЧЕЛОВЕК КОТОРЫЙ В СЛУЧАЕ БЭД ТРИПА СМОЖЕТ ВАМ ПОМОЧЬ
    ТАКЖЕ НЕ ПРИНИМАЙТЕ СЛИШКОМ БОЛЬШУЮ ДОЗУ ИНАЧЕ ВАМ СТАНЕТ ПЛОХО (ЗНАЮ ПО СВОЕМУ ОПЫТУ LUL ЛУЧШЕ НЕ ПРОВЕРЯТЬ)
    А НА ЭТОМ У МЕНЯ ВСЕ СПАСИБО ЗА ЧТЕНИЕ! ! ДО ВСТРЕЧ 0)
    footer

    Архив

  • Заявка на разбан
    t1m1yepT t1m1yep

    https://forum2023.octothorp.team/topic/6912/заявка-на-разбан-после-3-х-лет-повторная

    ты скрыл видео с рдмом, которое я отправлял на твоей прошлой заявке, поставив доступ по ссылке
    https://www.youtube.com/watch?v=MHcvOSlGQqw
    и вот бекапчик https://imgur.com/a/i9ghb9w
    😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊 😊

    Решенные заявки одобрено

  • дима черенок галерея
    t1m1yepT t1m1yep

    уважаемы подписчики дима черенок был ликвидирован вражескими войсками 26.05.24 в 20:56 😭
    федеральное бюро расследования обнаружило дмитрия на месте преступления и ликвидировало его за убийство полицейских, что напали на его жилище. все действия димы черенка оправданы законами шариата ☝ 😕
    уголовное преследования дмитрия черенка было незаконно и я, как менеджер дмитрия черенка, прошу обратить внимание на данный произвол. на момент совершения преступления, дмитрий черенок был сильно напуган, он запаниковал и открыл огонь по офицерам полиции. он был зверски ликвидирован сотрудниками фбр и участковым по городу доброград текоем. сейчас он находится в реанимации, шансы на восстановление имеются: возможно что милиция по городу доброград не даст дмитрию шанса на выживание. мы искренне сочувствуем дмитрию и надеемся на скорейшею реабилитацию черенка. доброград никогда не будем прежним
    #IStayWithCherenok
    Описание

    Творчество

  • Dead end story
    t1m1yepT t1m1yep

    у тебя картинки мертвые, заливай на имгур а не в дискорд
    https://www.timesnownews.com/technology-science/discord-to-switch-to-temporary-file-links-to-block-malware-distribution-article-105041402

    Архив историй архив

  • Боевик в стиле тарантино: NonRP, сомнительные отыгровки, Powergaming, Fungame, Mehan, Freedamage, Freekill
    t1m1yepT t1m1yep
    1. Дима Механайзер
    2. STEAM_0:1:442642190
    3. t1m1yep
    4. Генри Миллер (ливнул после просьбы не ливать, не успел взять), Курт Бекер (STEAM_0:1:445357108), Глеб Гулин (STEAM_0:0:31915557)
    5. выше указано
    6. нет
    7. 13:30 МСК 27.04.24

    В помещение моего друга зашли незнакомцы (~3 человека), я посчитал что они хотят нас ограбить и достал оружие, закрыл выход и приказал им встать к стене - изьять у них оружие (дабы те не могли создать аварийную для меня/моих друзей ситуацию) и передать полиции

    Генри Миллер моим просьбам не подчинился - под дулом пистолета вызвал полицию и начал меня бить механом. Я передал пистолет другу, тот также приказал ему лечь на землю. Парень не двигался, я отправил отыгровку что прижал его к земле и начал обыскивать (ответа не последовало, лишь механ прыжок и попытку сбежать) - после сопротивления Генри получил пулю: никаких отыгровок боли от него не было, он продолжил сопротивлятся, после чего, во время попыток вразумить его и положить на землю, Курт Бекер достает пистолет и стреляет в моего вооруженного друга Эдди, убивая того во время перестрелки, получая ранения. Он отходит за укрытие с целью перезарядки, в меня значительно не попали и я, воспользовавшись моментом, хватаю оружие и за укрытием перезаряжаю его (был один патрон), выхожу на Курта и получаю пулю в голову. Пометка: Генри был случайно застрелен в ходе перестрелки моего друга Эдди и Курта. Также добавлю что Генри многократно, механом включал анимацию “выбросить”, дабы симулировать доставание оружия.

    Далее, после смерти и во время начала штурма здания от Генри Миллера в looc чат поступают следующие сообщения, что я и мои друзья посчитали оскорбительными в нашу сторону:
    1
    После этого игрок покинул игру, вопреки нашим просьбам этого не делать.

    Глеб Гулин имеет полтора часа на сервере на момент написания жалобы, отправляет сомнительные отыгровки в чат, также он пытался схватить и придушить вооруженного человека (самый первый скрин):
    2
    3
    Описание
    Описание
    Описание
    Описание
    Описание
    Описание
    Описание
    Описание

    1. https://youtu.be/YF065W6gZBE
    2. да
    Решенные жалобы одобрено

  • дима черенок галерея
    t1m1yepT t1m1yep

    день 5 без доброграда занимаюсь мотокроссом начинаю выходить на улицу

    Творчество

  • Скиньте пожалуйста заменку на P90 Vector
    t1m1yepT t1m1yep

    @схщдзхщдзлщдз а почему тебе должны давать приватную заменку тогда?

    Архив

  • 🍊83 Hoover Criminals Gang (8-Tr3y) // #83HCG
    t1m1yepT t1m1yep

    @Pasha-Drobovik извини что у людей есть личная жизнь и сборы проходят ближе к выходным 😭

    Архив архив
  • 1 / 1
  • Войти

  • Login or register to search.
  • Первое сообщение
    Последнее сообщение
0
  • На сайт
  • Главная
  • Правила форума
  • Последние
  • Популярные
  • Пользователи
  • Группы