Menu
CoddyTech

Trò chơi phản xạ: Thời gian tốt nhất

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

Bản phác thảo lưu thời gian tốt nhất (thấp nhất) trong một biến và in thời gian đó sau mỗi lượt.

Lúc bắt đầu, chưa có thời gian tốt nhất. Dùng giá trị mà không lượt chơi thực nào có thể đạt được, 0, để biểu thị “chưa có”. Sau mỗi lượt: nếu chưa có thời gian tốt nhất hoặc lượt này nhanh hơn thời gian đó, thì lượt này trở thành lượt tốt nhất mới.

if (best == 0 || reaction < best) {
  best = reaction;
}
Serial.print("Best: ");
Serial.print(best);
Serial.println(" ms");

Đặt đoạn code này trong trạng thái LIT, nơi một lượt kết thúc với thời gian thực. Bắt đầu sai sẽ không chạy đến đoạn code đó, nên không thể trở thành kỷ lục.

Thời gian tốt nhất được lưu trong bộ nhớ của bo mạch (RAM), bộ nhớ này sẽ bị xóa khi tắt nguồn: kỷ lục sẽ được giữ đến khi bạn nhấn Chạy lần nữa.

challenge icon

Thử thách

Trung bình

Ghi lại:

  • một biến best, ban đầu bằng 0
  • sau mỗi lượt tính thời gian, nếu best bằng 0 hoặc lượt đó nhanh hơn, hãy lưu lượt đó làm thành tích tốt nhất mới
  • in ra thành tích sau mỗi lượt dưới dạng Best: 250 ms
  • nhấn nút quá sớm thì không thay đổi gì

Nhấn Chạy, thử vượt thành tích tốt nhất của bạn, rồi nhấn Kiểm tra.

Tự làm thử

const int ledPin = 12;
const int buttonPin = 2;

// Ba trạng thái của một lượt
enum State { READY, WAITING, LIT };
State state = READY;

int lastButton = HIGH;       // giá trị đọc từ nút ở lần trước
unsigned long waitStart = 0; // thời điểm bắt đầu chờ
unsigned long waitTime = 0;  // thời gian chờ của lượt này
unsigned long litAt = 0;     // thời điểm LED sáng

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Press the button to start");
}

void loop() {
  int button = digitalRead(buttonPin);
  bool pressed = (button == LOW && lastButton == HIGH);  // vừa nhấn nút
  lastButton = button;
  unsigned long now = millis();

  switch (state) {
    case READY:
      if (pressed) {
        randomSeed(micros());  // thời điểm nhấn nút không bao giờ trùng nhau giữa hai lần
        waitTime = random(1000, 3001);
        waitStart = now;
        state = WAITING;
      }
      break;
    case WAITING:
      if (pressed) {
        // Nhấn nút trước khi đèn sáng: bắt đầu quá sớm.
        Serial.println("Too soon!");
        state = READY;
      } else if (now - waitStart >= waitTime) {
        digitalWrite(ledPin, HIGH);
        litAt = now;
        state = LIT;
      }
      break;
    case LIT:
      if (pressed) {
        digitalWrite(ledPin, LOW);
        unsigned long reaction = now - litAt;
        Serial.print("Reaction: ");
        Serial.print(reaction);
        Serial.println(" ms");
        state = READY;
      }
      break;
  }
}
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