# Circuit Playground Simple Simon

## Overview

https://youtu.be/xC6pPdWDGHU

This is a Circuit Playground rendition of the [classic Simon game](https://en.wikipedia.org/wiki/Simon_(game)) from the late 70s and early 80s. The idea is to repeat an ever growing sequence of lights (each with a tone). Here we use the NeoPixels to represent the colors, the capacitive touch pads provide our buttons, and the speaker to play the distinctive tones. The Circuit Playground is even round like the classic game!

# Special Thanks

The technical information provided [on this page](http://www.waitingforfriday.com/?p=586) was very useful for creating the game. Thanks [waitingforfriday](http://www.waitingforfriday.com/) for the reverse engineering!

Another version of this game is available in [this guide](../../../circuit-playground-music/simon-says-game) by Mike Barela.

Also, forum user bbunderson posted another version of Simon you can play on Circuit Playground. [Check it out here](https://forums.adafruit.com/viewtopic.php?f=58&t=99995).

# Required Parts

This project uses the hardware already included on the Circuit Playground so no additional electronics or soldering are required. If you want to play the game without being attached to your computer, you will also need some batteries and a holder for the batteries.

- Circuit Playground

  - [Classic](https://www.adafruit.com/products/3000)
  - [Express](https://www.adafruit.com/products/3333)

- [3 x AAA Battery Holder](https://www.adafruit.com/products/727)
- 3 x AAA Batteries (NiMH work great!)

![circuit_playground_items.jpg](https://cdn-learn.adafruit.com/assets/assets/000/038/547/medium640/circuit_playground_items.jpg?1484883873)

# Before Starting

If you are new to the Circuit Playground, you may want to first read these overview guides.

## Circuit Playground Classic

- [Overview](../../../introducing-circuit-playground)
- [Lesson #0](../../../circuit-playground-lesson-number-0)

## Circuit Playground Express

- [Overview](../../../adafruit-circuit-playground-express/)

# Circuit Playground Simple Simon

## Playing the Game

Here's the code for the Simple Simon game. Download the zip file, extract it, and load the sketch to your Circuit Playground using the Arduino IDE.

[SimpleSimon.zip](https://cdn-learn.adafruit.com/assets/assets/000/038/546/original/SimpleSimon.zip?1484882455)
# Starting a New Game

You can press the **RESET** button at anytime to start a new game. When the game starts, you must first select a game difficulty level using the **SKILL LEVEL** button. Then press the **GAME START** button to start playing.

- **SKILL LEVEL** : Use to select game difficulty
- **GAME START** : Use to start a game at selected skill level

![circuit_playground_simon_buttons1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/038/540/medium640/circuit_playground_simon_buttons1.jpg?1484872906)

The **SKILL LEVEL** sets the total length (N) of the game sequence.

- 1 -\> N=8
- 2 -\> N=14
- 3 -\> N=20
- 4 -\> N=31

![circuit_playground_simon_buttons3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/038/543/medium640/circuit_playground_simon_buttons3.jpg?1484873009)

The game is played by repeating the sequence of lights shown using the associated touch pads. There are four different sections of lights, each with its own color and tone.

Use the touch pads shown for each color. You can press one or both, it doesn't matter.

![circuit_playground_simon_buttons2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/038/544/medium640/circuit_playground_simon_buttons2.jpg?1484873380)

The sequence starts with only one light. It then grows by one light each time you successfully complete the sequence. Thus the game starts easy, and gets more difficult as it progresses. To make it even more difficult, the sequence playback speeds up when the sequence becomes longer.

# Winning

To game is won by completing the entire sequence for the chosen skill level without making any mistakes. A super special sound and light show called a 'razz' is displayed for the victor.

# Losing

There are two was to lose the game:

1. Pick an incorrect light in the sequence.
2. Take too long (\>3 secs) to pick the next light.

If either of the above happens, the game ends. The light that was suppose to be next is shown.

# Playing Again

Simply press **RESET** to start a new game.

# Example Game Play

The video below demonstrates selecting a skill level, starting a new game, general game play, and successfully completing the sequence.

https://youtu.be/xC6pPdWDGHU

# Circuit Playground Simple Simon

## Code Walk Through

Let's go through the code chunk by chunk to see how it works.

### chooseSkillLevel()
```auto
void chooseSkillLevel() {
  while (!CircuitPlayground.rightButton()) {
    if (CircuitPlayground.leftButton()) {
      skillLevel = skillLevel + 1;
      if (skillLevel > 4) skillLevel = 1;
      
      CircuitPlayground.clearPixels();
      for (int p=0; p<skillLevel; p++) {
        CircuitPlayground.setPixelColor(p, 0xFFFFFF);
      }
      
      delay(DEBOUNCE); 
    }
  }
}
```

The outer `while()` loop looks for the right button press, which starts the new game. Inside the loop is an `if` statement that looks for the left button press and increments the skill level for each press. The value is checked and reset back to 1 if it exceeds the max level, which is 4. The current level is shown using the first 4 NeoPixels.

### newGame()
```auto
void newGame() {
  // Set game sequence length based on skill level
  switch (skillLevel) {
    case 1:
      sequenceLength = 8;
      break;
    case 2:
      sequenceLength = 14;
      break;
    case 3:
      sequenceLength = 20;
      break;
    case 4:
      sequenceLength = 31;
      break;
  }

  // Populate the game sequence
  for (int i=0; i<sequenceLength; i++) {
    simonSequence[i] = random(4);
  }

  // We start with the first step in the sequence
  currentStep = 1;
}
```

The entire game sequence is created before the game is started. The game sequence length is set based on the skill level in the `switch` block. The game sequence is then filled with random numbers between 0-3 to represent one of the four game pads. The currentStep is set to the starting position of 1.

### indicateButton()
```auto
void indicateButton(uint8_t b, uint16_t duration) {
  CircuitPlayground.clearPixels();
  for (int p=0; p<3; p++) {
    CircuitPlayground.setPixelColor(simonButton[b].pixel[p], simonButton[b].color);
  }
  CircuitPlayground.playTone(simonButton[b].freq, duration);
  CircuitPlayground.clearPixels();
}
```

This function displays the NeoPixels associated with the "button" passed in by `b`, plays the tone associated with this "button" for the length of time passed in by `duration`. After the tone is played, the lights are turned off.

### showSequence()
```auto
void showSequence() {
  // Set tone playback duration based on current sequence length
  uint16_t toneDuration;
  if (currentStep<=5) {
    toneDuration = 420;
  } else if (currentStep<=13) {
    toneDuration = 320;
  } else {
    toneDuration = 220;
  }

  // Play back sequence up to current step
  for (int i=0; i<currentStep; i++) {
    delay(50);
    indicateButton(simonSequence[i], toneDuration);
  }
}
```

The game sequence is played back up to the current game play location. The duration of the tone is set in the `if` statement based on the current location. This sets the play back speed of the sequence. Then, the sequence is played back up to its current location.

### getButtonPress()
```auto
uint8_t getButtonPress() {
  for (int b=0; b<4; b++) {
    for (int p=0; p<2; p++) {
      if (CircuitPlayground.readCap(simonButton[b].capPad[p]) > CAP_THRESHOLD) {
        indicateButton(b, DEBOUNCE);
        return b;
      }
    }
  }
  return NO_BUTTON;
}
```

The 2 touch pads associated with each "button" are scanned to see if either are currently being touched. If so, it is indicated and its index is returned, otherwise `NO_BUTTON` is returned.

### gameLost()
```auto
void gameLost(int b) {
  // Show button that should have been pressed
  for (int p=0; p<3; p++) {
    CircuitPlayground.setPixelColor(simonButton[b].pixel[p], simonButton[b].color);
  }

  // Play sad sound :(
  CircuitPlayground.playTone(FAILURE_TONE, 1500);
 
  // And just sit here until reset
  while (true) {}
}
```

The "button" that is passed in via `b` is shown, the sad tone is played, and the game ends at an infinite loop.

### gameWon()
```auto
void gameWon() {
  // Play 'razz' special victory signal 
  for (int i=0; i<3; i++) {
    indicateButton(3, 100);  // RED
    indicateButton(1, 100);  // YELLOW
    indicateButton(2, 100);  // BLUE
    indicateButton(0, 100);  // GREEN
  }
  indicateButton(3, 100);  // RED
  indicateButton(1, 100);  // YELLOW

  // Change tones to failure tone
  for (int b=0; b<4; b++) simonButton[b].freq = FAILURE_TONE;

  // Continue for another 0.8 seconds
  for (int i=0; i<2; i++) {
    indicateButton(2, 100);  // BLUE
    indicateButton(0, 100);  // GREEN
    indicateButton(3, 100);  // RED
    indicateButton(1, 100);  // YELLOW
  }

  // Change tones to silence
  for (int b=0; b<4; b++) simonButton[b].freq = 0;

  // Loop lights forever
  while (true) {
    indicateButton(2, 100);  // BLUE
    indicateButton(0, 100);  // GREEN
    indicateButton(3, 100);  // RED
    indicateButton(1, 100);  // YELLOW
  }
}
```

Plays the super special victory 'razz' and ends with an infinite loop of blinking lights.

### setup()
```auto
void setup() {
  // Initialize the Circuit Playground
  CircuitPlayground.begin();

  // Set play level
  skillLevel = 1;
  CircuitPlayground.clearPixels();
  CircuitPlayground.setPixelColor(0, 0xFFFFFF);
  chooseSkillLevel();

  // Sowing the seeds of random
  randomSeed(millis());
  
  // Create game
  newGame();
}
```

Per the rules of Arduino, this is the first thing called. It initializes the Circuit Playground, gets the skill level, seeds the pseudo random number generator, and sets up a new game.

### loop()
```auto
void loop() {
  // Show sequence up to current step
  showSequence();

  // Read player button presses
  for (int s=0; s<currentStep; s++) {
    startGuessTime = millis();
    guess = NO_BUTTON;
    while ((millis() - startGuessTime < GUESS_TIMEOUT) && (guess==NO_BUTTON)) {
      guess = getButtonPress();           
    }
    if (guess != simonSequence[s]) {
      gameLost(simonSequence[s]);
    }
  }
  currentStep++;
  if (currentStep > sequenceLength) {
    delay(SEQUENCE_DELAY);
    gameWon();
  }
  delay(SEQUENCE_DELAY);
}
```

Per the rules of Arduino, this is called over and over and over and over. First, the current sequence is played back. Then the player interaction is dealt with. For each step in the sequence, a button is read. If it's the wrong button, or the player took too long to press the button, the value is set to `NO_BUTTON`. The button value is then compared to the current sequence value. If it's correct, the game continues. If it's wrong, the game is over. Once the step values exceeds the game sequence length, the game is won.

# Circuit Playground Simple Simon

## The Structure of struct

Warning: 

In the previous section, I didn't mention any of the lines of code at the top of the sketch. Most of these are just normal global variables and constants that are fairly common. However, this section of code may be new to you.

```auto
struct button {
  uint8_t capPad[2];
  uint8_t pixel[3];
  uint32_t color;
  uint16_t freq;
} simonButton[] = {
  { {3,2},    {0,1,2},  0x00FF00,   415 },  // GREEN
  { {0,1},    {2,3,4},  0xFFFF00,   252 },  // YELLOW
  { {12, 6},  {5,6,7},  0x0000FF,   209 },  // BLUE
  { {9, 10},  {7,8,9},  0xFF0000,   310 },  // RED 
};
```

This is defining, and initializing, an array (`simonButton[]`) of something called a **struct**. A struct comes from the C programming language, but is also supported in C++ and thus Arduino. What it basically does is let us create a new variable that is a collection of information associated with something, like a Simon "button". This let's us pass around and access this information from a single reference. We don't need to pass around each individual piece of information separately.

Talking about structs can get pretty complex, and they're a precursor to the more complex `class` of C++ and the world of OOP. But they are very useful, and we are using it in a fairly simple way in our Simple Simon code. To better understand why a struct is useful, let's look at a more simple example - a 2D point.

# 2D Point Example

A 2D point is represented by an `x` and `y` value. We could create these as separate variables:

```auto
float x;
float y;
```

and then use them as normal:

```auto
x = 45.3;
y = -108.6;
```

But what if I wanted to pass this 2D point to a function? Or what if I wanted to create another 2D point? Things start getting a little messy. This is where a struct would help out. Instead of two separate variable, we create a single struct to represent the 2D point, and put the variables in there.

```auto
struct point {
  float x;
  float y;
}
```

And then to create a new point variable:

```auto
struct point someLocation;
```

And assign it values:

```auto
someLocation.x = 45.3;
someLocation.y = -108.6;
```

Now all one needs to do is pass the variable `someLocation` around. The values come along for the ride. And they don't get confused with some other values. If we need another 2D point, we just create another variable, or better yet, an array of them.

The one fancy thing being done in the Simple Simon code is to create and initialize the values of the struct in one step. For our 2D point example, this would look like:

```auto
struct point {
  float x;
  float y;
} someLocation = {
  45.3, -108.6
}
```

It's just a shortcut way of creating the variable and assigning it some initial values.

# The Simple Simon "button"

Getting back to our Simple Simon game, think about what each of the four "buttons" has. Most obvious is a **color**. But they also make a sound when they are pressed, and each has its own **tone**. Since we are trying to implement these on our Circuit Playground, we will use a set of **NeoPixels** to show off the color. Also, we plan to use capacitive touch for the buttons, with each button having a couple of **pads**. So, we have the following items for each "button":

- 2 x capacitive touch pads
- 3 x NeoPixels
- a color
- a tone

Hey, that should look familiar. Look again at the struct definition:

```auto
struct button {
  uint8_t capPad[2];
  uint8_t pixel[3];
  uint32_t color;
  uint16_t freq;
}
```

Just like the list. For each "button" we have the indices for 2 capacitive touch pads, the indices for 3 NeoPixels, the color to use for the NeoPixels, and the frequency of the tone for the button.

We have more than one "button", so we create an array of them and initialize their values:

```auto
  simonButton[] = {
  { {3,2},    {0,1,2},  0x00FF00,   415 },  // GREEN
  { {0,1},    {2,3,4},  0xFFFF00,   252 },  // YELLOW
  { {12, 6},  {5,6,7},  0x0000FF,   209 },  // BLUE
  { {9, 10},  {7,8,9},  0xFF0000,   310 },  // RED 
};
```

Each line is an entry in the array and represents one button. Each item in each line corresponds to the value of the struct and is used to define the specific buttons. For example, the first line defines the GREEN button as having the capacitive touch pads #3 and #2, the NeoPixels #0, #1, and #2, the color green (in hex), and the frequency 415Hz.

Then, if we need the frequency for the tone of the GREEN button, the syntax is:

```auto
simonButton[0].freq
```

The color for the BLUE button?

```auto
simonButton[2].color
```

The index of the 2nd NeoPixel for the RED button?

```auto
simonButton[3].pixel[1]
```

etc. etc.

Hopefully that makes some sense and you see how it is useful. If not, meh, just have fun playing the game....for now.

# So Why Didn't You Just Create a simonButton Class?

Just trying to keep it simple. But this is totally doable, since Arduino uses C++ under the hood.

# Circuit Playground Simple Simon

## CircuitPython Version

Here is a [CircuitPython](../../../../adafruit-circuit-playground-express/adafruit2-circuitpython) version of the Simple Simon code.

Info: 

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/CPX_Simple_Simon/code.py


## Featured Products

### Circuit Playground Express

[Circuit Playground Express](https://www.adafruit.com/product/3333)
 **Circuit Playground Express** is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and made it even better! Not only did we pack even more sensors in, we also made it even easier to...

In Stock
[Buy Now](https://www.adafruit.com/product/3333)
[Related Guides to the Product](https://learn.adafruit.com/products/3333/guides)
### Circuit Playground Classic

[Circuit Playground Classic](https://www.adafruit.com/product/3000)
Would you like to learn electronics, with an all-in-one board that has sensors and LEDs built in? **Circuit Playground** is here - and it's the best way to practice programming on real hardware with no soldering or sewing required!

This is the **Classic**...

In Stock
[Buy Now](https://www.adafruit.com/product/3000)
[Related Guides to the Product](https://learn.adafruit.com/products/3000/guides)
### 3 x AAA Battery Holder with On/Off Switch and 2-Pin JST

[3 x AAA Battery Holder with On/Off Switch and 2-Pin JST](https://www.adafruit.com/product/727)
This battery holder connects 3 AAA batteries together in series for powering all kinds of projects. We spec'd these out because the box is slim, and 3 AAA's add up to about 3.3-4.5V, a very similar range to Lithium Ion/polymer (Li-Ion) batteries and have an on-off switch. That makes...

In Stock
[Buy Now](https://www.adafruit.com/product/727)
[Related Guides to the Product](https://learn.adafruit.com/products/727/guides)

## Related Guides

- [Introducing Circuit Playground](https://learn.adafruit.com/introducing-circuit-playground.md)
- [Adafruit Circuit Playground Express](https://learn.adafruit.com/adafruit-circuit-playground-express.md)
- [BOSEbuild Reactive Sound ](https://learn.adafruit.com/bosebuild-reactive-sound.md)
- [Circuit Playground Slouch Detector](https://learn.adafruit.com/circuit-playground-slouch-detector.md)
- [Ever-Burning Flame Painting](https://learn.adafruit.com/ever-burning-flame-painting.md)
- [CRICKIT Exhibit Demo Board](https://learn.adafruit.com/crickit-exhibit-demo-board.md)
- [Makey Paper Craft ](https://learn.adafruit.com/makey-paper-craft.md)
- [Circuit Playground Bike Light](https://learn.adafruit.com/circuit-playground-bike-light.md)
- [Archimedes' Boat](https://learn.adafruit.com/archimedes-boat.md)
- [Circuit Playground Express Rocket Lamp](https://learn.adafruit.com/cpx-rocket-lamp.md)
- [Giant Mechanical Keyboard](https://learn.adafruit.com/giant-control-alt-delete.md)
- [Mini Golf Course with Circuit Playground and Crickit](https://learn.adafruit.com/mini-golf-course-with-makecode-circuit-playground-crickit.md)
- [New Year Countdown Clock with Circuit Playground Express](https://learn.adafruit.com/new-year-countdown-clock-with-circuit-playground-express.md)
- [Makecode para la Circuit Playground Express](https://learn.adafruit.com/makecode-es.md)
- [FLORAbrella](https://learn.adafruit.com/florabrella.md)
- [Circuit Playground + CircuitPython Quickstart Guide](https://learn.adafruit.com/circuit-playground-express-circuitpython-5-minute-guide.md)
