Перейти к содержимому
  • 0
Teen_Romance

Работа условного оператора if

Вопрос

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

image.png.ddd7a8ff55efa9f90b2bfb4c12ab7490.png

Типа если y(nil) тогда не выполнять следующий иф.

image.png.852e6808def0e90712a684863151c16c.png

Как пофиксить?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

  • 0

Ну как где? "pe4[stack.id]" - тут и сравнивает. Если таблица pe4 содержит элемент с ключом, эквивалентным значению поля id таблицы stack, то результатом будет значение элемента таблицы pe4 по требуемому ключу.

 

Да, для того, чтобы ветвь if выполнилась, все условные элементы должны отличаться от nil. И нет, первая часть условия далеко не всегда будет истинна: если требуемый слот не содержит предметов, то переменная stack будет иметь значение nil. 

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Скорее всего, cry.getStackInSlot(j) для пустого слота возвращает пустую таблицу. Избежать исключения можно, проверив наличие поля cry.getStackInSlot(j).id.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

@eu_tomat Возможно я не так понял, но я сделал вот так:

image.png.634409ff92088d7f125e5dc829817ed9.png

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

image.png.b157cfd78c0f934f7b6a46085b3b7b6e.png

ну и собственно если поменять y=cry.getStackInSlot(j).id то получаю ту же  ошибку

Изменено пользователем Teen_Romance

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

zX5OdLjFMis.jpg

Проблема именно в том что программа не может индекс дать пустому слоту в 7 строке :(

Изменено пользователем Teen_Romance

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
11 минут назад, Teen_Romance сказал:

Проблема именно в том что программа не может индекс дать пустому слоту в 7 строке :(

Что значит "не может дать индекс"? Как выглядит ошибка? Какая версия OpenComputers?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

OpenComputers-MC1.7.10-1.6.2.12-universal - так называется файл в папке mods.

image.png.83395d47ca5b4ab84ec1256cbccd8d27.png

вот так выглядит ошибка

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Что такое crystal ? Все перебрал в МЭ так и не нашел этой штуки.

И вообще покажи что за установка, чтобы можно было воссаздать и протестировать. А то так долго можно перебирать и предполагать "а если ..."

Изменено пользователем Asior

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

@Teen_Romance

local stack
for i = 1, 10 do
  stack = cry.getStackInSlot(i)
  if stack then
    -- Делай чо надобно
  end
end

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

@ECS Вот код :

image.png.ec4a3ba312c71eda1c7399ce17262911.png

Вот ошибка:

image.png.57c221ce9c08730eb9ac87dc740fc411.png

Насколько я понимаю, указывает ошибку на 10 строку, а значит if stack then все равно не работает 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

@Asior crystal - это имя компонента Кристального сундука.

Больше 200 кб скрин я почему то не могу загрузить,  поэтому вот скрин установки.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Ни у кого большое не осталось идей как пофиксить это? Проблема где то в логике, но я не могу понять где (

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Идеи есть, но я пока не добрался до компа с Майнкрафтом, чтобы проверить.

Можешь показать значения cry.getStackInSlot(i) для пустых и заполненных слотов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
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" - то тут уж ты сам виноват. ПоДуМоЙ

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Компонент crystal, это прозрачный сундук из мода ironchest, подключается модом OpenPeripheral.

Нумерация начинается с единицы, cry.getStackInSlot(i) возвращает таблицу с описанием содержимого слота или nil, если слот пустой.

 

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

@Teen_Romance можешь выложить код не скриношотом, чтобы я его запустил у себя?

А ещё нужны версии ironchest и OpenPeripheral.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
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 :) А то на вики чет вообще ничего не понятно.

Спасибо всем кто помогал :) 

Изменено пользователем Teen_Romance

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
8 минут назад, eu_tomat сказал:

Кстати, выше @ECS предложил более удобный вариант поиска элемента по id в качестве ключа, что избавляет от цикла:

Я не понимаю в чем фишка этого варианта. Грубо говоря stack это таблица с кучей инфы от проверки жидкость ли это до dmg. А что у меня получится если я напишу pe4[stack.id] - я не понимаю. Типо ключем таблицы будет допустим "minecraft:cobblestone" и что дальше? И что вообще делает if stack and pe4[stack.id] then. Если в таблице stack(то есть в ячейке сундука) что то есть, и в таблице с ключем stack.id(имеется в виду что ключем будет тоже "miecraft:cobblestone" как я понял) что то есть, тогда что то там. Вообщем как то сложновато (

Изменено пользователем Teen_Romance

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
1 час назад, Teen_Romance сказал:

Я не понимаю в чем фишка этого варианта.

Это просто более удобный и быстрый вариант проверки наличия id предмета из сундука в твоей таблице pe4. Можно, конечно, делать сие через цикл - но зачем? Ключом элемента таблицы может быть что угодно: хоть число, хоть строка, хоть функция, хоть таблица - это уж как тебе удобно. Просто если поле id у предмета - это "minecraft:cobblestone", то и таблица pe4 для корректного поиска должна выглядеть соответствующе:

pe4 = {
  ["minecraft:cobblestone"] = true,
  ["minecraft:wood"] = true,
}

А конструкция "if stack and pe4[stack.id]" работает именно так, как ты и предположил - сначала проверяет наличие предмета в слоте,  а затем уже сверяет id с твоей таблицей

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
6 минут назад, ECS сказал:

А конструкция "if stack and pe4[stack.id]" работает именно так, как ты и предположил - сначала проверяет наличие предмета в слоте,  а затем уже сверяет id с твоей таблицей

А где она сравнивает id с таблицей? "if stack and pe4[stack.id]" Разве для того чтобы ветвь if выполнилась выражения должны быть равны между собой?  Разве не просто проверяется их пустота? Тип если stack не пустой и pe4[stack.id] не пуста тогда что то делается. Правая часть условия всегда будет истинна, но где они сравниваются? И вы имеет ввиду вообще без цикла или только с 1 фором? По ячейкам сундука ведь мне все равно нужно проходить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
3 минуты назад, ECS сказал:

Ну как где? "pe4[stack.id]" - тут и сравнивает. Если таблица pe4 содержит элемент с ключом, эквивалентным значению поля id таблицы stack, то результатом будет значение элемента таблицы pe4 по требуемому ключу.

Минуты 2 сидел вчитывался и не мог понять фишку, а потом каааак понял 🤣 На самом деле гениально, просто звучит сложно. Если элемента по такому ключу в таблице не будет то выражение просто будет равно nil )

Сложно как то еще применить но я подумаю)

Спасибо большое еще раз :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...