Menu
CoddyTech

Simon: Trình tự ngẫu nhiên

Thuộc phần Dự án trong hành trình Arduino của Coddy. Bài học 14 trên 24.

Giờ đến lượt bảng mạch. Khi bạn thả nút lần đầu, trò chơi bắt đầu: bảng mạch chọn ngẫu nhiên bốn màu, lưu chúng trong một mảng rồi phát chúng.

random(4) trả về 0, 1, 2 hoặc 3: một màu. Vòng lặp for điền vào mảng. Như trong trò chơi phản xạ, hãy tạo seed bằng micros() khi nhấn, nếu không thì ván nào cũng phát cùng một màu:

randomSeed(micros());
for (int i = 0; i < 4; i++) {
  sequence[i] = random(4);
}

Vòng lặp for thứ hai phát mẫu: bật đèn màu cùng nốt nhạc của màu đó, chờ, tắt đèn rồi chờ thêm lần nữa. Lần chờ thứ hai rất quan trọng khi một màu xuất hiện hai lần liên tiếp: nếu không có khoảng chờ này, đỏ, đỏ sẽ trông như một màu đỏ sáng liên tục. Lúc này người chơi chỉ quan sát, nên dùng delay() là ổn.

for (int i = 0; i < 4; i++) {
  lightOn(sequence[i]);
  delay(400);
  lightOff(sequence[i]);
  delay(200);
}

Một biến bool tên là playing ghi nhớ rằng trò chơi đã bắt đầu, để chỉ lần nhấn đầu tiên mới khởi động trò chơi.

challenge icon

Thử thách

Trung bình

Khiến bo mạch phát một mẫu:

  • thêm int sequence[4]; và bool playing = false;
  • khi thả nút và playing là false: khởi tạo bộ tạo số ngẫu nhiên, điền mảng bằng random(4), đặt playing thành true rồi phát mẫu
  • mẫu gồm: chờ 500 ms, sau đó bật từng màu và phát nốt nhạc tương ứng trong 400 ms, rồi im lặng 200 ms

Sau đó, các nút sẽ sáng và phát âm thanh như trước. Nhấn Chạy, nhấn một nút, rồi nhấn Kiểm tra.

Tự làm thử

// Mỗi màu có một phần tử: đỏ, xanh lá, xanh dương, vàng
const int ledPins[4] = {9, 10, 11, 12};
const int buttonPins[4] = {2, 3, 4, 5};
const int notes[4] = {262, 330, 392, 523};  // C, E, G và C cao
const int buzzerPin = 8;

int lastState[4] = {HIGH, HIGH, HIGH, HIGH};  // giá trị đọc gần nhất của từng nút

// Bật đèn màu i và phát nốt nhạc tương ứng.
void lightOn(int i) {
  digitalWrite(ledPins[i], HIGH);
  tone(buzzerPin, notes[i]);
}

// Tắt đèn màu i và dừng âm thanh.
void lightOff(int i) {
  digitalWrite(ledPins[i], LOW);
  noTone(buzzerPin);
}

void setup() {
  for (int i = 0; i < 4; i++) {
    pinMode(ledPins[i], OUTPUT);
    pinMode(buttonPins[i], INPUT_PULLUP);
  }
}

void loop() {
  for (int i = 0; i < 4; i++) {
    int state = digitalRead(buttonPins[i]);
    if (state == LOW && lastState[i] == HIGH) {  // đã nhấn
      lightOn(i);
    }
    if (state == HIGH && lastState[i] == LOW) {  // đã thả
      lightOff(i);
    }
    lastState[i] = state;
  }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Dự án

Tự luyện tập: Playground Arduino