Joey Doughty / Mbed 2 deprecated Connect_4_with_NeoPixel

Dependencies:   Matrix PinDetect mbed

Fork of 4180_Project_Finalcode by 4180

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // ======================================================================
00002 // Program to create a Connect 4 game using a NeoPixel Matrix 8x8 RGB LED
00003 // and a 5-way Tactile Navigation Switch.
00004 // Ha Dao and Joseph Doughty
00005 // April 25, 2018
00006 // Georgia Institute of Technology, ECE4011 Final Project
00007 //=======================================================================
00008 
00009 #include "mbed.h"
00010 #include "NeoStrip.h"
00011 #include "PinDetect.h"
00012 #include "Matrix.h"
00013 
00014 #define N 64
00015 
00016 NeoStrip strip(p18, N); // 8x8 neopixel matrix with each "pixel" LED addressable by its index, which range from 0 to 63 
00017 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
00018              
00019 PinDetect right(p5);
00020 PinDetect left(p7);
00021 PinDetect center(p8);
00022  
00023 int pos = 0; //c urrent position of LED in Neopixel index
00024 int row = 0; 
00025 int col = 0;
00026 int winmode = 0; //0 means the game hasn't yet been won, 1-4 are different ways to win
00027 
00028 int red = 0xFF0000; // one player is red
00029 int blue = 0x0000FF; // other player is blue
00030 int color = red; // begin the game with the red player
00031 int winningcolor = 0;
00032 
00033 // clears the LED matrix by turning each one off
00034 void alloff()
00035 {
00036     for (int i = 0; i < N; i++)
00037         strip.setPixel(i, 0, 0, 0);
00038     strip.write();
00039 }
00040 
00041 // converts row and column indexes of a matrix to the corresponding index of the NeoPixel
00042 int matrix2index(int r, int c) 
00043 {
00044    return (r-1)*8 + c - 1;
00045 }
00046 
00047 // when the game is won, flashes the four LEDs corresponding to the winning move
00048 // this will continue until the game is reset via the mbed reset button
00049 void display_winner(int mode, int r, int c, int wincolor)
00050 {
00051     switch (mode)
00052     {
00053         case 1:
00054             while (1)
00055                 {
00056                    strip.setPixel(matrix2index(r,c), wincolor);
00057                    strip.setPixel(matrix2index(r,c+1), wincolor);
00058                    strip.setPixel(matrix2index(r,c+2), wincolor);
00059                    strip.setPixel(matrix2index(r,c+3), wincolor);
00060                    strip.write();
00061                    wait(0.2);
00062                    strip.setPixel(matrix2index(r,c), 0, 0, 0);
00063                    strip.setPixel(matrix2index(r,c+1), 0, 0, 0);
00064                    strip.setPixel(matrix2index(r,c+2), 0, 0, 0);
00065                    strip.setPixel(matrix2index(r,c+3), 0, 0, 0);
00066                    strip.write();
00067                    wait(0.2);
00068                 }
00069         case 2:
00070             while (1)
00071                 {
00072                    strip.setPixel(matrix2index(r,c), wincolor);
00073                    strip.setPixel(matrix2index(r+1,c), wincolor);
00074                    strip.setPixel(matrix2index(r+2,c), wincolor);
00075                    strip.setPixel(matrix2index(r+3,c), wincolor);
00076                    strip.write();
00077                    wait(0.2);
00078                    strip.setPixel(matrix2index(r,c), 0, 0, 0);
00079                    strip.setPixel(matrix2index(r+1,c), 0, 0, 0);
00080                    strip.setPixel(matrix2index(r+2,c), 0, 0, 0);
00081                    strip.setPixel(matrix2index(r+3,c), 0, 0, 0);
00082                    strip.write();
00083                    wait(0.2);
00084                 }
00085         case 3:
00086             while (1)
00087                 {
00088                    strip.setPixel(matrix2index(r,c), wincolor);
00089                    strip.setPixel(matrix2index(r+1,c+1), wincolor);
00090                    strip.setPixel(matrix2index(r+2,c+2), wincolor);
00091                    strip.setPixel(matrix2index(r+3,c+3), wincolor);
00092                    strip.write();
00093                    wait(0.2);
00094                    strip.setPixel(matrix2index(r,c), 0, 0, 0);
00095                    strip.setPixel(matrix2index(r+1,c+1), 0, 0, 0);
00096                    strip.setPixel(matrix2index(r+2,c+2), 0, 0, 0);
00097                    strip.setPixel(matrix2index(r+3,c+3), 0, 0, 0);
00098                    strip.write();
00099                    wait(0.2);
00100                 }
00101         case 4:
00102             while (1)
00103                 {
00104                    strip.setPixel(matrix2index(r,c), wincolor);
00105                    strip.setPixel(matrix2index(r+1,c-1), wincolor);
00106                    strip.setPixel(matrix2index(r+2,c-2), wincolor);
00107                    strip.setPixel(matrix2index(r+3,c-3), wincolor);
00108                    strip.write();
00109                    wait(0.2);
00110                    strip.setPixel(matrix2index(r,c), 0, 0, 0);
00111                    strip.setPixel(matrix2index(r+1,c-1), 0, 0, 0);
00112                    strip.setPixel(matrix2index(r+2,c-2), 0, 0, 0);
00113                    strip.setPixel(matrix2index(r+3,c-3), 0, 0, 0);
00114                    strip.write();
00115                    wait(0.2);
00116                 }
00117         default:
00118             break;
00119     }
00120 }
00121 
00122 // checks to see if the game has been won; a game is won if either player has
00123 // four markers in a row horizontally, diagonally, or vertically
00124 void check_winner()
00125 {
00126     //checks for four markers in a row
00127     for (int r = 1; r < 9; r++)    
00128     {
00129         for (int c = 1; c < 6; c++)
00130         {
00131             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))
00132             {//have winner
00133                 row = r; col = c; winmode = 1; winningcolor = color;
00134                 return; //avoid the uncessary of continue to check
00135             }
00136         }
00137     }
00138     //checks for four markers in a column
00139     for (int c = 1; c < 9; c++)
00140     {
00141         for (int r = 1; r < 6; r++)
00142         {
00143             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))
00144             {//have winner
00145                 row = r; col = c; winmode = 2; winningcolor = color;
00146                 return;
00147             }
00148         }
00149     }
00150     //checks for four markers in a forward (right-leaning) diagonal
00151     for (int r = 3; r < 6; r++)
00152     {
00153         for (int c = 1; c < 5; c++)
00154         {
00155             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))
00156             {//have winner
00157                 row = r; col = c; winmode = 3; winningcolor = color;
00158                 return;
00159             }   
00160         }
00161     }
00162     //checks for four markers in a reverse (left-leaning) diagonal
00163     for (int r = 3; r < 6; r++)
00164     {
00165         for (int c = 4; c < 8; c++)
00166         {
00167             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))
00168             {//have winner
00169                 row = r; col = c; winmode = 4; winningcolor = color;
00170                 return;
00171             }   
00172         }
00173     }
00174 }
00175 
00176 // move the player marker to the right
00177 void right_hit_callback (void) { 
00178     strip.setPixel(pos, 0, 0, 0); // turn off the current LED
00179     if (pos < 6) pos = pos + 1; // only move to the right if not at "screen" edge
00180 }
00181 
00182 // move the player marker to the left
00183 void left_hit_callback (void) { 
00184     strip.setPixel(pos, 0, 0, 0); // turn off the current LED
00185     if (pos > 0) pos = pos - 1; // only move to the left if not at "screen" edge
00186 }
00187 
00188 // drop the player marker straight down the current column
00189 void center_hit_callback (void) { 
00190     strip.setPixel(pos, 0, 0, 0); // turn off the current LED
00191     // show marker at lowest unoccupied position in the selected column
00192     col = pos + 1;
00193     for(row = 8; row > 1; row-- )
00194     {
00195         if (board.getNumber(row,col) == 0) break; // break upon finding lowest unoccupied position
00196     }
00197     //convert to neopixel index to turn of that neopixel, but only if not all rows in 6x7 board are occupied 
00198     if (row > 2) strip.setPixel(matrix2index(row,col), color);
00199     else return;
00200 
00201     if (color == red) // if it's red player's turn,
00202     {
00203         board.add( row, col, 1.0); // update matrix to have a matrix to check winner
00204         check_winner(); // check board state to see if the game has been won
00205         color = blue; // switch to the blue player
00206     }
00207     else // else, if it's blue player's turn,
00208     {
00209         board.add( row, col, 2.0); // update matrix to have a matrix to check winner
00210         check_winner(); // check board state to see if the game has been won
00211         color = red; // switch to the red player
00212     }
00213 }
00214 
00215 int main() {
00216    // initialize the matrix to 0 so that all rows and columns are unoccupied
00217    board << 0 << 0 << 0 << 0 << 0 << 0 << 0   
00218          << 0 << 0 << 0 << 0 << 0 << 0 << 0
00219          << 0 << 0 << 0 << 0 << 0 << 0 << 0
00220          << 0 << 0 << 0 << 0 << 0 << 0 << 0
00221          << 0 << 0 << 0 << 0 << 0 << 0 << 0
00222          << 0 << 0 << 0 << 0 << 0 << 0 << 0
00223          << 0 << 0 << 0 << 0 << 0 << 0 << 0
00224          << 0 << 0 << 0 << 0 << 0 << 0 << 0;
00225              
00226     // use internal pullups for pushbutton
00227     right.mode(PullUp);    
00228     left.mode(PullUp);    
00229     center.mode(PullUp);
00230      
00231     // delay for initial pullup to take effect
00232     wait(.05);
00233     
00234     // setup interrupt callback functions for a pb hit
00235     right.attach_deasserted(&right_hit_callback); // used to move player marker
00236     left.attach_deasserted(&left_hit_callback);  // used to move player marker
00237     center.attach_deasserted(&center_hit_callback); // used to drop player marker
00238                      
00239     // start sampling inputs using interrupts
00240     right.setSampleFrequency();
00241     left.setSampleFrequency();
00242     center.setSampleFrequency();
00243     wait(.01);
00244     
00245     float bright = 0.2; // 20% brightness is plenty for indoor visibility
00246     strip.setBrightness(bright);    // set default brightness
00247     alloff(); // initialize all of the NeoPixel LEDs to be off
00248     
00249     while(1)
00250     {
00251         // if the game has been won, display the winning move
00252         display_winner(winmode,row,col,winningcolor);
00253         
00254         // flash the LED corresponding to the currently selected player marker location
00255         strip.setPixel(pos, color);
00256         strip.write();
00257         wait(0.2);
00258         strip.setPixel(pos, 0, 0, 0);
00259         strip.write();
00260         wait(0.2);
00261     }    
00262 }