Есть пункты меню. Необходимо по нажатию кнопки выделять эти пункты по очереди. Но есть условия, когда некоторые пункты выбирать нельзя, их нужно пропустить. Вот пример из трех пунктов:
bool a, b, c; //если false значит выбирать этот пункт нельзя.
byte ind; //индекс выбранного пункта. 0 - ничего не выбрано.
Например в какой то момент пункты в таком состоянии:
a = false; b = true; c = false;
То значения ind должны быть циклично по нажатию кнопки такие: 2 0 2 0 2…
При a = true; b = true; c = true;
ind будут 0 1 2 3 0 1 2 3 0…
if (lnd < 3) lnd++; else lnd =0;
Это если не учитывать возможность выбора, а как сделать с учётом? Ну и вдруг это нужно будет сделать не с 3 а с 5 пунктами и допустим выбрать можно первый и пятый… (значения lnd 015015015…) Это я об универсальности алгоритма, а не тупой перебор всех вариантов lfами… Т.е. вопрос в том как рассчитывать этот самый ind
Пункт меню с индексом ind при отрисовки будет рисоваться выделенным. Но вопрос не в рисовании, а как грамотно перебирать значения lnd циклично
Покажите, пожалуйста, как Вы пытались решить эту задачу.
Только не вот это вот
а полный, рабочий скетч, который я могу без танцев с контрабасом запустить у себя и посмотреть.
Должны же Вы были сделать какую-то попытку самостоятельно, прежде, чем писать сюда.
Согласно лучшим традициям индусских программистов именно тупой перебор всех вариантов является наиболее оптимальным решением.
Я думал есть какие-то “стандартные” решения данного вопроса. Вопрос набирал с телефона, и показать как я пробовал сейчас не смогу, но обязательно, как доберусь до компьютера(но как скоро это будет, не могу к сожалению сказать) то покажу как я сделал этот алгоритм… Просто думаю, что есть грамотное решение данного алгоритма…
И да, я пока сделал только для определённого кол-ва пунктов меню, конкретно для 3, но расширить до любого кол-ва можно моё решение, но оно требует некоей модернизации кода…
if (ind ==0)
if (a) ind = 1; else if (b) ind = 2; else if (c) ind = 3;
if (ind == 1) if (b) ind=2;else if (c) ind = 3; else ind = 0;
if (ind == 2) if (c) ind=3; else ind =0;
if (ind == 3) ind =0;
Так что ли? Но это ужасно)
Войдите на старый форум. Наберите в строке поиска слово меню. Выбирайте разные варианты.
Да это в общем то не совсем меню (это я его так обозвал) Думал вообще к меню не относится… Это вроде как частный случай с одной стороны, но точно не я это придумал - с другой. Даже не знаю как это искать, а просматривать целиком решения по “меню” то ещё занятие… В чужом коде ещё и разобраться нужно… (
Данным вопросом занимался позавчера. Пробовал разные варианты, в основном ничего не получалось, на каком остановился сейчас не вспомню, впрочем рабочих было наверное всего два: (скажу честно, набираю с телефона без возможности проверить, но надеюсь ошибок не будет)
bool a, b, c;
byte ind;
void setup() {
Serial.begin(115200);
//тут меняем у пунктов возможность выбора
a=c=true; b=false;
ind=0;
}
byte getNextIndex(byte currInd) {
if (currInd == 3) return 0;
if (currInd ==0) if (a) return 1;
else if (b) return 2; else if (c) return 3; else return 0;
if (currInd == 1) if (b) return 2; else if (c) return 3; else return 0;
if (currInd == 2) if (c) return 3; else return 0;
}
void loop() {
ind = getNextIndex(ind) ;
Serial.println(ind);
delay(500);
}
Прошу прощение, не знаю как с телефона правильно оформить код
О, бл… получилось))
Чтобы наметить изящное решение, Вам нужно познакомиться с таким понятием как массивы.
Завести массив статуса пунктов меню. и проверять в условии, активен пункт или нет . Там же(в массиве статуса) производить необходимые изменения по ходу программы
byte menuItemStat[] = {1, 1, 1, 1, 0};
if(menuItemStat[0] )
//если пункт 0 меню активен - выполнить
знаком
Этот массив придётся переписывать каждый раз во время нажатия кнопки. Так как пункты могут сменить состояние возможности его выбора в любой момент. Вряд-ли с массивом будет проще… Чем я уже сделал.
У меня была мысль, что можно как-то использовать булевские значения при прибавление к ind.
Доберусь до компа, посмотрю как я ещё пробовал делать, покажу как сделаю(л)
В итоге то получается тот же самый код что и выше я нарисовал в 8
Хотя…может и можно попробовать заморочится с массивом… Надо будет попробовать… Там как бы не в хранении состояний пунктов вопрос, а их (состояние возможности выбора в текущий момент времени) учёт при изменении ind
В моем примере в 8 заменить луп на этот
void loop() {
a=random(2);
b=random(2);
c=random(2);
ind = getNextIndex(ind) ;
Serial.println(ind);
delay(500);
}
Это конечно слишком частая смена состояний, но… Примерно далеко но как то так)
И да, меня интересует только функция getNextIndex, остальной код только для её тестирования)
Хотя если рандом не из 2 сделать а попробовать из 10 (например или больше) 0 будет реже выпадать, может получится поудобнее тестировать (это я для себя :)))
Уверен?
const uint8_t maxItem = 5;
uint8_t menuItemStat[] = {1, 0, 1, 1, 0};
uint8_t currentIndex = 0;
uint8_t getNextIndex(uint8_t currInd);
void setup() {
Serial.begin(9600);
for (uint8_t i = 0; i < 10; i++) {
Serial.println(currentIndex);
currentIndex = getNextIndex(currentIndex + 1);
}
}
void loop() {
}
uint8_t getNextIndex(uint8_t currInd) {
if ( menuItemStat[currInd] ) { //если пункт меню активен
return currInd;
}
currInd++;
if ( currInd >= maxItem ) {
currInd = 0;
}
return getNextIndex(currInd);
}
Вывод:
0
2
3
0
2
3
0
2
3
0
Только аккуратнее с рекурсией, в этом случае нельзя чтобы в массиве все элементы были нулевыми - оно уйдет в вечную рекурсию пока программа не порушится. Хотя бы один элемент должен быть не нулевым.
Кстати, гуру программирования (особенно по рекурсиям).
А почему при таком массиве:
uint8_t menuItemStat[] = {0, 0, 1, 0, 1};
Полная ерунда в выводе?
2
4
5
6
2
4
5
6
Откуда 5 и 6 берется? ))

Пробовал разные варианты
// структура, описывающая пункт меню
struct MenuItem
{
bool active; // активен ли пункт меню
char *name; // строка пункта меню
};
// инициализация массива пунктов меню
MenuItem items[] = {
MenuItem{true,
"First item"},
MenuItem{true,
"Second item"},
MenuItem{false,
"Third item"},
MenuItem{true,
"LastItem"}};
...............................
// работа с пунктами меню
if (items[0].active)
{
/* Если пункт меню активен */
}
.

Этот массив придётся переписывать каждый раз во время нажатия кнопки.
Ещё можно числом обозначать набор “разрешимостей” - 0b10011001 (034703470…)
А их вставить в массив или менять значение формульно.

тупой перебор всех вариантов
Фу, как некрасиво!
Ну, Вы же говорите, “бл@дь”, а говорите “путана”, не “пидар@с” - а “гей”. Ну и здесь говорите: “Метод британского музея” - вумно, загадочно, по-европейски!
@ЕвгенийП , объясните что я не так сделал в #15, что в #16 - 5 и 6 «вылазят»?