#include <FastLED.h>

#define NUM_LEDS 12             // LED灯珠数量
#define DATA_PIN 14              // Arduino输出控制信号引脚A0
#define LED_TYPE WS2812         // LED灯带型号
#define COLOR_ORDER GRB         // RGB灯珠中红色、绿色、蓝色LED的排列顺序

CRGB leds[NUM_LEDS];

uint8_t max_bright = 128;
uint8_t Tone = 1; //音调变量

uint8_t Music = 1; //第几乐谱

uint8_t Num_of_Tones = 0; //乐谱音调数

uint8_t T = 1;
uint8_t pressed_Tone = 0; //长按判定键
uint8_t NUM_OF_TONES[3] = {20, 30, 40}; //乐谱1音调数,取三个乐谱数的最大值加1填入下面music数组的第二位: music[3][👉这里👈]

uint8_t music[3][41] = { //👈music[第几首][第几个音(第0位代表小调,0为C小调,1为F小调,2为G小调)]
  {0,/*👈0代表这首曲子是C小调这一排后20个是各个音符*/ 1, 6, 9, 2, 5, 8, 1, 4, 7, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 3},
  {1,/*👈1代表这首曲子是F小调这一排后20个是各个音符*/ 3, 2, 1, 6, 5, 4, 9, 8, 7, 6, 5, 4, 7, 4, 1, 8, 5, 2, 5, 8, 3, 2, 1, 6, 5, 4, 9, 8, 7, 6},
  {2,/*👈2代表这首曲子是G小调这一排后20个是各个音符*/ 9, 5, 1, 4, 5, 6, 8, 5, 2, 3, 5, 7, 8, 5, 2, 7, 4, 1, 2, 3, 3, 2, 1, 6, 5, 4, 9, 8, 7, 6, 3, 2, 1, 6, 5, 4, 9, 8, 7, 6}
};

bool Key[3][13][12] = {
  { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}//C小调
  },
  {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}//F小调
  },
  {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0},
    {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0},
    {1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} //G小调
  }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  for (int i = 2; i < 14; i++)
  {
    pinMode(i, INPUT_PULLUP);//设置按键引脚为输入状态并且内部上拉
  }
  LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);  // 初始化光带
  FastLED.setBrightness(max_bright);

  Num_of_Tones = NUM_OF_TONES[Music - 1];//设置乐谱音调数
}

void loop() {

  Play_judge();
}
void Play_judge()
{
  for (uint8_t s = 0; s < 12; s++)
  {
    if (Key[music[Music - 1][0]][music[Music - 1][Tone]][s] == 1) //不应按下的按键
    {
      leds[s] = CRGB::Blue;
      FastLED.show();
    }
    if (Key[music[Music - 1][0]][music[Music - 1][Tone]][s] == 0) //应该按下的按键
    {
      leds[s] = CRGB::Green;
      FastLED.show();
    }
  }
  if (T == 0) {
    while (digitalRead(pressed_Tone + 2) == LOW) {
      delay(100);
    }
    delay(1000);
  }
  uint8_t  j = 0;
  uint8_t keys[12] = {};

  while (1) {  //扫描按键被按下的while循环
    keys[j] = digitalRead(j + 2);
    if (keys[j] == 0) {
      break;
    }
    j++;
    if (j == 12)
    {
      j = 0;
    }
  }

  unsigned long starttime = millis();
  while (millis() - starttime < 2000)//规范按键时间段,两秒内按下正确的按键
  {
    for (uint8_t k = 0; k < 12; k++)
    {
      keys[k] = digitalRead(k + 2);

      if (keys[k] == 1)
        pressed_Tone = k;
    }
    T = 0;
  }

  for (uint8_t y = 0; y < 12; y++)//乐谱比对
  {
    if (keys[y] != Key[music[Music - 1][0]][music[Music - 1][Tone]][y])
    {
      ERROR();
      return;
    }
  }
  Tone++;
  if (Tone == Num_of_Tones)
    Tone = 1;
}

void ERROR()
{
  for (int i = 0; i < 12; i++) {
    leds[i] = CRGB::Yellow;
    FastLED.show();
  }
  delay(3000);
}