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:
2:1525f7ae330e
Parent:
1:85d63d7193e3
Child:
4:37b7ed4aa26b
--- a/main.cpp	Sat Apr 21 23:47:41 2018 +0000
+++ b/main.cpp	Sun Apr 22 00:25:22 2018 +0000
@@ -5,43 +5,36 @@
 
 #define N 64
 
-NeoStrip strip(p18, N);
-
-Matrix board(8,7);
+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
              
 PinDetect right(p5);
-//PinDetect down(p6);
 PinDetect left(p7);
 PinDetect center(p8);
-//PinDetect up(p9);
-
-//DigitalOut led1(LED1);
-//DigitalOut led2(LED2);
-//DigitalOut led3(LED3);
-//DigitalOut led4(LED4);
  
-int pos = 0;
+int pos = 0; //current position of led in Neopixel index
 int row = 0;
 int col = 0;
-int winmode = 0;
+int winmode = 0; //0 means the game is not won, 1-4 are different ways to win
 
 int red = 0xFF0000;
 int blue = 0x0000FF;
 int color = red;
 int winningcolor = 0;
 
-void alloff()
+void alloff() //turn off all neopixel at the beginning
 {
     for (int i = 0; i < N; i++)
         strip.setPixel(i, 0, 0, 0);
     strip.write();
 }
 
-int matrix2index(int r, int c)
+int matrix2index(int r, int c) //convert row,col of matrix to index of neopixel that range from 0 to 63
 {
    return (r-1)*8 + c - 1;
 }
 
+//when the game is won, flash the neopixels that lead to winning forever until the game is restarted
 void display_winner(int mode, int r, int c, int wincolor)
 {
     switch (mode)
@@ -62,7 +55,6 @@
                    strip.write();
                    wait(0.2);
                 }
-            break;
         case 2:
             while (1)
                 {
@@ -79,7 +71,6 @@
                    strip.write();
                    wait(0.2);
                 }
-            break;
         case 3:
             while (1)
                 {
@@ -96,7 +87,6 @@
                    strip.write();
                    wait(0.2);
                 }
-            break;
         case 4:
             while (1)
                 {
@@ -113,7 +103,6 @@
                    strip.write();
                    wait(0.2);
                 }
-            break;
         default:
             break;
     }
@@ -129,6 +118,7 @@
             if (board.getNumber(r,c) != 0 && board.getNumber(r,c) == board.getNumber(r,c+1) && board.getNumber(r,c+1) == board.getNumber(r,c+2) && board.getNumber(r,c+2) == board.getNumber(r,c+3))
             {//have winner
                 row = r; col = c; winmode = 1; winningcolor = color;
+                return; //avoid the uncessary of continue to check
             }
         }
     }
@@ -140,6 +130,7 @@
             if (board.getNumber(r,c) != 0 && board.getNumber(r,c) == board.getNumber(r+1,c) && board.getNumber(r+1,c) == board.getNumber(r+2,c) && board.getNumber(r+2,c) == board.getNumber(r+3,c))
             {//have winner
                 row = r; col = c; winmode = 2; winningcolor = color;
+                return;
             }
         }
     }
@@ -149,8 +140,9 @@
         for (int c = 1; c < 5; c++)
         {
             if (board.getNumber(r,c) != 0 && board.getNumber(r,c) == board.getNumber(r+1,c+1) && board.getNumber(r+1,c+1) == board.getNumber(r+2,c+2) && board.getNumber(r+2,c+2) == board.getNumber(r+3,c+3))
-            {//have winner}
+            {//have winner
                 row = r; col = c; winmode = 3; winningcolor = color;
+                return;
             }   
         }
     }
@@ -160,44 +152,42 @@
         for (int c = 4; c < 8; c++)
         {
             if (board.getNumber(r,c) != 0 && board.getNumber(r,c) == board.getNumber(r+1,c-1) && board.getNumber(r+1,c-1) == board.getNumber(r+2,c-2) && board.getNumber(r+2,c-2) == board.getNumber(r+3,c-3))
-            {//have winner}
+            {//have winner
                 row = r; col = c; winmode = 4; winningcolor = color;
+                return;
             }   
         }
     }
 }
 
-void right_hit_callback (void) { //move to the flashing LED to the right
+void right_hit_callback (void) { //move to the flashing neopixel to the right
     //led1 = !led1;
-    strip.setPixel(pos, 0, 0, 0);
-    if (pos < 6) pos = pos + 1;
+    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 LED to the left
+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;
 }
 
-//A random position in a 8x8 matrix have the neopixel index position: (row-1)*8 + col - 1   //with row and col start from 1
 void center_hit_callback (void) { //drop the coin
-    //led1 = 0; led2 = 0; led3 = 0; led4 = 0;
-    // in order to drop a coin, first the flashing on top row need to disappear
+    //turn off the flashing neopixel on top row
     strip.setPixel(pos, 0, 0, 0);
-    //then coin need to appear at the current column (which can be get from "pos"), on the lowest row not occupied
-    //how to keep track of occupied row?
+    //then coin need to appear at the current column, on the lowest row that not occupied
     col = pos + 1;
     for(row = 8; row > 1; row-- )
     {
-        if (board.getNumber(row,col) == 0) break; //have to break out of for loop becuz only want the first empty row
+        if (board.getNumber(row,col) == 0) break; //break out of loop when found the lowest unoccupied row
     }
-    //got col from pos, once got row, then can convert to index position and light up led at that 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)
     {
         board.add( row, col, 1.0);//update matrix to have a matrix to check winner
-        check_winner();
+        check_winner(); //check if the winning move is made
         color = blue; //change player/color
     }
     else
@@ -205,24 +195,12 @@
         board.add( row, col, 2.0);
         check_winner();
         color = red;
-    } 
-    //there will be no dropping affect to avoid having to temporary stop the while loop in main   
+    }
 }
 
-void one()  //turn on one at a time to test strip
-{
-    for (int i = 0; i < N; i++)
-    {
-        strip.setPixel(i, (uint8_t)(255), 0, 0);
-        strip.write();
-        wait(1);
-    }
-}  
-
-int main()
-{
-    
-board << 0 << 0 << 0 << 0 << 0 << 0 << 0
+int main() {
+   //initialize the matrix to 0 meaning all rows and cols are unoccupied
+   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
@@ -233,39 +211,36 @@
              
     // Use internal pullups for pushbutton
     right.mode(PullUp);    
-    //down.mode(PullUp);
     left.mode(PullUp);    
-    center.mode(PullUp);
-    //up.mode(PullUp);    
+    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
-    //down.attach_deasserted(&down_hit_callback); // not used
     left.attach_deasserted(&left_hit_callback);  //used to move coin
     center.attach_deasserted(&center_hit_callback); //used to drop coin
-    //up.attach_deasserted(&up_hit_callback);  // not used
     // Start sampling pb inputs using interrupts
     right.setSampleFrequency();
-    //down.setSampleFrequency();
     left.setSampleFrequency();
     center.setSampleFrequency();
-    //up.setSampleFrequency();
     wait(.01);
     
     float bright = 0.2; // 20% is plenty for indoor use
     strip.setBrightness(bright);    // set default brightness
-    alloff();
+    alloff(); //initial all neopixels to off
     
-    while(1) //flashing LED
+    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
         display_winner(winmode,row,col,winningcolor);
+        //flashing the current position indicating which col will the disc be dropped at
         strip.setPixel(pos, color);
         strip.write();
         wait(0.2);
         strip.setPixel(pos, 0, 0, 0);
         strip.write();
         wait(0.2);
-    }
-    
+    }    
 }
\ No newline at end of file