Code for 4180 mini project

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

Fork of Pacman by Shawn Rigdon

Revision:
0:0a900ff9a788
Child:
1:b86030cf57c4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Mar 25 04:36:32 2014 +0000
@@ -0,0 +1,647 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "uLCD_4DGL.h"
+
+#define PAC_SIZE    5
+#define STEP_SIZE   8
+#define CLEARANCE   12
+
+AnalogIn jsx(p19);  // The joysticks origin is about 1.6V in both directions
+AnalogIn jsy(p20);  // For just three states in each direction use thresholds 1.1V and 2V
+uLCD_4DGL uLCD(p28, p27, p29);
+Mutex lcd_mutex;
+
+void checkMOVE(void);
+
+volatile bool win=false;
+volatile bool lose=false;
+volatile int x = 64;
+volatile int y = 88;
+//volatile int x = 0;
+//volatile int y = 0;
+volatile int gx1 = 64;
+volatile int gy1 = 40;
+volatile int pixel;
+int i;
+bool clearRIGHT,clearLEFT,clearUP,clearDOWN,bgcr,bgcl,bgcu,bgcd;
+int coins[81][2] = {
+        {40,88},{48,88},{56,88},{72,88},{80,88},{88,88},
+        {40,40},{48,40},{56,40},{64,40},{72,40},{80,40},{88,40},
+        {40,48},{40,56},{40,64},{40,72},{40,80},
+        {88,48},{88,56},{88,64},{88,72},{88,80},
+        {56,96},{56,104},{56,112},
+        {48,112},{40,112},{32,112},{24,112},{16,112},
+        {16,104},{16,96},{16,88},{16,80},{16,72},
+        {24,64},{32,64},
+        {16,64},{16,56},{16,48},{16,40},{16,32},{16,24},{16,16},
+        {24,16},{32,16},{40,16},{48,16},{56,16},
+        {56,24},{56,32},
+        {72,96},{72,104},{72,112},
+        {80,112},{88,112},{96,112},{104,112},{112,112},
+        {112,104},{112,96},{112,88},{112,80},{112,72},
+        {104,64},{96,64},
+        {112,64},{112,56},{112,48},{112,40},{112,32},{112,24},{112,16},
+        {104,16},{96,16},{88,16},{80,16},{72,16},
+        {72,24},{72,32}
+    };
+
+void replaceCOINS(void)
+{
+    for(int n=0; n<81; n++)
+    {
+        lcd_mutex.lock();
+        if(gx1 == coins[n][0] && gy1 == coins[n][1])
+        {
+            uLCD.filled_circle(gx1,gy1,1,0xFFFF00);    
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void BGclearRIGHT(void)
+{
+    bgcr = true;
+    for(int p=gx1; p <= gx1+CLEARANCE; p++)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4))
+        {
+            bgcr = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void BGclearLEFT(void)
+{
+    bgcl = true;
+    for(int p=gx1; p >= gx1-CLEARANCE; p--)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4))
+        {
+            bgcl = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void BGclearUP(void)
+{
+    bgcu = true;
+    for(int p=gy1; p >= gy1-CLEARANCE; p--)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(gx1,p)==uLCD.read_pixel(4,4))
+        {
+            bgcu = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void BGclearDOWN(void)
+{
+    bgcd = true;
+    for(int p=gy1; p <= gy1+CLEARANCE; p++)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(gx1,p)==uLCD.read_pixel(4,4))
+        {
+            bgcd = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void bgRIGHT(void)
+{
+    Thread::wait(50);
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
+    lcd_mutex.unlock();
+    replaceCOINS();
+    if(gx1>124)
+    {
+        gx1 = 0;
+    }
+    gx1 = gx1+STEP_SIZE;
+    lcd_mutex.lock();
+    uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
+    uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
+    uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
+    lcd_mutex.unlock();
+}
+
+void bgLEFT(void)
+{
+    Thread::wait(50);
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
+    lcd_mutex.unlock();
+    replaceCOINS();
+    if(gx1<4)
+    {
+        gx1 = 124;
+    }
+    gx1 = gx1-STEP_SIZE;
+    lcd_mutex.lock();
+    uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
+    uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
+    uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
+    lcd_mutex.unlock();
+}
+
+void bgUP(void)
+{
+    Thread::wait(50);
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
+    lcd_mutex.unlock();
+    replaceCOINS();
+    if(gy1<4)
+    {
+        gy1 = 124;
+    }
+    gy1 = gy1-STEP_SIZE;
+    lcd_mutex.lock();
+    uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
+    uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
+    uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
+    lcd_mutex.unlock();
+}
+
+void bgDOWN(void)
+{
+    Thread::wait(50);
+    lcd_mutex.lock();
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
+    lcd_mutex.unlock();
+    replaceCOINS();
+    if(gy1>124)
+    {
+        gy1 = 0;
+    }
+    gy1 = gy1+STEP_SIZE;
+    lcd_mutex.lock();
+    uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
+    uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
+    uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
+    lcd_mutex.unlock();
+}
+
+void follow(void)
+{
+    if(x==gx1 && y==gy1)
+    {
+        win = true;
+        lose = true;
+    }
+    while(x==gx1 && gy1<y && !win)
+    {
+        BGclearDOWN();
+        bgDOWN();
+    }
+    while(x==gx1 && gy1>y && !win)
+    {
+        BGclearUP();
+        bgUP();
+    }
+    while(y==gy1 && gx1<x && !win)
+    {
+        BGclearRIGHT();
+        bgRIGHT();
+    }
+    while(y==gy1 && gx1>x && !win)
+    {
+        BGclearLEFT();
+        bgLEFT();
+    }
+}
+
+void pickMOVE(void)
+{
+    while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win)
+    {
+        follow();
+        //Thread::wait(100);
+    }
+    int dec = rand()%4;
+    //int dec = 0;
+    if(dec == 0)
+    {
+        BGclearRIGHT();
+        while(bgcr && !win)
+        {
+            bgRIGHT();
+            BGclearRIGHT();
+        }
+    }
+    else if(dec == 1)
+    {
+        BGclearLEFT();
+        while(bgcl && !win)
+        {
+            bgLEFT();
+            BGclearLEFT();
+        }
+    }
+    else if(dec == 2)
+    {
+        BGclearUP();
+        while(bgcu && !win)
+        {
+            bgUP();
+            BGclearUP();
+        }
+    }
+    else
+    {
+        BGclearDOWN();
+        while(bgcd && !win)
+        {
+            bgDOWN();
+            BGclearDOWN();
+        }
+    }
+}        
+
+void CHECKclearRIGHT(void)
+{
+    clearRIGHT = true;
+    for(i=x; i <= x+CLEARANCE; i++)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(i,y)==uLCD.read_pixel(4,4))
+        {
+            clearRIGHT = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void CHECKclearLEFT(void)
+{
+    clearLEFT = true;
+    for(i=x; i >= x-CLEARANCE; i--)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(i,y)==uLCD.read_pixel(4,4))
+        {
+            clearLEFT = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void CHECKclearUP(void)
+{
+    clearUP = true;
+    for(i=y; i >= y-CLEARANCE; i--)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(x,i)==uLCD.read_pixel(4,4))
+        {
+            clearUP = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void CHECKclearDOWN(void)
+{
+    clearDOWN = true;
+    for(i=y; i <= y+CLEARANCE; i++)
+    {
+        lcd_mutex.lock();
+        if(uLCD.read_pixel(x,i)==uLCD.read_pixel(4,4))
+        {
+            clearDOWN = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void changeCOINS(void)
+{
+    for(int m=0; m<81; m++)
+    {
+        lcd_mutex.lock();
+        if(x == coins[m][0] && y == coins[m][1])
+        {
+            coins[m][0]=64;
+            coins[m][1]=64;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void PACmoveRIGHT(void)
+{
+    while(clearRIGHT && !win)
+    {
+        lcd_mutex.lock();
+        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
+        lcd_mutex.unlock();
+        if(x>124)
+        {
+            x = 0;
+        }
+        x = x+STEP_SIZE;
+        changeCOINS();
+        
+        if(x%(2*STEP_SIZE) == 0)
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x+2,y-2,x+PAC_SIZE,y+2,BLACK);
+            lcd_mutex.unlock();
+        }
+        else
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x+2,y,x+PAC_SIZE,y+1,BLACK);
+            lcd_mutex.unlock();
+        }
+        if(jsx <= .75)
+        {
+            checkMOVE();
+        }
+        CHECKclearRIGHT();
+        Thread::wait(10);
+    }
+}
+
+void PACmoveLEFT(void)
+{
+    while(clearLEFT && !win)
+    {
+        lcd_mutex.lock();
+        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
+        lcd_mutex.unlock();
+        if(x<4)
+        {
+            x = 128;
+        }
+        x = x-STEP_SIZE;
+        changeCOINS();
+        if(x%(2*STEP_SIZE) == 0)
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK);
+            lcd_mutex.unlock();
+        }
+        else
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x-2,y,x-PAC_SIZE,y+1,BLACK);
+            lcd_mutex.unlock();
+        }
+        if(jsx >= .1)
+        {
+            checkMOVE();
+        }
+        CHECKclearLEFT();
+        Thread::wait(10);
+    }
+}
+
+void PACmoveUP(void)
+{
+    while(clearUP && !win)
+    {
+        lcd_mutex.lock();
+        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
+        lcd_mutex.unlock();
+        if(y<4)
+        {
+            y = 128;
+        }
+        y = y-STEP_SIZE;
+        changeCOINS();
+        if(y%(2*STEP_SIZE) == 0)
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x-2,y-2,x+2,y-PAC_SIZE,BLACK);
+            lcd_mutex.unlock();
+        }
+        else
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x,y-2,x+1,y-PAC_SIZE,BLACK);
+            lcd_mutex.unlock();
+        }
+        if(jsy <= .9)
+        {
+            checkMOVE();
+        }
+        CHECKclearUP();
+        Thread::wait(10);
+    }
+}
+
+void PACmoveDOWN(void)
+{
+    while(clearDOWN && !win)
+    {
+        lcd_mutex.lock();
+        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
+        lcd_mutex.unlock();
+        if(y>124)
+        {
+            y = 0;
+        }
+        y = y+STEP_SIZE;
+        changeCOINS();
+        if(y%(2*STEP_SIZE) == 0)
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x-2,y+2,x+2,y+PAC_SIZE,BLACK);
+            lcd_mutex.unlock();
+        }
+        else
+        {
+            lcd_mutex.lock();
+            uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+            uLCD.filled_rectangle(x,y+2,x+1,y+PAC_SIZE,BLACK);
+            lcd_mutex.unlock();
+        }
+        if(jsy >= .1)
+        {
+            checkMOVE();
+        }
+        CHECKclearDOWN();
+        Thread::wait(10);
+    }
+}
+
+void checkMOVE(void)
+{
+    if(jsx > .9)
+    {
+        CHECKclearRIGHT();
+        PACmoveRIGHT();
+    }
+    else if(jsx < .1)
+    {
+        CHECKclearLEFT();
+        PACmoveLEFT();
+    }
+    if(jsy > .9)
+    {
+        CHECKclearUP();
+        PACmoveUP();
+    }
+    else if(jsy < .1)
+    {
+        CHECKclearDOWN();
+        PACmoveDOWN();
+    }
+}
+
+void drawBORDERS(void)
+{
+    //Outer Border
+    uLCD.rectangle(4,4,124,124,RED);
+    uLCD.line(8,8,8,120,RED);
+    uLCD.line(8,8,62,8,RED);
+    uLCD.line(62,8,62,32,RED);
+    uLCD.line(62,32,66,32,RED);
+    uLCD.line(66,32,66,8,RED);
+    uLCD.line(66,8,120,8,RED);
+    uLCD.line(120,8,120,120,RED);
+    uLCD.line(120,120,66,120,RED);
+    uLCD.line(66,120,66,96,RED);
+    uLCD.line(66,96,62,96,RED);
+    uLCD.line(62,96,62,120,RED);
+    uLCD.line(62,120,8,120,RED);
+    //Inner Rectangle
+    uLCD.rectangle(52,52,76,76,RED);
+    uLCD.rectangle(48,48,80,80,RED);
+    //Upper Left Corner
+    uLCD.line(48,24,24,24,RED);
+    uLCD.line(24,24,24,56,RED);
+    uLCD.line(24,56,32,56,RED);
+    uLCD.line(32,56,32,32,RED);
+    uLCD.line(32,32,48,32,RED);
+    uLCD.line(48,32,48,24,RED);
+    //Upper Right Corner
+    uLCD.line(80,24,104,24,RED);
+    uLCD.line(104,24,104,56,RED);
+    uLCD.line(104,56,96,56,RED);
+    uLCD.line(96,56,96,32,RED);
+    uLCD.line(96,32,80,32,RED);
+    uLCD.line(80,32,80,24,RED);
+    //Lower Left Corner
+    uLCD.line(48,104,24,104,RED);
+    uLCD.line(24,104,24,72,RED);
+    uLCD.line(24,72,32,72,RED);
+    uLCD.line(32,72,32,96,RED);
+    uLCD.line(32,96,48,96,RED);
+    uLCD.line(48,96,48,104,RED);
+    //Lower Right Corner
+    uLCD.line(80,104,104,104,RED);
+    uLCD.line(104,104,104,72,RED);
+    uLCD.line(104,72,96,72,RED);
+    uLCD.line(96,72,96,96,RED);
+    uLCD.line(96,96,80,96,RED);
+    uLCD.line(80,96,80,104,RED);
+}
+
+void placeCOINS(void)
+{
+    for(int j=0; j<81; j++)
+    {
+        uLCD.filled_circle(coins[j][0],coins[j][1],1,0xFFFF00);
+    }
+}
+
+void initialize(void)
+{
+    drawBORDERS();
+    placeCOINS();
+    uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
+    uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK);
+}
+
+void checkWIN(void)
+{
+    win = true;
+    for(int k=0; k<81; k++)
+    {
+        lcd_mutex.lock();
+        if(coins[k][0]!=64 || coins[k][1]!=64)
+        {
+            win = false;
+        }
+        lcd_mutex.unlock();
+    }
+}
+
+void pacMOVE(void const *args)
+{
+    while(!win)
+    {
+        checkMOVE();
+        Thread::wait(10);
+    }
+}
+
+void blueGHOST(void const *args)
+{
+    while(!win)
+    {
+        pickMOVE();
+    }
+}
+
+int main()
+{
+    uLCD.cls();
+    //uLCD.background_color(DGREY);
+    uLCD.baudrate(BAUD_3000000);
+    //int x=64,y=64,
+    //int xy[2]={64,64};
+    //Thread t1(thread1,&x1,&y1);
+    initialize();
+    Thread pm(pacMOVE);
+    Thread bg(blueGHOST);
+    //Thread clr(clear);
+    //pixel = uLCD.read_pixel(128,128);
+    //for(int k=0; k<10; k++){
+    //i = rand();
+    //uLCD.printf("rand = %d\n",rand());
+    Thread::wait(5000);
+    
+    while(!win)
+    {
+        checkWIN();
+        Thread::wait(1000);
+    }
+    //uLCD.printf("WIN");
+    Thread::wait(1000);
+    if(lose)
+    {
+        uLCD.cls();
+        uLCD.printf("Sorry\nGame Over");
+    }
+    else
+    {
+        uLCD.cls();
+        //uLCD.locate(60,60);
+        //uLCD.set_font_size(10,10);
+        uLCD.printf("Congratulations!\nYou Won!");
+    }
+    
+    while(1){}
+}
\ No newline at end of file