![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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
Diff: main.cpp
- 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(¢er_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