Making Things Interactive

March 27, 2008

State machine

Filed under: 8: State Machine, Lea — tovelet @ 1:42 pm

I am not very good at this game, actually.


/*
A blinky light game.  Once a player has decided to "participate,"
the LED's blink in turn.  If a player hits the button that corresponds
to the currently lit LED, they gain a point, and the lights cycle slightly
faster.  They can exit the game at any time, and the score and speed
reset for the next player.
*/

int ledOne = 4;
int ledTwo = 7;
int buttonOne = 2;
int buttonTwo = 8;
int participate = 9;
int delayTime = 200;
int answer = 0;      //"right" or "wrong" for any given round
int score = 0;       //score tally, reset at the beginning of the game
int playPrint = 1;   //should it print "Will you play?"

const int sAttract = 0;
const int sQuestion = 1;
const int sIncorrect = 2;
const int sCorrect = 3;

int state = 0;

void setup ()
  {
  pinMode(ledOne, OUTPUT);
  pinMode(ledTwo, OUTPUT);
  pinMode(buttonOne, INPUT);
  pinMode(buttonTwo, INPUT);
  pinMode(participate, INPUT);
  Serial.begin(9600);
  }

void loop ()
  {
switch (state)
{
case sAttract:        //state is attract
  digitalWrite (ledOne, LOW);  //reset LEDs to off
  digitalWrite (ledTwo, LOW);
  if (playPrint == 1)
  {Serial.println("Will you play?");}
  score = 0;          //reset score
  delayTime = 200;    //reset delayTime
  if (digitalRead(participate)==HIGH)
    {state = sQuestion;}
  playPrint = 0;      //only print it once
  break;

case sQuestion:         //state is question:
  Serial.println("Push the lit button.");
  Serial.println();
  if (digitalRead(participate)==LOW)  //check if participate is off
    {
    state = sAttract;
    playPrint = 1;
    }
  answer = cycleLed();       //run the cycling lights, return correct or incorrect
  score = score + answer;    //tally score
  if (answer == 0)
    {state = sIncorrect;}
  if (answer == 1)
    {state = sCorrect;}
  break;

case sIncorrect:      //state is incorrect:
  Serial.println("Wrong.");
  Serial.println("Your score is:");
  Serial.println(score);      //print score
  Serial.println();
  delay (500);
  if (digitalRead(participate)==LOW) //check if participate is off
    {state = sAttract;
     playPrint = 1;}
  else
    {state = sQuestion;}    //return to question state
  break;

case sCorrect:      //state is correct:
  Serial.println("Correct!");
  Serial.println("Your score is:");
  Serial.println(score);
  Serial.println();
  delay (500);
  delayTime = (delayTime - (delayTime/(100-score))); //cycle lights faster next time
  if (delayTime <= 50) {delayTime = 50;}    //do not make it too hard
  if (digitalRead(participate)==LOW)
    {state = sAttract;
     playPrint = 1;}
  else
    {state = sQuestion;}
  break;

default:
  Serial.println ("error"); //this shouldn't happen
  state = sAttract;
  playPrint = 1;
  break;
}
}

int cycleLed ()
 {
    while (true)
    {
    for (int i=0; i<=delayTime; i++)
      {
      digitalWrite(ledOne, HIGH);    //ledOne is on
      digitalWrite(ledTwo, LOW);
      if (digitalRead(participate)==LOW)    //make sure participate is high
        {state = sAttract;
        playPrint = 1;
        return (0);}
      if (digitalRead(buttonOne)==HIGH)
        {return (1);}    //so if buttonOne is pressed, correct
      if (digitalRead(buttonTwo)==HIGH)
        {return (0);}    //and if button Two is pressed, incorrect
      delay(1);
      }
    for (int i=0; i<=delayTime; i++)
      {
      digitalWrite(ledOne, LOW);    //inverse of the other one
      digitalWrite(ledTwo, HIGH);
      if (digitalRead(participate)==LOW)
        {state = sAttract;
        playPrint = 1;
        return (0);}
      if (digitalRead(buttonOne)==HIGH)
        {return (0);}
      if (digitalRead(buttonTwo)==HIGH)
        {return (1);}
       delay(1);
       }
    }
}

No Comments Yet »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

You must be logged in to post a comment.

Blog at WordPress.com.