Simon: Trò chơi hoàn chỉnh
Thuộc phần Dự án trong hành trình Arduino của Coddy. Bài học 16 trên 24.
Simon thực sự bắt đầu với một chuỗi ngắn rồi dài dần. Vòng 1 phát một màu. Mỗi lần bạn lặp lại đúng một vòng, bảng sẽ giữ nguyên các màu và thêm một màu vào cuối, cho đến khi bạn mắc lỗi.
Mảng cần đủ chỗ cho một ván chơi dài, cùng với một biến length để theo dõi số chỗ đang dùng. Thêm một màu gồm hai dòng:
sequence[length] = random(4);
length++;Khởi tạo giá trị ban đầu một lần khi trò chơi bắt đầu. playSequence() giờ phát length màu thay vì bốn màu, và vòng chơi kết thúc khi step đạt đến length.
Một lỗi sẽ kết thúc trò chơi bằng âm thanh rõ ràng không phải nốt nhạc, ở tần số 110 Hz trong một giây, rồi in ra điểm số: số vòng đã hoàn thành, length - 1, vì vòng bị thua không được tính.
Mảng có 20 vị trí và chương trình không bao giờ được ghi vượt quá giới hạn, vì vậy người chơi sẽ thắng nếu lặp lại đúng 20 màu.
Thử thách
KhóBiến trò chơi thành phiên bản hoàn chỉnh:
const int MAX_STEPS = 20;,int sequence[MAX_STEPS];vàint length = 0;- trò chơi bắt đầu với một màu; mỗi vòng chơi được lặp lại đúng sẽ thêm một màu và phát toàn bộ dãy
- nếu mắc lỗi: phát âm ở tần số 110 Hz trong 1000 ms, sau đó in ra
Game over! Score:cùng điểm số, rồi kết thúc trò chơi - nếu lặp lại đúng 20 màu: in ra
You win!và kết thúc trò chơi
Nhấn Chạy, xem bạn chơi được đến đâu, 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
int sequence[4]; // các màu mà bo mạch phát
bool playing = false; // false cho đến khi một lần nhấn bắt đầu trò chơi
int step = 0; // số màu người chơi đã lặp lại
// 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);
}
// Phát chuỗi: mỗi màu sáng trong 400 ms, rồi im lặng 200 ms.
void playSequence() {
delay(500);
for (int i = 0; i < 4; i++) {
lightOn(sequence[i]);
delay(400);
lightOff(sequence[i]);
delay(200);
}
}
// Chọn một chuỗi ngẫu nhiên mới và phát chuỗi đó.
void startGame() {
randomSeed(micros());
for (int i = 0; i < 4; i++) {
sequence[i] = random(4);
}
playing = true;
step = 0;
playSequence();
}
// Người chơi thả nút màu i: đây có phải màu tiếp theo trong chuỗi không?
void checkPress(int i) {
if (i != sequence[step]) {
Serial.println("Wrong!");
playing = false;
return;
}
step++;
if (step == 4) {
Serial.println("Well done!");
playing = false;
}
}
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(buttonPins[i], INPUT_PULLUP);
}
Serial.begin(9600);
}
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) { // nhả nút
lightOff(i);
if (playing == false) {
startGame();
} else {
checkPress(i);
}
}
lastState[i] = state;
}
}
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
1Đèn giao thông
Chu kỳ đèn giao thôngĐèn giao thông dùng millis()Nút qua đườngTín hiệu đi bộ và còi báo4Simon
Simon: Nút bấm và nốt nhạcSimon: Trình tự ngẫu nhiênSimon: Lặp lại mẫuSimon: Trò chơi hoàn chỉnhTự luyện tập: Playground Arduino