Traffic Light Remix


##Motivation

At the end of last week, I spent some time with my CS30 students getting them used to the idea of a ‘state variable’, in which we keep track of the state of a program with a simple variable, and transition to appropriate states when certain conditions are met. To introduce this to them, I like to show them the following animation, which is generated by an example from Daniel Shiffman’s Learning Processing book:

State Variables GIF

I then have them work in partners (pair programming style) to try to come up with a way to replicate the functionality they see. Generally speaking, most of the pairs come up with a means of doing this, though the solutions vary wildly in elegance. After they have all come up with something, I show them a solution using a state variable, similar to the code that Daniel Shiffman uses in his example.

Then over the weekend, I read Alfred Thompson’s Traffic Light Project in Several Acts post, which is a riff on Dawn DuPriest’s Event-Based Programming post. This seemed like a lovely idea, so I used it today with my students to reinforce the idea of state variables.

##Starter Code

A few minutes before the first class started, I quickly created some starter code for the students, which looked like this:

//GOAL: make a 'traffic light' simulator. For now, just have the light 

// changing according to time. You may want to investigate the millis()

// function at processing.org/reference.


void setup() {
  size(600, 600);
}

void draw() {
  background(255);
  drawOutlineOfLights();
}

void drawOutlineOfLights() {
  //box

  rectMode(CENTER);
  fill(0);
  rect(width/2, height/2, 75, 200, 10);
  
  //lights

  fill(255);
  ellipse(width/2, height/2 - 65, 50, 50); //top

  ellipse(width/2, height/2, 50, 50); //middle

  ellipse(width/2, height/2 + 65, 50, 50); //bottom

}

This code generates the following image:

Image of Starter Code for Traffic Light Project

##Timer in Processing

Since we hadn’t worked with the millis() function in Processing yet, if student’s struggled, it was on figuring out how to keep track of time. After watching them flounder for awhile, I helped out a bit by working through an example of changing the background color of a sketch to a random color every 2 seconds. This seemed to provide enough scaffolding that most students could then complete the task.

Once we get to OOP later in the semester, we’ll be creating a nice Timer class, but for now, the timer logic is just included in the rest of the code.

##Finished Project

After the students had finished creating their solutions, I had them discuss their method of solution with a neighbour. Following that, I demonstrated a reasonable solution, with a focus on creating simple functions to make easy to understand code.

//GOAL: make a 'traffic light' simulator. For now, just have the light 

// changing according to time. You may want to investigate the millis()

// function at processing.org/reference.


int state;
int timeElapsed;

void setup() {
  size(600, 600);
  state = 0;  // 0 - green, 1 - orange, 2 - red

  timeElapsed = 0;
}

void draw() {
  background(255);
  drawOutlineOfLights();
  determineState();
  turnOnCorrectLight();
}

void determineState() {
  int timeToWait = 0;
  if (state == 0) {
    timeToWait = 5000;
  }
  else if (state == 1) {
    timeToWait = 1000;
  }
  else if (state == 2) {
    timeToWait = 5000;
  }
  
  if ( millis() >= timeElapsed + timeToWait) {
    state++;
    state = state % 3;
    timeElapsed = millis();
  }
}

void turnOnCorrectLight() {
  if (state == 0) {
    drawGreenLight();
  }
  else if (state == 1) {
    drawOrangeLight();
  }
  else if (state == 2) {
    drawRedLight();
  }
}

void drawOutlineOfLights() {
  //box

  rectMode(CENTER);
  fill(0);
  rect(width/2, height/2, 75, 200, 10);
  
  //lights

  fill(255);
  ellipse(width/2, height/2 - 65, 50, 50); //top

  ellipse(width/2, height/2, 50, 50); //middle

  ellipse(width/2, height/2 + 65, 50, 50); //bottom

}

void drawRedLight() {
  fill(255, 0, 0);
  ellipse(width/2, height/2 - 65, 50, 50); //top

}

void drawOrangeLight() {
  fill(245, 147, 17);
  ellipse(width/2, height/2, 50, 50); //middle

}

void drawGreenLight() {
  fill(0, 255, 0);
  ellipse(width/2, height/2 + 65, 50, 50); //bottom

}

The students seemed to enjoy the exercise. I’ll be doing it again next semester.