#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int ledPins[] = {2, 3, 4, 5}; // LEDピン
const int buttonPins[] = {6, 7, 8, 9}; // ボタンピン
const int buzzerPin = 10; // ブザーピン
int score = 0; // スコア
int randomLed = -1; // LEDのインデックス
int remainingTime = 61; // ゲーム制限時間(秒)
LiquidCrystal_I2C lcd(0x27, 20, 4); // I2Cアドレスが0x27のLCD
unsigned long previousMillis = 0; // 時間の計測用変数
const long interval = 1000; // 1秒ごとに残り時間を減らす
unsigned long ledInterval = 0; // LEDの点灯間隔
unsigned long ledChangeTime = 0; // LED点灯変更の時間
unsigned long ledLastOffTime = 0; // LEDが最後に消灯した時間
bool scoreIncreased = false; // スコアが増加したかどうかのフラグ
unsigned long ledSwitchDelay = 200; // LED消灯後に次のLEDに切り替えるまでの遅延時間(200ms)
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(buzzerPin, OUTPUT); // ブザーピンの設定
lcd.init(); // LCDの初期化
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Game Start!");
delay(2000);
lcd.clear();
// シリアルモニターの初期化(デバッグ用)
Serial.begin(9600);
}
void loop() {
unsigned long currentMillis = millis();
// 1秒ごとに残り時間を減らす
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (remainingTime > 0) {
remainingTime--;
}
}
// ゲームが進行中の処理
if (remainingTime > 0) {
lcd.setCursor(0, 0);
lcd.print("Score: ");
lcd.print(score);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("Time: ");
lcd.print(remainingTime);
lcd.print("s ");
// LED点灯の間隔を設定(0.5秒~1.5秒の範囲)
if (currentMillis - ledChangeTime >= ledInterval) {
// 点灯しているLEDを消灯(遅延を入れる)
if (randomLed >= 0) {
digitalWrite(ledPins[randomLed], LOW);
ledLastOffTime = currentMillis; // LEDを消灯した時間を記録
}
// 新しいLEDをランダムで選び、点灯させる
randomLed = random(0, 4);
digitalWrite(ledPins[randomLed], HIGH); // 新しいLEDを点灯
// LED点灯の間隔をランダムで設定(500ms~1500ms)
ledInterval = random(500, 1500);
ledChangeTime = currentMillis; // 次のLED変更時間を設定
scoreIncreased = false; // 新しいLEDが点灯したのでスコア加算フラグをリセット
}
// 点灯しているLEDの対応するボタンが押されるのを待つ
int pressedButton = waitForButtonPress();
if (pressedButton == randomLed && !scoreIncreased) {
score++; // スコアを1点加算
scoreIncreased = true; // スコア加算フラグをセット
tone(buzzerPin, 1000, 200); // 正しいボタンが押されたときに音を鳴らす
digitalWrite(ledPins[randomLed], LOW); // ボタンが押されたらLEDを消灯
delay(200); // ブザー音とLED消灯のため少し待機
}
// 200msの遅延後に次のLEDに切り替える
if (currentMillis - ledLastOffTime >= ledSwitchDelay) {
// LED消灯後の遅延が経過したら次のLEDに切り替える
if (randomLed >= 0) {
digitalWrite(ledPins[randomLed], LOW);
}
}
} else {
// ゲーム終了
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Game Over!");
lcd.setCursor(0, 1);
lcd.print("Score: ");
lcd.print(score);
for (int i = 0; i < 5; i++) {
tone(buzzerPin, 1000, 200); // 1000Hzの音を200ms間鳴らす
delay(200);
tone(buzzerPin, 1500, 200); // 1500Hzの音を200ms間鳴らす
delay(200);
}
noTone(buzzerPin); // ブザー音を止める
while (true); // ゲーム終了
}
}
int waitForButtonPress() {
for (int j = 0; j < 4; j++) {
if (digitalRead(buttonPins[j]) == LOW) {
delay(200); // デバウンス
return j; // 押されたボタンのインデックスを返す
}
}
return -1; // ボタンが押されていない場合
}