Этюд на тему "Угадайка"
- Войдите на сайт для отправки комментариев
1. Код написать и сам смогу, просьба не отсылать в раздел "Ищу исполнителя" ;)
2. Идеи алгоритма вроде как формируются, но пока тупые. Может кто подскажет более умный АЛГОРИТМ.
Итак, задачка.
Есть 12 кнопок. По рандому выбирается 4 цифры из 12 (не повторяющиеся) в интервале 1-9,A,B,C.
Примерно так:
while(!KBDread())
{
randomSeed(millis());
delay(1000);
}
while(i<4)
{
ChemodanKey[i]=random(1,13);
switch(i)
{
case 0:
i++;
break;
case 1:
if(ChemodanKey[i]!=ChemodanKey[0]){i++;}
break;
case 2:
if(ChemodanKey[i]!=ChemodanKey[0]&&ChemodanKey[i]!=ChemodanKey[1]){i++;}
break;
case 3:
if(ChemodanKey[i]!=ChemodanKey[0]&&ChemodanKey[i]!=ChemodanKey[1]&&ChemodanKey[i]!=ChemodanKey[2]){i++;}
break;
}
}
Хотя уверен не оптимальное решение.
Дальше алгоритм простой:
если нажата кнопка из списка ЧемоданКей - запоминаем ее (и показываем на экране), ждем нажатие следующей.
Если следующая и далее кнопки из списка - продолжаем пока не будет угадано все 4 цифры (показ и гимн в динамик ;)
Если ошибка - цифра не из списка - сирена, сброс показа дисплея и блокировка на Х минут.
После окончания блокировки цикл начинается сначала.
Идеи?
Примерно так:
while(!KBDread()) { randomSeed(millis()); delay(1000); } while(i<4) { ChemodanKey[i]=random(1,13); switch(i) { case 0: i++; break; case 1: if(ChemodanKey[i]!=ChemodanKey[0]){i++;} break; case 2: if(ChemodanKey[i]!=ChemodanKey[0]&&ChemodanKey[i]!=ChemodanKey[1]){i++;} break; case 3: if(ChemodanKey[i]!=ChemodanKey[0]&&ChemodanKey[i]!=ChemodanKey[1]&&ChemodanKey[i]!=ChemodanKey[2]){i++;} break; } }i не инициализирована. seed вызывается пачку раз зачем-то, причём вызывается как-то странно. Если это начало работы программы, то он там практически всегда одинаковый будет. Если уж нужен seed - надо брать analogRead с висящего в воздухе пина. Дальнейший выбор уж больно заморочный, но это Ваш выбор.
1. Код написать и сам смогу, просьба не отсылать в раздел "Ищу исполнителя" ;)
Успехов!
Идеи?
Я бы это скорей так писал. Код не проверялся на компилируемость
for(byte i=0;i<4;) { byte a=random(1,13); for(byte j=0;j<i;j++) { if(ChemodanKey[j]==a) { a=0;//повтор!!! break; } } if(a) ChemodanKey[i]=a; else continue; i++; }.Или хотяб свитч причесал
switch(i) { case 3: if(ChemodanKey[i]==ChemodanKey[2]) break; case 2: if(ChemodanKey[i]==ChemodanKey[1]) break; case 1: if(ChemodanKey[i]==ChemodanKey[0]) break; case 0: i++; }Спасибо, первый вариант попробую - более корректен на мой взягляд.
А второй вариант может неправильно отработать:
если i==0 то все понятно - записываем первыую цифру, если 1 - то сравниваем с первой, если 2 - то нужно сравнивать с первой и второй на совпадение, а для 3 - со всеми тремя предыдущими - т.к. цифры должны быть уникальными и несовпадающими.
если 2 - то нужно сравнивать с первой и второй на совпадение, а для 3 - со всеми тремя предыдущими - т.к. цифры должны быть уникальными и несовпадающими.
Дак учтено. Если при 2 сравнение свыявило совпадение, то бреак, иначе идем далее а далее случай 1, те проверка первого числа.
Вот что получилось - с учетом того что это процедура из части проекта - те используются глобалы за скобками:
void StartMODE3(void)// режим ЧЕМОДАН { //при старте выбираем время блокировки //на экране bd (block delay) в пятиминутках //выбор на кнопках от 1 до 12 по 5 минут == от 5 до 60 минут //затем инициализация датчика случайных чисел SE //генерируется 4 цифры кода, выводятся на экран на 2 сек //если нажата неправильная цифра - блокировка на время bd минут и сирена //если все цифры угаданы - звук и переход на новую игру //если найден ключ ТМ - сбрасываем все включая звук, найденные ключи //если с ключем ТМ наата любая кнопка - рестарт игры while(1) { byte EndGAME=0; byte i=1; byte j=0; byte buff=0; byte ChmNM=0;// цифра угадана byte numKey=0;// количество угаданных цифр byte ChemodanRead[4]={0,0,0,0};//буфер //инициализация параметров игры tm1637.clearDisplay();//на экран выводим bd tm1637.display(0,11); tm1637.display(1,13); buff=KBDread(); do//ждем нажатие на кнопку { buff=KBDread();//читаем кнопки TimeCH=buff*5;//устанавливаем тайм-аут для ошибки набора *5 мин tm1637.display(3,buff);// выводим число 5-минуток тайм-аута }while(!buff);//ждем нажатие на кнопку delay(4000); tm1637.clearDisplay();//на экран выводим 5Е tm1637.display(0,5); tm1637.display(1,14); while(!KBDread())//ждем нажатие на кнопку { randomSeed(millis());//инициализируем счетчик рандома delay(200); } ChemodanKey[0]=random(1,13);//из списка 1-12 первая цифра while(i<4)//набираем 4 цифры { buff=random(1,13);//из списка 1-12 следующая цифра ChmNM=1; for(j=0;j<i;j++) { if(ChemodanKey[j]==buff)//Если цифра повторяется { ChmNM=0;//сбрасываем счетчик - идем на повтор } } if (ChmNM)//если цифра новая - запоминаем, ищем следующую { ChemodanKey[i]=buff; i++; } } ChmNM=0; for (i=0;i<4;i++) { tm1637.display(i,ChemodanKey[i]);//выводим установленные цифры Serial.print(ChemodanKey[i],HEX); //для отладки } Serial.println(); //для отладки SirenaOUT;//мявкаем в динамик delay(2000); tm1637.clearDisplay();//стираем все tm1637.display(0,0);//на экран 0 numKey=0; while(!EndGAME)//пока EndGAME==0 крутим цикл { if(ds.reset()) // если обнаружен ключ сбрасываем все в 0 { for(i=0;i<=numKey;i++) { ChemodanRead[i]=0;//сбросили хранилище угаданных ключей } ChmNM=0;//изменили статус на 0 numKey=0;//число угаданных 0 tm1637.clearDisplay();//стираем все tm1637.display(0,0);//на экран 0 if (KBDread())//если нажата кнопка стартуем новую игру { EndGAME=1; } } buff=KBDread();//читаем клавиатуру if(buff)//если кнопка нажата { ChmNM=0; for(i=0;i<4;i++)// проверяем цифру { if(buff==ChemodanKey[i])//если цифра есть в коде { ChmNM=1;//изменили статус на 1 ChemodanRead[numKey]=ChemodanKey[i];//запомнили угаданную цифру SirenaOUT();//мявкнули в динамик tm1637.display(numKey,ChemodanRead[numKey]);//вывели на экран угаданную цифру } } if(!ChmNM)//если не угадали { for(i=0;i<=numKey;i++) { ChemodanRead[i]=0;//сбросили хранилище угаданных ключей } ChmNM=0;//изменили статус на 0 numKey=0;//число угаданных 0 tm1637.clearDisplay();//стираем все for(i=0;i<4;i++) { tm1637.display(i,0);//на экран 0 } Serial.println(" ERROR "); //для отладки PrevMillis=millis();//запоминаем первый миллс while(millis()-PrevMillis<TimeCH*TimeXX)//в течении ХХ минут ревем сиреной { SirenaOUT();//сирена delay(1000); Serial.println(" ERROR 1"); //для отладки if(ds.reset()) // если обнаружен ключ сбрасываем все в 0 { for(i=0;i<=numKey;i++) { ChemodanRead[i]=0;//сбросили хранилище угаданных ключей } PrevMillis=TimeCH*TimeXX+millis(); ChmNM=0;//изменили статус на 0 numKey=0;//число угаданных 0 tm1637.clearDisplay();//стираем все tm1637.display(0,0);//на экран 0 if (KBDread())//если нажата кнопка стартуем новую игру { EndGAME=1; } } } tm1637.clearDisplay();//стираем все tm1637.display(0,0);//на экран 0 }else { numKey++;//если угадали - следующий номер delay(1000); } } if(numKey>3)//если угадали все 4 - гимн { SirenaOUT(); SirenaOUT(); SirenaOUT(); EndGAME=1; } } } }