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

main.cpp

Committer:
hdao9
Date:
2018-04-21
Revision:
1:85d63d7193e3
Parent:
0:f0807589902f
Child:
2:1525f7ae330e

File content as of revision 1:85d63d7193e3:

#include "mbed.h"
#include "NeoStrip.h"
#include "PinDetect.h"
#include "Matrix.h"

#define N 64

NeoStrip strip(p18, N);

Matrix board(8,7);
             
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 row = 0;
int col = 0;
int winmode = 0;

int red = 0xFF0000;
int blue = 0x0000FF;
int color = red;
int winningcolor = 0;

void alloff()
{
    for (int i = 0; i < N; i++)
        strip.setPixel(i, 0, 0, 0);
    strip.write();
}

int matrix2index(int r, int c)
{
   return (r-1)*8 + c - 1;
}

void display_winner(int mode, int r, int c, int wincolor)
{
    switch (mode)
    {
        case 1:
            while (1)
                {
                   strip.setPixel(matrix2index(r,c), wincolor);
                   strip.setPixel(matrix2index(r,c+1), wincolor);
                   strip.setPixel(matrix2index(r,c+2), wincolor);
                   strip.setPixel(matrix2index(r,c+3), wincolor);
                   strip.write();
                   wait(0.2);
                   strip.setPixel(matrix2index(r,c), 0, 0, 0);
                   strip.setPixel(matrix2index(r,c+1), 0, 0, 0);
                   strip.setPixel(matrix2index(r,c+2), 0, 0, 0);
                   strip.setPixel(matrix2index(r,c+3), 0, 0, 0);
                   strip.write();
                   wait(0.2);
                }
            break;
        case 2:
            while (1)
                {
                   strip.setPixel(matrix2index(r,c), wincolor);
                   strip.setPixel(matrix2index(r+1,c), wincolor);
                   strip.setPixel(matrix2index(r+2,c), wincolor);
                   strip.setPixel(matrix2index(r+3,c), wincolor);
                   strip.write();
                   wait(0.2);
                   strip.setPixel(matrix2index(r,c), 0, 0, 0);
                   strip.setPixel(matrix2index(r+1,c), 0, 0, 0);
                   strip.setPixel(matrix2index(r+2,c), 0, 0, 0);
                   strip.setPixel(matrix2index(r+3,c), 0, 0, 0);
                   strip.write();
                   wait(0.2);
                }
            break;
        case 3:
            while (1)
                {
                   strip.setPixel(matrix2index(r,c), wincolor);
                   strip.setPixel(matrix2index(r+1,c+1), wincolor);
                   strip.setPixel(matrix2index(r+2,c+2), wincolor);
                   strip.setPixel(matrix2index(r+3,c+3), wincolor);
                   strip.write();
                   wait(0.2);
                   strip.setPixel(matrix2index(r,c), 0, 0, 0);
                   strip.setPixel(matrix2index(r+1,c+1), 0, 0, 0);
                   strip.setPixel(matrix2index(r+2,c+2), 0, 0, 0);
                   strip.setPixel(matrix2index(r+3,c+3), 0, 0, 0);
                   strip.write();
                   wait(0.2);
                }
            break;
        case 4:
            while (1)
                {
                   strip.setPixel(matrix2index(r,c), wincolor);
                   strip.setPixel(matrix2index(r+1,c-1), wincolor);
                   strip.setPixel(matrix2index(r+2,c-2), wincolor);
                   strip.setPixel(matrix2index(r+3,c-3), wincolor);
                   strip.write();
                   wait(0.2);
                   strip.setPixel(matrix2index(r,c), 0, 0, 0);
                   strip.setPixel(matrix2index(r+1,c-1), 0, 0, 0);
                   strip.setPixel(matrix2index(r+2,c-2), 0, 0, 0);
                   strip.setPixel(matrix2index(r+3,c-3), 0, 0, 0);
                   strip.write();
                   wait(0.2);
                }
            break;
        default:
            break;
    }
}

void check_winner()
{
    //check 4 in a row
    for (int r = 1; r < 9; r++)    
    {
        for (int c = 1; c < 6; c++)
        {
            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;
            }
        }
    }
    //check 4 in a col
    for (int c = 1; c < 9; c++)
    {
        for (int r = 1; r < 6; r++)
        {
            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;
            }
        }
    }
    //check 4 in a forward diagonal
    for (int r = 3; r < 6; r++)
    {
        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}
                row = r; col = c; winmode = 3; winningcolor = color;
            }   
        }
    }
    //check 4 in a reverse diagonal
    for (int r = 3; r < 6; r++)
    {
        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}
                row = r; col = c; winmode = 4; winningcolor = color;
            }   
        }
    }
}

void right_hit_callback (void) { //move to the flashing LED to the right
    //led1 = !led1;
    strip.setPixel(pos, 0, 0, 0);
    if (pos < 6) pos = pos + 1;
}
void left_hit_callback (void) {  //move the flashing LED 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
    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?
    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
    }
    //got col from pos, once got row, then can convert to index position and light up led at that position
    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();
        color = blue; //change player/color
    }
    else
    {
        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
         << 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
         << 0 << 0 << 0 << 0 << 0 << 0 << 0
         << 0 << 0 << 0 << 0 << 0 << 0 << 0
         << 0 << 0 << 0 << 0 << 0 << 0 << 0;
             
    // Use internal pullups for pushbutton
    right.mode(PullUp);    
    //down.mode(PullUp);
    left.mode(PullUp);    
    center.mode(PullUp);
    //up.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();
    
    while(1) //flashing LED
    {
        display_winner(winmode,row,col,winningcolor);
        strip.setPixel(pos, color);
        strip.write();
        wait(0.2);
        strip.setPixel(pos, 0, 0, 0);
        strip.write();
        wait(0.2);
    }
    
}