Connect 4 game using the NeoPixel Matrix 8x8 RGB LED and a 5-way Tactile Navigation Switch.

Dependencies:   Matrix PinDetect mbed

Fork of 4180_Project_Finalcode by 4180

Revision:
4:37b7ed4aa26b
Parent:
2:1525f7ae330e
--- a/main.cpp	Thu Apr 26 02:51:49 2018 +0000
+++ b/main.cpp	Thu Apr 26 03:20:45 2018 +0000
@@ -1,3 +1,11 @@
+// ======================================================================
+// Program to create a Connect 4 game using a NeoPixel Matrix 8x8 RGB LED
+// and a 5-way Tactile Navigation Switch.
+// Ha Dao and Joseph Doughty
+// April 25, 2018
+// Georgia Institute of Technology, ECE4011 Final Project
+//=======================================================================
+
 #include "mbed.h"
 #include "NeoStrip.h"
 #include "PinDetect.h"
@@ -5,36 +13,39 @@
 
 #define N 64
 
-NeoStrip strip(p18, N); //8x8 neopixel matrix with each neopixel addressable by its index which range from 0 to 63 
-Matrix board(8,7); //the Connect Four game board is a 6x7 matrix, the neopixel matrix is 8x8, created an 8x7 matrix to keep track of moves
+NeoStrip strip(p18, N); // 8x8 neopixel matrix with each "pixel" LED addressable by its index, which range from 0 to 63 
+Matrix board(8,7); // the Connect Four game board is a 6x7 matrix, the NeoPixel matrix is 8x8, created an 8x7 matrix to keep track of moves
              
 PinDetect right(p5);
 PinDetect left(p7);
 PinDetect center(p8);
  
-int pos = 0; //current position of led in Neopixel index
-int row = 0;
+int pos = 0; //c urrent position of LED in Neopixel index
+int row = 0; 
 int col = 0;
-int winmode = 0; //0 means the game is not won, 1-4 are different ways to win
+int winmode = 0; //0 means the game hasn't yet been won, 1-4 are different ways to win
 
-int red = 0xFF0000;
-int blue = 0x0000FF;
-int color = red;
+int red = 0xFF0000; // one player is red
+int blue = 0x0000FF; // other player is blue
+int color = red; // begin the game with the red player
 int winningcolor = 0;
 
-void alloff() //turn off all neopixel at the beginning
+// clears the LED matrix by turning each one off
+void alloff()
 {
     for (int i = 0; i < N; i++)
         strip.setPixel(i, 0, 0, 0);
     strip.write();
 }
 
-int matrix2index(int r, int c) //convert row,col of matrix to index of neopixel that range from 0 to 63
+// converts row and column indexes of a matrix to the corresponding index of the NeoPixel
+int matrix2index(int r, int c) 
 {
    return (r-1)*8 + c - 1;
 }
 
-//when the game is won, flash the neopixels that lead to winning forever until the game is restarted
+// when the game is won, flashes the four LEDs corresponding to the winning move
+// this will continue until the game is reset via the mbed reset button
 void display_winner(int mode, int r, int c, int wincolor)
 {
     switch (mode)
@@ -108,9 +119,11 @@
     }
 }
 
+// checks to see if the game has been won; a game is won if either player has
+// four markers in a row horizontally, diagonally, or vertically
 void check_winner()
 {
-    //check 4 in a row
+    //checks for four markers in a row
     for (int r = 1; r < 9; r++)    
     {
         for (int c = 1; c < 6; c++)
@@ -122,7 +135,7 @@
             }
         }
     }
-    //check 4 in a col
+    //checks for four markers in a column
     for (int c = 1; c < 9; c++)
     {
         for (int r = 1; r < 6; r++)
@@ -134,7 +147,7 @@
             }
         }
     }
-    //check 4 in a forward diagonal
+    //checks for four markers in a forward (right-leaning) diagonal
     for (int r = 3; r < 6; r++)
     {
         for (int c = 1; c < 5; c++)
@@ -146,7 +159,7 @@
             }   
         }
     }
-    //check 4 in a reverse diagonal
+    //checks for four markers in a reverse (left-leaning) diagonal
     for (int r = 3; r < 6; r++)
     {
         for (int c = 4; c < 8; c++)
@@ -160,46 +173,47 @@
     }
 }
 
-void right_hit_callback (void) { //move to the flashing neopixel to the right
-    //led1 = !led1;
-    strip.setPixel(pos, 0, 0, 0); //turn off the current neopixel
-    if (pos < 6) pos = pos + 1; //move the neopixel to the right if not out of range
-}
-void left_hit_callback (void) {  //move the flashing neopixel to the left
-    //led3 = !led3;
-    strip.setPixel(pos, 0, 0, 0);
-    if (pos > 0) pos = pos - 1;
+// move the player marker to the right
+void right_hit_callback (void) { 
+    strip.setPixel(pos, 0, 0, 0); // turn off the current LED
+    if (pos < 6) pos = pos + 1; // only move to the right if not at "screen" edge
 }
 
-void center_hit_callback (void) { //drop the coin
-    //turn off the flashing neopixel on top row
-    strip.setPixel(pos, 0, 0, 0);
-    //then coin need to appear at the current column, on the lowest row that not occupied
+// move the player marker to the left
+void left_hit_callback (void) { 
+    strip.setPixel(pos, 0, 0, 0); // turn off the current LED
+    if (pos > 0) pos = pos - 1; // only move to the left if not at "screen" edge
+}
+
+// drop the player marker straight down the current column
+void center_hit_callback (void) { 
+    strip.setPixel(pos, 0, 0, 0); // turn off the current LED
+    // show marker at lowest unoccupied position in the selected column
     col = pos + 1;
     for(row = 8; row > 1; row-- )
     {
-        if (board.getNumber(row,col) == 0) break; //break out of loop when found the lowest unoccupied row
+        if (board.getNumber(row,col) == 0) break; // break upon finding lowest unoccupied position
     }
     //convert to neopixel index to turn of that neopixel, but only if not all rows in 6x7 board are occupied 
     if (row > 2) strip.setPixel(matrix2index(row,col), color);
     else return;
-    //after added LED to that position
-    if (color == red)
+
+    if (color == red) // if it's red player's turn,
     {
-        board.add( row, col, 1.0);//update matrix to have a matrix to check winner
-        check_winner(); //check if the winning move is made
-        color = blue; //change player/color
+        board.add( row, col, 1.0); // update matrix to have a matrix to check winner
+        check_winner(); // check board state to see if the game has been won
+        color = blue; // switch to the blue player
     }
-    else
+    else // else, if it's blue player's turn,
     {
-        board.add( row, col, 2.0);
-        check_winner();
-        color = red;
+        board.add( row, col, 2.0); // update matrix to have a matrix to check winner
+        check_winner(); // check board state to see if the game has been won
+        color = red; // switch to the red player
     }
 }
 
 int main() {
-   //initialize the matrix to 0 meaning all rows and cols are unoccupied
+   // initialize the matrix to 0 so that all rows and columns are unoccupied
    board << 0 << 0 << 0 << 0 << 0 << 0 << 0   
          << 0 << 0 << 0 << 0 << 0 << 0 << 0
          << 0 << 0 << 0 << 0 << 0 << 0 << 0
@@ -209,33 +223,35 @@
          << 0 << 0 << 0 << 0 << 0 << 0 << 0
          << 0 << 0 << 0 << 0 << 0 << 0 << 0;
              
-    // Use internal pullups for pushbutton
+    // use internal pullups for pushbutton
     right.mode(PullUp);    
     left.mode(PullUp);    
-    center.mode(PullUp); 
-    // Delay for initial pullup to take effect
+    center.mode(PullUp);
+     
+    // delay for initial pullup to take effect
     wait(.05);
-    // Setup Interrupt callback functions for a pb hit
-    right.attach_deasserted(&right_hit_callback); //used to move coin
-    left.attach_deasserted(&left_hit_callback);  //used to move coin
-    center.attach_deasserted(&center_hit_callback); //used to drop coin
-    // Start sampling pb inputs using interrupts
+    
+    // setup interrupt callback functions for a pb hit
+    right.attach_deasserted(&right_hit_callback); // used to move player marker
+    left.attach_deasserted(&left_hit_callback);  // used to move player marker
+    center.attach_deasserted(&center_hit_callback); // used to drop player marker
+                     
+    // start sampling inputs using interrupts
     right.setSampleFrequency();
     left.setSampleFrequency();
     center.setSampleFrequency();
     wait(.01);
     
-    float bright = 0.2; // 20% is plenty for indoor use
+    float bright = 0.2; // 20% brightness is plenty for indoor visibility
     strip.setBrightness(bright);    // set default brightness
-    alloff(); //initial all neopixels to off
+    alloff(); // initialize all of the NeoPixel LEDs to be off
     
     while(1)
     {
-        //winmode is initialized to 0 (not won and the function return)
-        //winmode is changed in check_winner
-        //need to call display_winner here rather than calling from interrupt fuction because display_winner loop forever if the game is won
+        // if the game has been won, display the winning move
         display_winner(winmode,row,col,winningcolor);
-        //flashing the current position indicating which col will the disc be dropped at
+        
+        // flash the LED corresponding to the currently selected player marker location
         strip.setPixel(pos, color);
         strip.write();
         wait(0.2);