воскресенье, 2 ноября 2014 г.

Игра Simon Say на Blockduino

Как-то встретил товарища, который тоже увлекается Ардуинкой. И похвастался он... Та неа, не похвастался, а просто между прочим проскользнуло, что делал он игру Simon Say и она очень понравилась его сыну.
Ессно и мне захотелось посмотреть, что она из себя представляет. Тем более, есть из чего делать.
Нашел пару вариантов.

Сначала классический:

Четыре разноцветных кнопки и соответствующего цвета светодиоды. И одна кнопка для запуска игры.
Взято все отсюда: http://scuola.arduino.cc/

Т.е. нам нужны:
Подключал все в другие порты, чем в примере. Позже объясню почему. Подключил все в плату BlockIO, хотя, т.к. здесь используются только цифровые порты, можно было бы подключить и в платку PlugDIO, но в следующем примере будет использован и аналоговый порт, поэтому, чтоб не переставлять туда-сюда сразу установил BlockIO.


 Код переправил немного под себя, но пока не выложу, т.к. мне не понравилось резкое моргание светодиодами. Т.к. светодиоды большие (10 мм), то при резком включении и выключении бьет по глазам. А так как на микроконтроллере есть четыре порта с ШИМ'ом, то можно организовать плавное зажигание и затухание светодиодов. Поэтому я их и подключил в порта D5, D6, D9 и D10.

Update: Вариант классический, но без пусковой кнопки и с плавными светодиодами

В общем, сделал как хотел и даже чуточку больше: выбросил пусковую кнопку (зачем она нужна, если в режиме ожидания простаивают все остальные), теперь нажатие любой кнопки запускает игру; упростил код подключив библиотеки 'LED.h' и 'Button.h'; добавил плавность зажигания светодиодов; ну и попутно изменил режим моргания светодиодами в режиме ожидания.

Simon Say Faded LEDs


Код под спойлером:


/*This sketch is a version of the famous Simon Says game. You can use it and improved it adding
 levels and everything you want to increase the diffuculty!
  
 author : Arturo Guadalupi <a.guadalupi@arduino.cc>
 edited : Vasyl Yudin <vasyl.yudin@gmail.com>
 */
#include <Button.h>
#include <LED.h>

const int bttn_start = 4;
const int max_level = 100;

Button bttn[4] = { Button(2), Button(7), Button(8), Button(3) };
LED led[4] = { LED(5), LED(6), LED(9), LED(10) };

int sequence[max_level];
int your_sequence[max_level];
int level = 1;
 
int velocity = 250;
 
void setup() {
  Serial.begin(9600);
  ready();
  delay(1000);
}
 
void loop() 
{    
  if ( bttn[0].isPressed() || 
       bttn[1].isPressed() || 
       bttn[2].isPressed() || 
       bttn[3].isPressed() || 
       level != 1) //If any button is pressed or you're plaing
  {
    show_sequence();    //show the sequence
    get_sequence();     //wait for your sequence
  }
  else {
    generate_sequence();//generate a sequence;
    ready();
  }
}
 
void show_sequence()
{
  for (int i=0; i<4; i++)
    led[i].off();
    
  for (int i = 0; i < level; i++)
  { 
    led[sequence[i]].fadeIn(velocity);
    led[sequence[i]].fadeOut(velocity/2);
    delay(200);
  }
}
 
void get_sequence()
{
  int isPush = 0; //this flag indicates if the sequence is correct
 
  for (int j=0; j<level; j++)
  {
    isPush = 0;
    while(isPush == 0)
    {
      for(int i=0; i<4; i++)
        if (bttn[i].isPressed())
        {
           led[i].on();
           your_sequence[j] = i;
           isPush = 1;
           delay(200);
           if (your_sequence[j] != sequence[j])
           {
             wrong_sequence();
             return;
           }
           led[i].off();
        } 
    }
  }
  right_sequence();
}
 
void generate_sequence()
{
  randomSeed(millis()); //in this way is really random!!!
 int randPin;
  for (int i = 0; i < max_level; i++)
  {
    sequence[i] = (int)random(4);
  }
}

void wrong_sequence()
{
  led[0].on();
  led[1].on();
  led[2].off();
  led[3].off();
  for (int j=0; j<10; j++)
  {
    for(int i=0; i<4; i++){
      led[i].toggle();
    }
    delay(250);
  }
  level = 1;
  velocity = 250;
}
 
void right_sequence()
{
  for (int i=0; i<4; i++)
    led[i].off();
 
  for (int i=0; i<4; i++)
    led[i].fadeIn(100);

  for (int i=0; i<4; i++)
    led[i].fadeOut(100); 
  delay(500);
 
  if (level < max_level)
    level++;
 
  velocity -= 5; //increase difficulty
}

void ready() {// lights up leds during stand-by
  int time = millis()/16;
  for(int i=0; i<4; i++)
  {
    led[i].setValue(255-(time+i*32)%128);
  Serial.print((255-(time+i*32)%128));Serial.print(" ");
  }
  Serial.println();
  delay(100);
}





Вариант другой

Описан здесь: http://madrid.verkstad.cc/
Здесь ввод уже не с кнопок, а с одного резистора. Соответственно и больше пространства для маневров: можно добавить больше светодиодов, например семь; можно подключить зуммер и изменять его тональность: каждому светодиоду - свою ноту, т.е. развивать еще и слуховую память.
Но это я апробирую чуток позже...
Уже попробовал, вот он:
Но описание и код будут уже в следующей статье.