Sudoku Game using the LCD, joystick, number pad, and speaker.

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player_copy

Fork of rtos_basic by mbed official

main.cpp

Committer:
decfrv
Date:
2016-11-03
Revision:
7:a935e2f5ebd0
Parent:
3:c92e21f305d8

File content as of revision 7:a935e2f5ebd0:

#include "mbed.h"
#include <mpr121.h>
#include "rtos.h"
#include "uLCD_4DGL.h"
#include "wave_player.h"
#include "SDFileSystem.h"
 
 class Nav_Switch
{
public:
    Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire);
    int read();
//boolean functions to test each switch
    bool up();
    bool down();
    bool left();
    bool right();
    bool fire();
//automatic read on RHS
    operator int ();
//index to any switch array style
    bool operator[](int index) {
        return _pins[index];
    };
private:
    BusIn _pins;
 
};
Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire):
    _pins(up, down, left, right, fire)
{
    _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise
    wait(0.001); //delays just a bit for pullups to pull inputs high
}
inline bool Nav_Switch::up()
{
    return !(_pins[0]);
}
inline bool Nav_Switch::down()
{
    return !(_pins[1]);
}
inline bool Nav_Switch::left()
{
    return !(_pins[2]);
}
inline bool Nav_Switch::right()
{
    return !(_pins[3]);
}
inline bool Nav_Switch::fire()
{
    return !(_pins[4]);
}
inline int Nav_Switch::read()
{
    return _pins.read();
}
inline Nav_Switch::operator int ()
{
    return _pins.read();
}
 
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
uLCD_4DGL uLCD(p28,p27,p30);
Serial pc(USBTX, USBRX);

SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
DigitalIn sddetect(p9);

Nav_Switch myNav( p16, p19, p15, p20, p17); //pin order on Sparkfun breakout

//number pad
InterruptIn interrupt(p21);
I2C i2c(p9, p10);
Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);

AnalogOut DACout(p18);
wave_player waver(&DACout);

Mutex lcdMutex;



int xndx;
int yndx;

static int nums [9][9] = {{0,5,4, 9,3,8, 2,7,6},
                  {6,7,9, 1,4,2, 8,3,5},
                  {8,2,3, 7,5,6, 4,9,1},
                  
                  {4,8,5, 2,7,9, 6,1,3},
                  {7,3,1, 6,0,4, 5,2,9},
                  {9,6,2, 3,1,5, 7,8,4},
                  
                  {5,1,6, 0,2,3, 9,4,7},
                  {2,9,7, 4,6,1, 3,5,8},
                  {3,4,8, 5,9,7, 1,6,2}};


bool preset[9][9] = {};

bool interruptChange = false;
int interruptNum = -1;

// Key hit/release interrupt routine
void fallInterrupt() {

      int value=mpr121.read(0x00);
      value +=mpr121.read(0x01)<<8;
            
      int number = 0;
      if ((value>>9) & 0x01) {
          number = 9;
      } else if ((value>>8) & 0x01) {
          number = 8;
      } else if ((value>>7) & 0x01) {
          number = 7;
      } else if ((value>>6) & 0x01) {
          number = 6;
      } else if ((value>>5) & 0x01) {
          number = 5;
      } else if ((value>>4) & 0x01) {
          number = 4;
      } else if ((value>>3) & 0x01) {
          number = 3;
      } else if ((value>>2) & 0x01) {
          number = 2;
      } else if ((value>>1) & 0x01) {
          number = 1;
      } else if (value & 0x01) {
          number = 0;
      }

  if (!preset[yndx][xndx]) {
      interruptNum = number;
      //nums[yndx][xndx] = number;
      interruptChange = true;
  }
}

int main() {
    nums[0][0] = 1;
    interrupt.fall(&fallInterrupt);
    interrupt.mode(PullUp);
    
    uLCD.background_color(WHITE);
    uLCD.cls();
    uLCD.color(BLACK);
    uLCD.text_height(1);
    uLCD.text_width(1);
    uLCD.textbackground_color(WHITE);
    //uLCD.printf("1 2 3 4 5 6 7 8 9\n\n1 2 3 4 5 6 7 8 9\n\n1 2 3 4 5 6 7 8 9\n1 2 3 4 5 6 7 8 9\n\n1 2 3 4 5 6 7 8 9\n\n1 2 3 4 5 6 7 8 9\n1 2 3 4 5 6 7 8 9\n\n1 2 3 4 5 6 7 8 9\n\n1 2 3 4 5 6 7 8 9");
    
    /*uLCD.filled_triangle(30, 61, 13, 81, 51, 112, GREEN);
    uLCD.filled_triangle(30, 61, 51, 112, 66, 92, GREEN);
    uLCD.filled_triangle(51, 112, 104, 11, 120, 24, GREEN);
    uLCD.filled_triangle(51, 112, 31, 96, 104, 11, GREEN);*/
    
    uLCD.color(BLUE);
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (nums[i][j] == 0) {
                uLCD.printf("  ");
                preset[i][j] = false;
            } else {
                uLCD.printf("%d ", nums[i][j]);
                preset[i][j] = true;
            }
        }
        //uLCD.printf("\n");
        if (i != 2 && i != 5) {
            uLCD.printf("\n");
        }
    }
    uLCD.color(BLACK); 
    
    
    uLCD.line(40, 0, 40, 128, BLACK);
    uLCD.line(80, 0, 80, 128, BLACK);
    uLCD.line(0, 40, 128, 40, BLACK);
    uLCD.line(0, 80, 128, 80, BLACK);
    
    xndx = 0;
    yndx = 0;
    int oldxndx = 0;
    int oldyndx = 0;
    bool changed = true;
    
    bool up = false;
    bool down = false;
    bool left = false;
    bool right = false;
    bool fire = false;
    //uLCD.rectangle(0,0,7,7, BLUE);
    
    
    bool keepGoing = true;
    while (keepGoing) {
        //led1 = !led1;
        oldyndx = yndx;
        oldxndx = xndx;
        if(myNav.left() && !up) {
             if (yndx > 0) {
                 //oldyndx=yndx;
                 //do {
                    yndx--;
                 //} while (preset[yndx][xndx] && yndx != 0);
                 changed = true;
             }
             up = true;
        } else if(myNav.right() && !down) {
             if (yndx < 8) {
                 //oldyndx=yndx;
                 //do {
                    yndx++;
                 //} while (preset[yndx][xndx] && yndx != 8);
                 changed = true;
             }
             down = true;
        } else if(myNav.down() && !left) {
             if (xndx > 0) {
                 //oldxndx=xndx;
                 //do {
                    xndx--;
                 //} while (preset[yndx][xndx] && xndx != 0);
                 changed = true;
             }
             left= true;
        } else if(myNav.up() && !right) {
             if (xndx < 8) {
                 //oldxndx=xndx;
                 //do {
                    xndx++;
                 //} while (preset[yndx][xndx] && xndx != 8);
                 changed = true;
             }
             right = true;
        } else if(myNav.fire() && !fire) {
            
            bool test = true;
            ///////////////////////////////////////////////
            pc.printf("5,5: %d\r\n",nums[4][4]);
            for (int i = 0; i < 9; i++) {
                int sum = 0;
                int product = 1;
                for (int j = 0; j < 9; j++) {
                    product *= nums[i][j];
                    sum += nums[i][j];
                }
                if (sum != 45 || product != 362880) {
                    test = false;
                    pc.printf("Bad Row: %d Sum:%d Product:%d\r\n", i + 1, sum, product);
                }
            }   
            
            for (int i = 0; i < 9; i++) {
                int sum = 0;
                int product = 1;
                for (int j = 0; j < 9; j++) {
                    product *= nums[j][i];
                    sum += nums[j][i];
                }
                if (sum != 45 || product != 362880) {
                    test = false;
                    pc.printf("Bad Column: %d Sum:%d Product:%d\r\n", i + 1, sum, product);
                }
            }
            
            for (int m = 0; m < 3; m++) {
                for (int k = 0; k < 3; k++) {
                    int sum = 0;
                    int product = 1;
                    for (int i = 0; i < 3; i++) {
                        for (int j = 0; j < 3; j++) {
                            product *= nums[3*k + i][3*m + j];
                            sum += nums[3*k + i][3*m + j];
                        }
                    } 
                    if (sum != 45 || product != 362880) {
                        test = false;
                        pc.printf("Bad Box: %d Sum:%d Product:%d\r\n", m*3 + k + 1, sum, product);
                    }
                }
            }
            if (test) {
                //Play Sound
                for (int i = 0; i < 20; i++) {
                    uLCD.line(11+i,81-i, 49+i, 112-i, GREEN);
                    uLCD.line(12+i,81-i, 50+i, 112-i, GREEN);
                    uLCD.line(51-i,112-i, 120-i,24-i, GREEN);
                    uLCD.line(52-i,112-i, 121-i,24-i, GREEN);
                }
                keepGoing = false;
                pc.printf("SUCCESS :)\r\n");
                
                FILE *wave_file;
                wave_file = fopen("/sd/champs.wav","r");
                bool playing = true;
                int vol = 5;
                waver.play(wave_file, playing, vol);
            } else {
                for (int i = 0; i < 20; i++) {
                    uLCD.line(21+i,15,89+i,118, RED);
                    uLCD.line(89+i,15,21+i,118, RED);
                }
                pc.printf("FAILURE :(\r\n");
                FILE *wave_file;
                wave_file = fopen("/sd/failure.wav","r");
                bool playing = true;
                int vol = 5;
                waver.play(wave_file, playing, vol);
                //wait(5);
                //redraw
                uLCD.cls();
                uLCD.color(BLUE);
                for (int i = 0; i < 9; i++) {
                    for (int j = 0; j < 9; j++) {
                        if (nums[i][j] == 0) {
                            uLCD.printf("  ");
                            preset[i][j] = false;
                        } else {
                            uLCD.printf("%d ", nums[i][j]);
                            preset[i][j] = true;
                        }
                    }
                    //uLCD.printf("\n");
                    if (i != 2 && i != 5) {
                        uLCD.printf("\n");
                    }
                }
                uLCD.color(BLACK); 
                
                
                uLCD.line(40, 0, 40, 128, BLACK);
                uLCD.line(80, 0, 80, 128, BLACK);
                uLCD.line(0, 40, 128, 40, BLACK);
                uLCD.line(0, 80, 128, 80, BLACK);
            }
            
            ///////////////////////////////////////////////
            fire = true;
        } else {
            up = false;
            down = false;
            left = false;
            right = false;
            fire = false;
        }
        
        if (changed) {
            int xpoint = xndx * 14;
            int ypoint = yndx * 16 - (yndx/3) * 8;
            int oxpoint = oldxndx * 14;
            int oypoint = oldyndx * 16 - (oldyndx/3) * 8;
            
            uLCD.rectangle(oxpoint,oypoint-1,oxpoint+7,oypoint+7, WHITE);
            uLCD.rectangle(xpoint,ypoint-1,xpoint+7,ypoint+7, BLUE);
            changed = false;
        }
        //pc.printf("Joystick: %d %d %d %d %d\n\r", myNav[0], myNav[1], myNav[2], myNav[3], myNav[4]);
        //int number = -1;
        if (interruptChange && nums[yndx][xndx] != 0 && !preset[yndx][xndx]) {
            //number = nums[yndx][xndx];
            //pc.printf("Number: %d\r\n", nums[yndx][xndx]);
            uLCD.locate(xndx * 2, yndx *2 - (yndx/3));
            uLCD.printf("%d", nums[yndx][xndx]);
            interruptChange = false;
            
            //pc.printf("Test: %d\r\n", nums[yndx][xndx]);
            
            int xpoint = xndx * 14;
            int ypoint = yndx * 16 - (yndx/3) * 8;
            uLCD.rectangle(xpoint,ypoint-1,xpoint+7,ypoint+7, BLUE);
        }
        if (interruptNum != -1 && interruptNum != 0) {
            //pc.printf("Setting 5,5 as %d\r\n", interruptNum);
            nums[yndx][xndx] = interruptNum;
            interruptNum = -1;
            FILE *wave_file;
            wave_file = fopen("/sd/beep.wav","r");
            bool playing = true;
            int vol = 5;
            waver.play(wave_file, playing, vol);
        }
        //pc.printf("Test2: %d\r\n", nums[yndx][xndx]);
        wait(0.1);
    }
}