Simon Says (Alexandra E. Morton)

Our Project was Number Memory game mainly inspired by the fact the we recently worked with 7-segment displays. We wanted to display a randomly generated number for a few seconds, then store it and display zeros. The player would then be able to input the number they remember and check it against it the stored number – after which they would either be told “No” and have a strike marked against them and have to try again, or get told “Yes” and gain a point and be given a new number to remember. If four strikes are gained, they lose and a sad-face would be displayed for several seconds before the game refreshed and started over; meanwhile, if four points are gained, they win and a smiley-face would be displayed for several seconds before the game refreshed and started over.

During play, buttons would be used to move between the displays [buttonB], change the number on each [buttonA], and check the number against the stored number [buttonB].

For this game we used:

  • 3 – 7-segment Displays (Outputs)
  • 3 – Shift Registers
  • 2 – Buttons (Inputs)
  • 23 – Resistors [7 for each display; 1 for each button]
  • 2 many – Wires

The three Shift Registers, one for each display, were inter-connected, allowing us to take up only three Digital pin-ports on the Arduino (the data-, clock-, and latch-pins). Meanwhile, the buttons took up only two Digital pin-ports. The buttons and Shift Registers were both connected to the same ground and 5V power line [the display connected indirectly through their respective Registers]. All-in-all, there were much less pins connected directly to the Arduino than we were originally thinking there would be. Sadly, we did not have time to tame the many wire and fit the game in an enclosure.

 


 

Throughout this, we ran into several difficulties. Including:

Buttons: Originally we wanted three buttons – one to move currentDisplay, one to change the number set in the currentDisplay, and one to compare the player’s guess to the stored number. Oddly, despite the code working and nothing being wrong with the physical button and it’s wiring, we couldn’t get a third button to work in any other of the ports. We got around the need for a third button by making buttonB multi-purpose.

In loop():

  debouncerA.update();

  debouncerB.update();

  int add = debouncerA.rose();

  int next = debouncerB.rose();

  int check = debouncerB.fell();

While add and next came back true when their button was pressed [.rose()], check came back true when buttonB was released [.fell()]. This, along with a time-lapse [if (check && currentTime – pressTime > 2000) {pressTime being set to millis() when buttonB  is pressed (part of the  if (next) { statement], allows checkMemory(oneDisplay, twoDisplay, threeDisplay) to be run if buttonB is held down for more than 2 seconds.

 


 

If it is, then this helper function decides if a guess is correct or not:

bool checkMemory(int d1, int d2, int d3) {

  int myGuess[] = {d1, d2, d3};

  if (myGuess[0] == guessMe[0] && myGuess[1] == guessMe[1] && myGuess[2] == guessMe[2]) {

    return 1;

  } else {

    return 0;

  }

}

myGuess[] being the number currently on the display and guessMe[] being the stored number from the start of the round.


Another error seems to be that WIN and LOSE states won’t go back to the START (where a new number is generated) state, even though the RIGHT (state after a correct guess) does work and has near identical coding.

Doesn’t work:

if (gameState == WIN || gameState == LOSE) {

    if (currentTime – endTime > 3000) {

        int r1 = random( 0, 9);

        int r2 = random( 0, 9);

        int r3 = random( 0, 9);

        setGuessMe(r1, r2, r3);

        strike = 0;

        score = 0;

        startTime = millis();

        gameState == START;

    }

  }

Works:

if (gameState == RIGHT) {

    if (currentTime – startTime > 2000) {

      if (score > 3) {

        endTime = millis();

        gameState = WIN;

      } else {

        int r1 = random( 0, 9);

        int r2 = random( 0, 9);

        int r3 = random( 0, 9);

        setGuessMe(r1, r2, r3);

        startTime = millis();

        gameState = START;

      }

    }

  }


Overall, though, this assignment was fun (if highly frustrating) and helped me understand Shift Registers and state machines better.


Extra: Here’s how I got the messages and face:

byte text[] =

{ ~B01101110,//Y

  ~B01111001,//E

  ~B01101101,//S

  ~B01010100,//n

  ~B00111111,//o

  ~B01000000,//dash

  ~B00100011,//eye

  ~B00011100,//u

};

With this helper function:

void displayByt(int a, int b, int c) {

  shiftOut(datapin, clockpin, MSBFIRST, a);

  shiftOut(datapin, clockpin, MSBFIRST, b);

  shiftOut(datapin, clockpin, MSBFIRST, c);

  digitalWrite(latchpin, HIGH);

  digitalWrite(latchpin, LOW);

}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s