Menu
CoddyTech

Simon: Repeat the Pattern

Part of the Projects section of Coddy's Arduino journey. Lesson 15 of 24.

After the board plays, it is your turn: repeat the four colours in the same order. The sketch needs one more number, step, that counts how many colours you have repeated so far. The colour you must press next is sequence[step].

Count a press when the button is let go, as the game already does to start. By then its light and note are off, and the sketch can react cleanly:

void checkPress(int i) {
  if (i != sequence[step]) {
    Serial.println("Wrong!");
    playing = false;
    return;
  }
  step++;
  if (step == 4) {
    Serial.println("Well done!");
    playing = false;
  }
}

return leaves the function at once, so after a wrong colour nothing below it runs. Setting playing back to false ends the game, and the next press starts a new one.

Every new game must count from the start again: set step = 0 in startGame().

challenge icon

Challenge

Hard

Let the player answer:

  • an int step = 0;, set back to 0 in startGame()
  • when a button is let go and the game is playing, call checkPress(i)
  • a wrong colour prints Wrong! and ends the game
  • after four right colours, print Well done! and end the game

Start Serial in setup(). Press Run, watch, repeat the pattern, then Check.

Try it yourself

// One entry per colour: red, green, blue, yellow
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 and high C
const int buzzerPin = 8;

int lastState[4] = {HIGH, HIGH, HIGH, HIGH};  // each button's last reading

int sequence[4];       // the colours the board plays
bool playing = false;  // false until a press starts the game

// Light colour i and play its note.
void lightOn(int i) {
  digitalWrite(ledPins[i], HIGH);
  tone(buzzerPin, notes[i]);
}

// Turn colour i off and stop the sound.
void lightOff(int i) {
  digitalWrite(ledPins[i], LOW);
  noTone(buzzerPin);
}

// Play the sequence: each colour 400 ms, then 200 ms of quiet.
void playSequence() {
  delay(500);
  for (int i = 0; i < 4; i++) {
    lightOn(sequence[i]);
    delay(400);
    lightOff(sequence[i]);
    delay(200);
  }
}

// Pick a new random sequence and play it.
void startGame() {
  randomSeed(micros());
  for (int i = 0; i < 4; i++) {
    sequence[i] = random(4);
  }
  playing = true;
  playSequence();
}

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) {  // pressed
      lightOn(i);
    }
    if (state == HIGH && lastState[i] == LOW) {  // let go
      lightOff(i);
      if (playing == false) {
        startGame();
      }
    }
    lastState[i] = state;
  }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Projects

Practice on your own: Arduino playground