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

Committer:
Josahty
Date:
Thu Apr 26 03:20:45 2018 +0000
Revision:
4:37b7ed4aa26b
Parent:
2:1525f7ae330e
Updated comments and formatting

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Josahty 4:37b7ed4aa26b 1 // ======================================================================
Josahty 4:37b7ed4aa26b 2 // Program to create a Connect 4 game using a NeoPixel Matrix 8x8 RGB LED
Josahty 4:37b7ed4aa26b 3 // and a 5-way Tactile Navigation Switch.
Josahty 4:37b7ed4aa26b 4 // Ha Dao and Joseph Doughty
Josahty 4:37b7ed4aa26b 5 // April 25, 2018
Josahty 4:37b7ed4aa26b 6 // Georgia Institute of Technology, ECE4011 Final Project
Josahty 4:37b7ed4aa26b 7 //=======================================================================
Josahty 4:37b7ed4aa26b 8
hdao9 0:f0807589902f 9 #include "mbed.h"
hdao9 0:f0807589902f 10 #include "NeoStrip.h"
hdao9 0:f0807589902f 11 #include "PinDetect.h"
hdao9 1:85d63d7193e3 12 #include "Matrix.h"
hdao9 0:f0807589902f 13
hdao9 0:f0807589902f 14 #define N 64
hdao9 0:f0807589902f 15
Josahty 4:37b7ed4aa26b 16 NeoStrip strip(p18, N); // 8x8 neopixel matrix with each "pixel" LED addressable by its index, which range from 0 to 63
Josahty 4:37b7ed4aa26b 17 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
hdao9 1:85d63d7193e3 18
hdao9 0:f0807589902f 19 PinDetect right(p5);
hdao9 0:f0807589902f 20 PinDetect left(p7);
hdao9 0:f0807589902f 21 PinDetect center(p8);
hdao9 0:f0807589902f 22
Josahty 4:37b7ed4aa26b 23 int pos = 0; //c urrent position of LED in Neopixel index
Josahty 4:37b7ed4aa26b 24 int row = 0;
hdao9 1:85d63d7193e3 25 int col = 0;
Josahty 4:37b7ed4aa26b 26 int winmode = 0; //0 means the game hasn't yet been won, 1-4 are different ways to win
hdao9 0:f0807589902f 27
Josahty 4:37b7ed4aa26b 28 int red = 0xFF0000; // one player is red
Josahty 4:37b7ed4aa26b 29 int blue = 0x0000FF; // other player is blue
Josahty 4:37b7ed4aa26b 30 int color = red; // begin the game with the red player
hdao9 1:85d63d7193e3 31 int winningcolor = 0;
hdao9 0:f0807589902f 32
Josahty 4:37b7ed4aa26b 33 // clears the LED matrix by turning each one off
Josahty 4:37b7ed4aa26b 34 void alloff()
hdao9 0:f0807589902f 35 {
hdao9 0:f0807589902f 36 for (int i = 0; i < N; i++)
hdao9 0:f0807589902f 37 strip.setPixel(i, 0, 0, 0);
hdao9 0:f0807589902f 38 strip.write();
hdao9 0:f0807589902f 39 }
hdao9 0:f0807589902f 40
Josahty 4:37b7ed4aa26b 41 // converts row and column indexes of a matrix to the corresponding index of the NeoPixel
Josahty 4:37b7ed4aa26b 42 int matrix2index(int r, int c)
hdao9 1:85d63d7193e3 43 {
hdao9 1:85d63d7193e3 44 return (r-1)*8 + c - 1;
hdao9 1:85d63d7193e3 45 }
hdao9 1:85d63d7193e3 46
Josahty 4:37b7ed4aa26b 47 // when the game is won, flashes the four LEDs corresponding to the winning move
Josahty 4:37b7ed4aa26b 48 // this will continue until the game is reset via the mbed reset button
hdao9 1:85d63d7193e3 49 void display_winner(int mode, int r, int c, int wincolor)
hdao9 1:85d63d7193e3 50 {
hdao9 1:85d63d7193e3 51 switch (mode)
hdao9 1:85d63d7193e3 52 {
hdao9 1:85d63d7193e3 53 case 1:
hdao9 1:85d63d7193e3 54 while (1)
hdao9 1:85d63d7193e3 55 {
hdao9 1:85d63d7193e3 56 strip.setPixel(matrix2index(r,c), wincolor);
hdao9 1:85d63d7193e3 57 strip.setPixel(matrix2index(r,c+1), wincolor);
hdao9 1:85d63d7193e3 58 strip.setPixel(matrix2index(r,c+2), wincolor);
hdao9 1:85d63d7193e3 59 strip.setPixel(matrix2index(r,c+3), wincolor);
hdao9 1:85d63d7193e3 60 strip.write();
hdao9 1:85d63d7193e3 61 wait(0.2);
hdao9 1:85d63d7193e3 62 strip.setPixel(matrix2index(r,c), 0, 0, 0);
hdao9 1:85d63d7193e3 63 strip.setPixel(matrix2index(r,c+1), 0, 0, 0);
hdao9 1:85d63d7193e3 64 strip.setPixel(matrix2index(r,c+2), 0, 0, 0);
hdao9 1:85d63d7193e3 65 strip.setPixel(matrix2index(r,c+3), 0, 0, 0);
hdao9 1:85d63d7193e3 66 strip.write();
hdao9 1:85d63d7193e3 67 wait(0.2);
hdao9 1:85d63d7193e3 68 }
hdao9 1:85d63d7193e3 69 case 2:
hdao9 1:85d63d7193e3 70 while (1)
hdao9 1:85d63d7193e3 71 {
hdao9 1:85d63d7193e3 72 strip.setPixel(matrix2index(r,c), wincolor);
hdao9 1:85d63d7193e3 73 strip.setPixel(matrix2index(r+1,c), wincolor);
hdao9 1:85d63d7193e3 74 strip.setPixel(matrix2index(r+2,c), wincolor);
hdao9 1:85d63d7193e3 75 strip.setPixel(matrix2index(r+3,c), wincolor);
hdao9 1:85d63d7193e3 76 strip.write();
hdao9 1:85d63d7193e3 77 wait(0.2);
hdao9 1:85d63d7193e3 78 strip.setPixel(matrix2index(r,c), 0, 0, 0);
hdao9 1:85d63d7193e3 79 strip.setPixel(matrix2index(r+1,c), 0, 0, 0);
hdao9 1:85d63d7193e3 80 strip.setPixel(matrix2index(r+2,c), 0, 0, 0);
hdao9 1:85d63d7193e3 81 strip.setPixel(matrix2index(r+3,c), 0, 0, 0);
hdao9 1:85d63d7193e3 82 strip.write();
hdao9 1:85d63d7193e3 83 wait(0.2);
hdao9 1:85d63d7193e3 84 }
hdao9 1:85d63d7193e3 85 case 3:
hdao9 1:85d63d7193e3 86 while (1)
hdao9 1:85d63d7193e3 87 {
hdao9 1:85d63d7193e3 88 strip.setPixel(matrix2index(r,c), wincolor);
hdao9 1:85d63d7193e3 89 strip.setPixel(matrix2index(r+1,c+1), wincolor);
hdao9 1:85d63d7193e3 90 strip.setPixel(matrix2index(r+2,c+2), wincolor);
hdao9 1:85d63d7193e3 91 strip.setPixel(matrix2index(r+3,c+3), wincolor);
hdao9 1:85d63d7193e3 92 strip.write();
hdao9 1:85d63d7193e3 93 wait(0.2);
hdao9 1:85d63d7193e3 94 strip.setPixel(matrix2index(r,c), 0, 0, 0);
hdao9 1:85d63d7193e3 95 strip.setPixel(matrix2index(r+1,c+1), 0, 0, 0);
hdao9 1:85d63d7193e3 96 strip.setPixel(matrix2index(r+2,c+2), 0, 0, 0);
hdao9 1:85d63d7193e3 97 strip.setPixel(matrix2index(r+3,c+3), 0, 0, 0);
hdao9 1:85d63d7193e3 98 strip.write();
hdao9 1:85d63d7193e3 99 wait(0.2);
hdao9 1:85d63d7193e3 100 }
hdao9 1:85d63d7193e3 101 case 4:
hdao9 1:85d63d7193e3 102 while (1)
hdao9 1:85d63d7193e3 103 {
hdao9 1:85d63d7193e3 104 strip.setPixel(matrix2index(r,c), wincolor);
hdao9 1:85d63d7193e3 105 strip.setPixel(matrix2index(r+1,c-1), wincolor);
hdao9 1:85d63d7193e3 106 strip.setPixel(matrix2index(r+2,c-2), wincolor);
hdao9 1:85d63d7193e3 107 strip.setPixel(matrix2index(r+3,c-3), wincolor);
hdao9 1:85d63d7193e3 108 strip.write();
hdao9 1:85d63d7193e3 109 wait(0.2);
hdao9 1:85d63d7193e3 110 strip.setPixel(matrix2index(r,c), 0, 0, 0);
hdao9 1:85d63d7193e3 111 strip.setPixel(matrix2index(r+1,c-1), 0, 0, 0);
hdao9 1:85d63d7193e3 112 strip.setPixel(matrix2index(r+2,c-2), 0, 0, 0);
hdao9 1:85d63d7193e3 113 strip.setPixel(matrix2index(r+3,c-3), 0, 0, 0);
hdao9 1:85d63d7193e3 114 strip.write();
hdao9 1:85d63d7193e3 115 wait(0.2);
hdao9 1:85d63d7193e3 116 }
hdao9 1:85d63d7193e3 117 default:
hdao9 1:85d63d7193e3 118 break;
hdao9 1:85d63d7193e3 119 }
hdao9 1:85d63d7193e3 120 }
hdao9 1:85d63d7193e3 121
Josahty 4:37b7ed4aa26b 122 // checks to see if the game has been won; a game is won if either player has
Josahty 4:37b7ed4aa26b 123 // four markers in a row horizontally, diagonally, or vertically
hdao9 1:85d63d7193e3 124 void check_winner()
hdao9 1:85d63d7193e3 125 {
Josahty 4:37b7ed4aa26b 126 //checks for four markers in a row
hdao9 1:85d63d7193e3 127 for (int r = 1; r < 9; r++)
hdao9 1:85d63d7193e3 128 {
hdao9 1:85d63d7193e3 129 for (int c = 1; c < 6; c++)
hdao9 1:85d63d7193e3 130 {
hdao9 1:85d63d7193e3 131 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))
hdao9 1:85d63d7193e3 132 {//have winner
hdao9 1:85d63d7193e3 133 row = r; col = c; winmode = 1; winningcolor = color;
hdao9 2:1525f7ae330e 134 return; //avoid the uncessary of continue to check
hdao9 1:85d63d7193e3 135 }
hdao9 1:85d63d7193e3 136 }
hdao9 1:85d63d7193e3 137 }
Josahty 4:37b7ed4aa26b 138 //checks for four markers in a column
hdao9 1:85d63d7193e3 139 for (int c = 1; c < 9; c++)
hdao9 1:85d63d7193e3 140 {
hdao9 1:85d63d7193e3 141 for (int r = 1; r < 6; r++)
hdao9 1:85d63d7193e3 142 {
hdao9 1:85d63d7193e3 143 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))
hdao9 1:85d63d7193e3 144 {//have winner
hdao9 1:85d63d7193e3 145 row = r; col = c; winmode = 2; winningcolor = color;
hdao9 2:1525f7ae330e 146 return;
hdao9 1:85d63d7193e3 147 }
hdao9 1:85d63d7193e3 148 }
hdao9 1:85d63d7193e3 149 }
Josahty 4:37b7ed4aa26b 150 //checks for four markers in a forward (right-leaning) diagonal
hdao9 1:85d63d7193e3 151 for (int r = 3; r < 6; r++)
hdao9 1:85d63d7193e3 152 {
hdao9 1:85d63d7193e3 153 for (int c = 1; c < 5; c++)
hdao9 1:85d63d7193e3 154 {
hdao9 1:85d63d7193e3 155 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))
hdao9 2:1525f7ae330e 156 {//have winner
hdao9 1:85d63d7193e3 157 row = r; col = c; winmode = 3; winningcolor = color;
hdao9 2:1525f7ae330e 158 return;
hdao9 1:85d63d7193e3 159 }
hdao9 1:85d63d7193e3 160 }
hdao9 1:85d63d7193e3 161 }
Josahty 4:37b7ed4aa26b 162 //checks for four markers in a reverse (left-leaning) diagonal
hdao9 1:85d63d7193e3 163 for (int r = 3; r < 6; r++)
hdao9 1:85d63d7193e3 164 {
hdao9 1:85d63d7193e3 165 for (int c = 4; c < 8; c++)
hdao9 1:85d63d7193e3 166 {
hdao9 1:85d63d7193e3 167 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))
hdao9 2:1525f7ae330e 168 {//have winner
hdao9 1:85d63d7193e3 169 row = r; col = c; winmode = 4; winningcolor = color;
hdao9 2:1525f7ae330e 170 return;
hdao9 1:85d63d7193e3 171 }
hdao9 1:85d63d7193e3 172 }
hdao9 1:85d63d7193e3 173 }
hdao9 1:85d63d7193e3 174 }
hdao9 1:85d63d7193e3 175
Josahty 4:37b7ed4aa26b 176 // move the player marker to the right
Josahty 4:37b7ed4aa26b 177 void right_hit_callback (void) {
Josahty 4:37b7ed4aa26b 178 strip.setPixel(pos, 0, 0, 0); // turn off the current LED
Josahty 4:37b7ed4aa26b 179 if (pos < 6) pos = pos + 1; // only move to the right if not at "screen" edge
hdao9 0:f0807589902f 180 }
hdao9 0:f0807589902f 181
Josahty 4:37b7ed4aa26b 182 // move the player marker to the left
Josahty 4:37b7ed4aa26b 183 void left_hit_callback (void) {
Josahty 4:37b7ed4aa26b 184 strip.setPixel(pos, 0, 0, 0); // turn off the current LED
Josahty 4:37b7ed4aa26b 185 if (pos > 0) pos = pos - 1; // only move to the left if not at "screen" edge
Josahty 4:37b7ed4aa26b 186 }
Josahty 4:37b7ed4aa26b 187
Josahty 4:37b7ed4aa26b 188 // drop the player marker straight down the current column
Josahty 4:37b7ed4aa26b 189 void center_hit_callback (void) {
Josahty 4:37b7ed4aa26b 190 strip.setPixel(pos, 0, 0, 0); // turn off the current LED
Josahty 4:37b7ed4aa26b 191 // show marker at lowest unoccupied position in the selected column
hdao9 0:f0807589902f 192 col = pos + 1;
hdao9 1:85d63d7193e3 193 for(row = 8; row > 1; row-- )
hdao9 0:f0807589902f 194 {
Josahty 4:37b7ed4aa26b 195 if (board.getNumber(row,col) == 0) break; // break upon finding lowest unoccupied position
hdao9 0:f0807589902f 196 }
hdao9 2:1525f7ae330e 197 //convert to neopixel index to turn of that neopixel, but only if not all rows in 6x7 board are occupied
hdao9 1:85d63d7193e3 198 if (row > 2) strip.setPixel(matrix2index(row,col), color);
hdao9 1:85d63d7193e3 199 else return;
Josahty 4:37b7ed4aa26b 200
Josahty 4:37b7ed4aa26b 201 if (color == red) // if it's red player's turn,
hdao9 1:85d63d7193e3 202 {
Josahty 4:37b7ed4aa26b 203 board.add( row, col, 1.0); // update matrix to have a matrix to check winner
Josahty 4:37b7ed4aa26b 204 check_winner(); // check board state to see if the game has been won
Josahty 4:37b7ed4aa26b 205 color = blue; // switch to the blue player
hdao9 1:85d63d7193e3 206 }
Josahty 4:37b7ed4aa26b 207 else // else, if it's blue player's turn,
hdao9 1:85d63d7193e3 208 {
Josahty 4:37b7ed4aa26b 209 board.add( row, col, 2.0); // update matrix to have a matrix to check winner
Josahty 4:37b7ed4aa26b 210 check_winner(); // check board state to see if the game has been won
Josahty 4:37b7ed4aa26b 211 color = red; // switch to the red player
hdao9 2:1525f7ae330e 212 }
hdao9 0:f0807589902f 213 }
hdao9 0:f0807589902f 214
hdao9 2:1525f7ae330e 215 int main() {
Josahty 4:37b7ed4aa26b 216 // initialize the matrix to 0 so that all rows and columns are unoccupied
hdao9 2:1525f7ae330e 217 board << 0 << 0 << 0 << 0 << 0 << 0 << 0
hdao9 1:85d63d7193e3 218 << 0 << 0 << 0 << 0 << 0 << 0 << 0
hdao9 1:85d63d7193e3 219 << 0 << 0 << 0 << 0 << 0 << 0 << 0
hdao9 1:85d63d7193e3 220 << 0 << 0 << 0 << 0 << 0 << 0 << 0
hdao9 1:85d63d7193e3 221 << 0 << 0 << 0 << 0 << 0 << 0 << 0
hdao9 1:85d63d7193e3 222 << 0 << 0 << 0 << 0 << 0 << 0 << 0
hdao9 1:85d63d7193e3 223 << 0 << 0 << 0 << 0 << 0 << 0 << 0
hdao9 1:85d63d7193e3 224 << 0 << 0 << 0 << 0 << 0 << 0 << 0;
hdao9 1:85d63d7193e3 225
Josahty 4:37b7ed4aa26b 226 // use internal pullups for pushbutton
hdao9 0:f0807589902f 227 right.mode(PullUp);
hdao9 0:f0807589902f 228 left.mode(PullUp);
Josahty 4:37b7ed4aa26b 229 center.mode(PullUp);
Josahty 4:37b7ed4aa26b 230
Josahty 4:37b7ed4aa26b 231 // delay for initial pullup to take effect
hdao9 0:f0807589902f 232 wait(.05);
Josahty 4:37b7ed4aa26b 233
Josahty 4:37b7ed4aa26b 234 // setup interrupt callback functions for a pb hit
Josahty 4:37b7ed4aa26b 235 right.attach_deasserted(&right_hit_callback); // used to move player marker
Josahty 4:37b7ed4aa26b 236 left.attach_deasserted(&left_hit_callback); // used to move player marker
Josahty 4:37b7ed4aa26b 237 center.attach_deasserted(&center_hit_callback); // used to drop player marker
Josahty 4:37b7ed4aa26b 238
Josahty 4:37b7ed4aa26b 239 // start sampling inputs using interrupts
hdao9 0:f0807589902f 240 right.setSampleFrequency();
hdao9 0:f0807589902f 241 left.setSampleFrequency();
hdao9 0:f0807589902f 242 center.setSampleFrequency();
hdao9 0:f0807589902f 243 wait(.01);
hdao9 0:f0807589902f 244
Josahty 4:37b7ed4aa26b 245 float bright = 0.2; // 20% brightness is plenty for indoor visibility
hdao9 0:f0807589902f 246 strip.setBrightness(bright); // set default brightness
Josahty 4:37b7ed4aa26b 247 alloff(); // initialize all of the NeoPixel LEDs to be off
hdao9 0:f0807589902f 248
hdao9 2:1525f7ae330e 249 while(1)
hdao9 0:f0807589902f 250 {
Josahty 4:37b7ed4aa26b 251 // if the game has been won, display the winning move
hdao9 1:85d63d7193e3 252 display_winner(winmode,row,col,winningcolor);
Josahty 4:37b7ed4aa26b 253
Josahty 4:37b7ed4aa26b 254 // flash the LED corresponding to the currently selected player marker location
hdao9 0:f0807589902f 255 strip.setPixel(pos, color);
hdao9 0:f0807589902f 256 strip.write();
hdao9 0:f0807589902f 257 wait(0.2);
hdao9 0:f0807589902f 258 strip.setPixel(pos, 0, 0, 0);
hdao9 0:f0807589902f 259 strip.write();
hdao9 0:f0807589902f 260 wait(0.2);
hdao9 2:1525f7ae330e 261 }
hdao9 0:f0807589902f 262 }