Teen_Romance 4 Опубликовано: 14 марта, 2019 Хотел сделать так, чтобы если ячейка сундука пустая, то проверка не выполнялась, но все равно ругается почему то программа Типа если y(nil) тогда не выполнять следующий иф. Как пофиксить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 904 Опубликовано: 15 марта, 2019 Ну как где? "pe4[stack.id]" - тут и сравнивает. Если таблица pe4 содержит элемент с ключом, эквивалентным значению поля id таблицы stack, то результатом будет значение элемента таблицы pe4 по требуемому ключу. Да, для того, чтобы ветвь if выполнилась, все условные элементы должны отличаться от nil. И нет, первая часть условия далеко не всегда будет истинна: если требуемый слот не содержит предметов, то переменная stack будет иметь значение nil. Для работы программы нужно банально пробежаться по всем слотам сундука, проверить, есть ли что-либо в слоте - и если есть, то проверить, является ли id предмета в слоте валидным (т.е. содержится ли он в таблице pe4). По крайней мере, я именно так понял условие задачи. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 14 марта, 2019 Скорее всего, cry.getStackInSlot(j) для пустого слота возвращает пустую таблицу. Избежать исключения можно, проверив наличие поля cry.getStackInSlot(j).id. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 14 марта, 2019 (изменено) @eu_tomat Возможно я не так понял, но я сделал вот так: И теперь ошибка в том что не может дать индекс полю если пустой слот и не выполняет вообще ничего: ну и собственно если поменять y=cry.getStackInSlot(j).id то получаю ту же ошибку Изменено 14 марта, 2019 пользователем Teen_Romance Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 14 марта, 2019 (изменено) Проблема именно в том что программа не может индекс дать пустому слоту в 7 строке Изменено 14 марта, 2019 пользователем Teen_Romance Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 14 марта, 2019 11 минут назад, Teen_Romance сказал: Проблема именно в том что программа не может индекс дать пустому слоту в 7 строке Что значит "не может дать индекс"? Как выглядит ошибка? Какая версия OpenComputers? 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 14 марта, 2019 OpenComputers-MC1.7.10-1.6.2.12-universal - так называется файл в папке mods. вот так выглядит ошибка Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Asior 586 Опубликовано: 14 марта, 2019 (изменено) Что такое crystal ? Все перебрал в МЭ так и не нашел этой штуки. И вообще покажи что за установка, чтобы можно было воссаздать и протестировать. А то так долго можно перебирать и предполагать "а если ..." Изменено 14 марта, 2019 пользователем Asior 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 904 Опубликовано: 14 марта, 2019 @Teen_Romance, local stack for i = 1, 10 do stack = cry.getStackInSlot(i) if stack then -- Делай чо надобно end end 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 14 марта, 2019 @ECS Вот код : Вот ошибка: Насколько я понимаю, указывает ошибку на 10 строку, а значит if stack then все равно не работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 14 марта, 2019 @Asior crystal - это имя компонента Кристального сундука. Больше 200 кб скрин я почему то не могу загрузить, поэтому вот скрин установки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 15 марта, 2019 Ни у кого большое не осталось идей как пофиксить это? Проблема где то в логике, но я не могу понять где ( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 15 марта, 2019 Идеи есть, но я пока не добрался до компа с Майнкрафтом, чтобы проверить. Можешь показать значения cry.getStackInSlot(i) для пустых и заполненных слотов? 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 904 Опубликовано: 15 марта, 2019 31 минуту назад, Teen_Romance сказал: Ни у кого большое не осталось идей как пофиксить это? Проблема где то в логике, но я не могу понять где ( Мяу, ну написали же русским языком, что getStackInSlot(номер слота) возвращает таблицу с информацией о предмете, если таковой имеется в слоте - либо nil в том случае, если слот пустой, для чего и нужна проверка на "пустотность". Шаг 1. Получил инфу о предмете в слоте stack = getStackInSlot(i) Шаг 2. Убедился, что в слоте есть предмет if stack then Шаг 3. Обработал информацию о предмете в слоте так, как требуется. НЕ НУЖНО вызывать getStackInSlot() еще раз. Переменная stack уже хранит результат вызова getStackInSlot() if stack.id == 8 then Конкретно в твоем случае ошибка происходит по той причине, что getStackInSlot возвращает nil, а ты пытаешься получить поле от возвращаемых данных по ключу id - вот и получаешь ошибку attempt to index a nil value. Слот пустой, id не существует. Делай проверку разово - и работай с переменной stack. Также я не совсем понимаю, почему ты используешь два цикла for i = 1, 10 / for j = 1, 10, когда число предметов в ME-сети явно может превышать 100. Наверняка там должен иметься метод getInventorySize, или getItemCount, или еще какой-то схожий - используй его. И еще: для сравнения id предметов с таблицей pe4 также придется делать отдельную логику. Что-то наподобие: local pe4 = { [1] = "камушек", [8] = "доски" } ... stack = cry.getStackInSlot(i) if stack and pe4[stack.id] then print("рассматривается валидный предмет") end Кроме того, как заметил @Asior, мы понятия не имеем, что это за компонент такой под названием "crystal". Так что если выяснится, что информация о его stack'ах вообще не содержит никаких id, либо его id является строковым наподобие "minecraft:stone" - то тут уж ты сам виноват. ПоДуМоЙ 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 15 марта, 2019 Компонент crystal, это прозрачный сундук из мода ironchest, подключается модом OpenPeripheral. Нумерация начинается с единицы, cry.getStackInSlot(i) возвращает таблицу с описанием содержимого слота или nil, если слот пустой. Код из стартового поста выглядит работоспособным, и я пока не вижу проблему. @Teen_Romance можешь выложить код не скриношотом, чтобы я его запустил у себя? А ещё нужны версии ironchest и OpenPeripheral. 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 15 марта, 2019 (изменено) 3 часа назад, ECS сказал: Конкретно в твоем случае ошибка происходит по той причине, что getStackInSlot возвращает nil, а ты пытаешься получить поле от возвращаемых данных по ключу id - вот и получаешь ошибку attempt to index a nil value. Слот пустой, id не существует. Делай проверку разово - и работай с переменной stack. Проснулся и после прочтения всего что вы тут писали понял: ошибка из за того что первым фором (for i=1,10) я прохожу по таблице с рецептом (таблица pe4 ) в которой всего 2 ключа(или 2 таблицы внутри, не знаю как правильно сказать). А вторым фором(for j=1,10) я прохожу по ячейкам кристального сундука, для сравнения рецепта (pe4) и наличия ресурсов в сундуке. А из за того что первый for 10 раз идет по таблице в которой всего 2 элемента я получал ошибку(Так глупо что аж ... ). 3 часа назад, ECS сказал: Также я не совсем понимаю, почему ты используешь два цикла for i = 1, 10 / for j = 1, 10, когда число предметов в ME-сети явно может превышать 100. Наверняка там должен иметься метод getInventorySize, или getItemCount, или еще какой-то схожий - используй его. Я просто давно не работал с OC и сейчас маленькими кусочками вспоминаю что и как работает. На скринах это просто куски программы ничего по сути пока что не делающей. 2 цикла for я использую чтобы первый проходил по таблице с рецептом, а второй по ячейкам сундука(Ведь нужные ресурсы могут быть не только в первых 2,3,4,10 слотах). 10 я в цикле указал просто так, для теста, я понимаю что в сундуке около 100 ячеек. Не знаю насколько это рационально использовать 2 фора, но как я говорил выше, я просто пробую что и как работает) 3 часа назад, ECS сказал: И еще: для сравнения id предметов с таблицей pe4 также придется делать отдельную логику. Что-то наподобие: Возможно с этим у меня в будущем возникнут проблемы, но я пока что просто проверяю что и как работает. Попробую пока что использовать для проверки ресурсов в сундуке и сравнения с рецептом, то что у меня на скринах. А вообще я хочу написать программу для автокарфата вещей на варпе. Типо на компе выбираешь дробитель из IC2, тебе показывает какие и сколько ресурсов нужно, ты кладешь их в сундук и для тебя делается дробитель. Хочется еще сделать граф оформление(чтобы по экрану можно было клацать) поэтому у меня в скором времени появятся вопросы с event и GUI А то на вики чет вообще ничего не понятно. Спасибо всем кто помогал Изменено 15 марта, 2019 пользователем Teen_Romance Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 15 марта, 2019 11 минут назад, Teen_Romance сказал: Проснулся и после прочтения всего что вы тут писали понял: ошибка из за того что первым фором (for i=1,10) я прохожу по таблице с рецептом (таблица pe4 ) в которой всего 2 ключа(или 2 таблицы внутри, не знаю как правильно сказать). А вторым фором(for j=1,10) я прохожу по ячейкам кристального сундука, для сравнения рецепта (pe4) и наличия ресурсов в сундуке. А из за того что первый for 10 раз идет по таблице в которой всего 2 элемента я получал ошибку. Кхе. Я ожидал увидеть кривую работу компонента, а ошибка возникла в своей же таблице. Ларчик просто открывался. Кстати, выше @ECS предложил более удобный вариант поиска элемента по id в качестве ключа, что избавляет от цикла: 3 часа назад, ECS сказал: if stack and pe4[stack.id] then Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 15 марта, 2019 (изменено) 8 минут назад, eu_tomat сказал: Кстати, выше @ECS предложил более удобный вариант поиска элемента по id в качестве ключа, что избавляет от цикла: Я не понимаю в чем фишка этого варианта. Грубо говоря stack это таблица с кучей инфы от проверки жидкость ли это до dmg. А что у меня получится если я напишу pe4[stack.id] - я не понимаю. Типо ключем таблицы будет допустим "minecraft:cobblestone" и что дальше? И что вообще делает if stack and pe4[stack.id] then. Если в таблице stack(то есть в ячейке сундука) что то есть, и в таблице с ключем stack.id(имеется в виду что ключем будет тоже "miecraft:cobblestone" как я понял) что то есть, тогда что то там. Вообщем как то сложновато ( Изменено 15 марта, 2019 пользователем Teen_Romance Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 904 Опубликовано: 15 марта, 2019 1 час назад, Teen_Romance сказал: Я не понимаю в чем фишка этого варианта. Это просто более удобный и быстрый вариант проверки наличия id предмета из сундука в твоей таблице pe4. Можно, конечно, делать сие через цикл - но зачем? Ключом элемента таблицы может быть что угодно: хоть число, хоть строка, хоть функция, хоть таблица - это уж как тебе удобно. Просто если поле id у предмета - это "minecraft:cobblestone", то и таблица pe4 для корректного поиска должна выглядеть соответствующе: pe4 = { ["minecraft:cobblestone"] = true, ["minecraft:wood"] = true, } А конструкция "if stack and pe4[stack.id]" работает именно так, как ты и предположил - сначала проверяет наличие предмета в слоте, а затем уже сверяет id с твоей таблицей Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 15 марта, 2019 6 минут назад, ECS сказал: А конструкция "if stack and pe4[stack.id]" работает именно так, как ты и предположил - сначала проверяет наличие предмета в слоте, а затем уже сверяет id с твоей таблицей А где она сравнивает id с таблицей? "if stack and pe4[stack.id]" Разве для того чтобы ветвь if выполнилась выражения должны быть равны между собой? Разве не просто проверяется их пустота? Тип если stack не пустой и pe4[stack.id] не пуста тогда что то делается. Правая часть условия всегда будет истинна, но где они сравниваются? И вы имеет ввиду вообще без цикла или только с 1 фором? По ячейкам сундука ведь мне все равно нужно проходить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Teen_Romance Автор вопроса 4 Опубликовано: 15 марта, 2019 3 минуты назад, ECS сказал: Ну как где? "pe4[stack.id]" - тут и сравнивает. Если таблица pe4 содержит элемент с ключом, эквивалентным значению поля id таблицы stack, то результатом будет значение элемента таблицы pe4 по требуемому ключу. Минуты 2 сидел вчитывался и не мог понять фишку, а потом каааак понял 🤣 На самом деле гениально, просто звучит сложно. Если элемента по такому ключу в таблице не будет то выражение просто будет равно nil ) Сложно как то еще применить но я подумаю) Спасибо большое еще раз Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Хотел сделать так, чтобы если ячейка сундука пустая, то проверка не выполнялась, но все равно ругается почему то программа
Типа если y(nil) тогда не выполнять следующий иф.
Как пофиксить?
Поделиться сообщением
Ссылка на сообщение
Поделиться на других сайтах