Code Tutorial

(1) Library inclusion
#include colorduino.h
This line of code is used to import the Colorduino library. Once the library files are downloaded as a .zip file, include them by clicking Sketch => Include Library => Add .ZIP Library...


(2) Pins
const int BUTTON = 5;
const int X_PIN = 3; 
These statements declare variable names for the Analog pins used for the button on the joystick and the x-axis.


(3) Variables
int select = 0;
int player = 1;
 
int color[] = {
  0,     // red
  0,     // green
  255    // blue
};
 
int board[][8] = {
  /* array to store colors on the board */
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0},
  {0, 0, 0, 0, 0, 0, 0, 0}
};

int bottom[8] = {
  /* index at last open color */
  7, 7, 7, 7, 7, 7, 7, 7
};

bool win = false;
This block of quote defines variables for use later. select is an integer which changes with the movement of the joystick. player switches between 1 and 2 as the players take turns. color changes between blue and green (it starts as blue). The board array starts off as zeros but gets filled in with 1 or 2 to represent the colors on the board. It is used to check for the winner. bottom stores the index of the last available spot in each column. They all start as 7 because the last row on the board, with index 7, is the last available space. The last variable win is changed to true when a player has won.


(4) setup()
void setup() {
  pinMode(BUTTON, INPUT);
  Colorduino.Init();
  flipSet(0, select);
}
This code sets the button pin to input, initializes the Colorduino library, and sets the light at position (0, 0) to the blue using the custom function flipSet (see (6) ).


(5) loop()
void loop() {
  if (analogRead(X_PIN) > 750) {          // joystick moved right
    flipOff(0, select);                          // turn off current
    if (select < 7) {         // if the selection is on the screen
      select += 1;                          // move to the right one
    } else {             // if the next move would go off the screen
      select = 0;                                   // start at left
    }
    flipSet(0, select);                     // turn on new selection
  } else if (analogRead(X_PIN) < 250){      // joystick moved left
    flipOff(0, select);                          // turn off current     if (select > 0){                     // if selection on screen
      select -= 1;                           // move to the left one
    } else {                // if next selection would be off screen       select = 7;                                  // start at right
    }
    flipSet(0, select);                     // turn on new selection
  } else if (analogRead(BUTTON) < 100) {      // if joystick pressed       if (bottom[select] != 0){
        for (int i=0; i<=bottom[select]; i++) {     // fancy lights
          flipSet(i, select);                // turn on each light
          delay(100);                      // delay light movement
          if (i != bottom[select]){
            flipOff(i, select);        // turn off each except last           }
            delay(50);
          }
        board[bottom[select]][select] = player; 
        // change corresponding pixel in array to 1 or 2
       
      checkWinner(bottom[select], select);
     
      bottom[select] -= 1;                 // update last position
      delay(500);
       while (win) {
        /* repeat this infinitely after a player has won */
        while (analogRead(BUTTON) > 100) { // button not pressed
          delay(250);
          off();
          delay(500);
          if (board[bottom[select]][select] == 1) { // if player 1
            one();
          } else {                                  // if player 2
            two();
          }
          delay(400);   
        }
        reset();
        off();
       }

       playerSwap();                       // switch player color      
     } 
   
   else {
      /* If the board fills up and neither of the players has won*/
      for(int bot=0; bot<= 7; bot++){
        if (bottom[bot] <= 0) {
          full++;
        }
        if (full == 8){
          delay(500);
          reset();
        }
      }
   }
 
   delay(175);

}
This code runs the main program. If the joystick is moved right, it turns off the current selection LED and turns on the one to the right. If the joystick is moved left, it does the same but to the left. If the button is pressed, the lights will cascade down the column and settle into the last available space. The game then checks for a winner. If someone has won, it will turn off the board and blink either a 1 or  2, depending on which player won. If there is no winner, it will continue the game. This code calls various custom functions, which are defined below.


(6) flipSet()
int flipSet(int row, int col) {
  /* turn on at specified location with current color
   * There are two pages, so the page needs to be flipped to edit and then flipped back to display
   * For this game, only page 1 is used */

  Colorduino.FlipPage();                           
 // edit PAGE1, display PAGE2

  Colorduino.SetPixel(row, col, color[0], color[1], color[2]);
 // set light at (row, col) with color on PAGE1

  Colorduino.FlipPage();                           
  // display PAGE1, edit PAGE2

}
This function sets a pixel at a specified location with the color color. In the Colorduino library, there are two writable pages. Using this function prevents having to flip the page back and forth every time a light is changed.


(7) flipOff()
int flipOff(int row, int col) {
  /* turn off at specified location
   * There are two pages, so the page needs to be flipped to edit and then flipped back to display
   * For this game, only page 1 is used */

  Colorduino.FlipPage();                           
  // edit PAGE1, display PAGE2

  Colorduino.SetPixel(row, col, 0, 0, 0);           
 // turn off light at (row, col) on PAGE1

  Colorduino.FlipPage();                           
 // display PAGE1, edit PAGE2

}
This function turns off a pixel at a specified location.


(8) off()
void off(){                                       
  /* turns off every LED */
  for(int r=0; r<=7; r++){                 // cycles between rows
    for(int c=0; c<=7; c++){               // cycles between columns
       flipOff(r, c);                // turn off at row, column
     }
  }
}
This function turns off every LED on the board.


(9) on()
void on(){                           
  /* turns on every LED */
  for(int r=0; r<=7; r++){              // cycles between rows
    for(int c=0; c<=7; c++){            // cycles between columns
      flipSet(r, c);                // turn on at row, column
     }
  }
}
This function turns on every LED on the board with color color.


(10) one()
void one() {                                     
  /* display the number 1, if player 1 wins */
  Colorduino.SetPixel(0, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(1, 3, color[0], color[1], color[2]);
  Colorduino.SetPixel(1, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(2, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(3, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(4, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(5, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 3, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 5, color[0], color[1], color[2]);
  Colorduino.FlipPage();
}
This function displays the number 1 on the board in the color color.


(11) two()
void two() {                                     
  /* display the number 2, if player 2 wins */
  Colorduino.SetPixel(0, 3, color[0], color[1], color[2]);
  Colorduino.SetPixel(0, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(0, 5, color[0], color[1], color[2]);
  Colorduino.SetPixel(1, 2, color[0], color[1], color[2]);
  Colorduino.SetPixel(1, 6, color[0], color[1], color[2]);
  Colorduino.SetPixel(2, 6, color[0], color[1], color[2]);
  Colorduino.SetPixel(3, 5, color[0], color[1], color[2]);
  Colorduino.SetPixel(4, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(5, 3, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 2, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 3, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 4, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 5, color[0], color[1], color[2]);
  Colorduino.SetPixel(6, 6, color[0], color[1], color[2]);
  Colorduino.FlipPage();
}
This function displays the number 2 on the board in the color color.


(12) playerSwap()
void playerSwap() {
  /* Change player color
   * Player 1 is blue and Player 2 is red
   * Each turn switches player and resets selection to top left */

  if (color[2] == 255) {              // if blue (player 1)
      color[1] = 255;                 // turn red on
      color[2] = 0;                   // turn blue off
      player = 2;
     } else {                         // if red (player 2)
      color[1] = 0;                   // turn red off
      color[2] = 255;                 // turn blue on
      player = 1;
     }
  flipOff(0, select);                 // turn off current selection
  select = 0;                         // start new selection at beginning
  flipSet(0, select);                 // turn on current selection
}
This function swaps the player color between blue and green and changes the variable player to 1 or 2.


(13) reset()
void reset() {
  off();
  win = false;
  for(int r=0; r<=7; r++){           // cycles between rows
    for(int c=0; c<=7; c++){         // cycles between columns
      board[r][c] = 0;
      bottom[c] = 7;
    }
  }
  select = 0;
}
This function resets the game. Because it is called after a player has won, it resets win to false, clears the variable board, and resets select.


(14) checkWinner()
int checkWinner(int row, int col) {
  /* Check for the winner of the game
   *  input of row, col is the location of the last piece placed
   *  checks for four in a row vertically, horizontally, and diagonally
   */
 
  /* vertical */

  if (row <= 4) {
   if ((board[row][col] == board[row+1][col]) &&
       (board[row][col] == board[row+2][col]) &&
       (board[row][col] == board[row+3][col])) {
     /* vertical */
     win = true;
   }
  }
 
  /* horizontal */
  if (col <= 4 ){
   if ((board[row][col] == board[row][col+1]) &&
       (board[row][col] == board[row][col+2]) &&
       (board[row][col] == board[row][col+3])) {
     /* horizontal - three already to the right */
     win = true;
  }
  }
  if (col <=5 && col >= 1){
   if ((board[row][col] == board[row][col+1]) &&
       (board[row][col] == board[row][col+2]) &&
       (board[row][col] == board[row][col-1])){
     /* horizontal - two already to the right, one to the left */
     win = true;
   }
  }
  if (col <= 6 && col >= 2){
   if ((board[row][col] == board[row][col+1]) &&
       (board[row][col] == board[row][col-1]) &&
       (board[row][col] == board[row][col-2])){
    /* horizontal - one to the right, two to the left */
    win = true;
   }
  }
 if (col >= 3){
   if ((board[row][col] == board[row][col-1]) &&
       (board[row][col] == board[row][col-2]) &&
       (board[row][col] == board[row][col-3])){
     /* horizontal - three already to the left */
     win = true;
   }
 }
 /* down right diagonal */
 if (row <= 4 && col <= 4){
   if ((board[row][col] == board[row+1][col+1]) &&
       (board[row][col] == board[row+2][col+2]) &&
       (board[row][col] == board[row+3][col+3])){
     /* three down to the right already */
     win = true;
  }
 }
 if (row <= 5 && row >= 1 && col <= 5 && col >= 1){
  if ((board[row][col] == board[row-1][col-1]) &&
      (board[row][col] == board[row+1][col+1]) &&
      (board[row][col] == board[row+2][col+2])){
     /* two down to the right already, one up to the left */
     win = true;
   }
 }
 if (row >= 3 && col >= 3){
  if ((board[row][col] == board[row-1][col-1]) &&
      (board[row][col] == board[row-2][col-2]) &&
      (board[row][col] == board[row-3][col-3])){
    /* one down to the right already, two up to the left */
    win = true;
  }
 }
 /* up right diagonal */
 if (row <= 4 && col >= 3){
  if ((board[row][col] == board[row+1][col-1]) &&
      (board[row][col] == board[row+2][col-2]) &&
      (board[row][col] == board[row+3][col-3])){
     /* three up to the left */
    win = true;
  }
 }
 if (row >= 1 && row <= 5 && col >= 2 && col <= 6){
   if ((board[row][col] == board[row-1][col+1]) &&
       (board[row][col] == board[row+1][col-1]) &&
       (board[row][col] == board[row+2][col-2])){
     /* two down to the left already, one up to the right */
     win = true;
   }
 }
 if (row >= 2 && row <= 6 && col >= 1 && col <= 5){
   if ((board[row][col] == board[row-1][col+1]) &&
       (board[row][col] == board[row-2][col+2]) &&
       (board[row][col] == board[row+1][col-1])){
     /* one down to the left already, two up to the right */
     win = true;
   }
 }
 if (row >= 3 && col <= 4){
   if ((board[row][col] == board[row-1][col+1]) &&
       (board[row][col] == board[row-2][col+2]) &&
       (board[row][col] == board[row-3][col+3])){
     /* three up to the right */
     win = true;
   }
 }
}
This function checks the winner of the game using the values stored in board. It checks every possible case of a win from the last piece placed on the board.

That is all of the code to run this game. If you have any questions or need clarification you can contact a group member.