ECE 2035 AgarIO MiniProject

Dependencies:   4DGL-uLCD-SE ECE2035_Agar_Shell EthernetInterface Game_Synchronizer MMA8452 SDFileSystem Sound USBDevice mbed-rtos mbed wave_player

Fork of ECE2035_Agar_Shell by ECE2035 Spring 2015 TA

This program is a MiniProject given in ECE 2035. This is to design and program the multiplayer ethernet based AGAR.IO mbed game. Starting code is given by the instructor to aid student to complete the project. It utilize uLCD, Accelerometer, pushbuttons, sdFileSystem, ethernetBreakoutBoard, speaker in mBED LPC1768. It uses the similar concept to the Game http://agar.io/

Files at this revision

API Documentation at this revision

Comitter:
pkoirala3
Date:
Sat Mar 18 14:55:51 2017 +0000
Parent:
0:9d6ea88b6d14
Commit message:
EC 2035 MiniProject AGARIO

Changed in this revision

ECE2035_Agar_Shell_ECE2035_Prana.lib Show annotated file Show diff for this revision Revisions of this file
Sound.lib Show annotated file Show diff for this revision Revisions of this file
TMP36.lib Show annotated file Show diff for this revision Revisions of this file
USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
blob.cpp Show annotated file Show diff for this revision Revisions of this file
blob.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
misc.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ECE2035_Agar_Shell_ECE2035_Prana.lib	Sat Mar 18 14:55:51 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/ECE2035-Spring-2015-TA/code/ECE2035_Agar_Shell/#9d6ea88b6d14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sound.lib	Sat Mar 18 14:55:51 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/lennonjoseph/code/Sound/#d20271759ae8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TMP36.lib	Sat Mar 18 14:55:51 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/pkoirala3/code/ECE2035_MiniProject_AGARIO/#dee4bf7b73bf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Sat Mar 18 14:55:51 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/sparkfun/code/USBDevice/#2af474687369
--- a/blob.cpp	Sun Mar 20 03:38:40 2016 +0000
+++ b/blob.cpp	Sat Mar 18 14:55:51 2017 +0000
@@ -3,6 +3,30 @@
 
 extern Serial pc;
 
+// Take in a blob and determine whether it is inside the world.
+// If the blob has escaped the world, put it back on the edge
+// of the world and negate its velocity so that it bounces off
+// the boundary. Use WORLD_WIDTH and WORLD_HEIGHT defined in "misc.h"
+void BLOB_constrain2world(BLOB* b) {
+    // ***
+    // checking for x-based constraints
+    if ((b->posx - b->rad) <= 0 || (b->posx + b->rad) >= WORLD_WIDTH) {
+        b->vx = -1 * b->vx;
+        if (b->posx < 0) {
+            b->posx = b->rad;
+        } else if (b->posx > WORLD_WIDTH) {
+            b->posx = WORLD_WIDTH - b->rad;
+        }
+    }
+    // checking for y-based constraints
+    if ((b->posy - b->rad) <= 0 || (b->posy + b->rad) >= WORLD_HEIGHT)
+        b->vy = -1 * b->vy;
+        if (b->posy < 0) {
+            b->posy = b->rad;
+        } else if (b->posy > WORLD_HEIGHT) {
+            b->posy = WORLD_HEIGHT - b->rad;
+        }
+}
 
 // Randomly initialize a blob's position, velocity, color, radius, etc.
 // Set the valid flag to true and the delete_now flag to false.
@@ -11,34 +35,54 @@
 // when that blob is deleted.
 void BLOB_init(BLOB* b) {
     // ***
-}
-
-
-// Take in a blob and determine whether it is inside the world.
-// If the blob has escaped the world, put it back on the edge
-// of the world and negate its velocity so that it bounces off
-// the boundary. Use WORLD_WIDTH and WORLD_HEIGHT defined in "misc.h"
-void BLOB_constrain2world(BLOB* b) {
-    // ***
+    // get a random radius
+    int rad = (rand() % 5) + 1;
+    BLOB_init(b, rad);
 }
 
 // Randomly initialize a blob. Then set the radius to the provided value.
 void BLOB_init(BLOB* b, int rad) {
     // ***
+    // using food color
+    BLOB_init(b, rad, FOOD_COL);
 }
 
-// Randomly initialize a blob. Then set the radius and color to the 
+// Randomly initialize a blob. Then set the radius and color to the
 // provided values.
 void BLOB_init(BLOB* b, int rad, int color) {
     // ***
+    // get random (x,y,) for blob pos
+    int genSpace_x = WORLD_WIDTH  - (3*rad);
+    int genSpace_y = WORLD_HEIGHT - (3*rad);
+
+    int rand_x = (rand() % genSpace_x) + rad;
+    int rand_y = (rand() % genSpace_y) + rad;
+
+    b->posx = rand_x;
+    b->posy = rand_y;
+    b->old_x = rand_x;
+    b->old_y = rand_y;
+    b->vx = ACC_THRESHOLD * 1000;      
+    b->vy = ACC_THRESHOLD * 1000;      
+    b->rad = rad;
+    b->color = color;
+    b->valid = 1;
+    b->delete_now = 0;
 }
 
 // For debug purposes, you can use this to print a blob's properties to your computer's serial monitor.
 void BLOB_print(BLOB b) {
-    pc.printf("(%f, %f) <%f, %f> Color: 0x%x\n", b.posx, b.posy, b.vx, b.vy, b.color);
+    pc.printf("cur(%.3f, %.3f) old(%.3f, %.3f) vel<%.3f, %.3f> Col: 0x%x\n", b.posx, b.posy, b.old_x, b.old_y, b.vx, b.vy, b.color);
 }
 
 // Return the square of the distance from b1 to b2
 float BLOB_dist2(BLOB b1, BLOB b2) {
     // ***
-}
\ No newline at end of file
+    float x1 = b1.posx;
+    float y1 = b1.posy;
+
+    float x2 = b2.posx;
+    float y2 = b2.posy;
+
+    return ((x2-x1) *(x2-x1)) + ((y2-y1) * (y2-y1));
+}
--- a/blob.h	Sun Mar 20 03:38:40 2016 +0000
+++ b/blob.h	Sat Mar 18 14:55:51 2017 +0000
@@ -8,7 +8,7 @@
     int color;    
     bool valid;
     bool delete_now;
-} BLOB;
+} BLOB;  // Type of this structure is: BLOB, user created type
 
 void BLOB_init(BLOB* b);
 void BLOB_init(BLOB* b, int rad);
--- a/main.cpp	Sun Mar 20 03:38:40 2016 +0000
+++ b/main.cpp	Sat Mar 18 14:55:51 2017 +0000
@@ -1,13 +1,19 @@
 // Student Side Shell Code
+// By: Prana Koirala
+// ECE 2035
+// AGAR.GT Game
 // For the baseline, anywhere you see ***, you have code to write.
 
 #include "mbed.h"
-
 #include "SDFileSystem.h"
 #include "wave_player.h"
 #include "game_synchronizer.h"
 #include "misc.h"
 #include "blob.h"
+#include "playSound.h"
+#include "uLCD_4DGL.h"
+#include "TMP36.h"
+
 
 #define NUM_BLOBS 22
 
@@ -16,10 +22,16 @@
 DigitalOut led3(LED3);
 DigitalOut led4(LED4);
 
+DigitalOut RedLED(p15);
+DigitalOut GreenLED(p14);
+DigitalOut BlueLED(p13);
+
 DigitalIn pb_u(p21);                        // Up Button
 DigitalIn pb_r(p22);                        // Right Button
 DigitalIn pb_d(p23);                        // Down Button
 DigitalIn pb_l(p24);                        // Left Button
+TMP36 TEMP(p15);
+char hitTune[] = "/sd/score.wav";            // identifies a blob being eaten
 
 Serial pc(USBTX, USBRX);                    // Serial connection to PC. Useful for debugging!
 MMA8452 acc(p28, p27, 100000);              // Accelerometer (SDA, SCL, Baudrate)
@@ -33,51 +45,81 @@
 
 int score1 = 0;                             // Player 1's score.
 int score2 = 0;                             // Player 2's score.
+int num_player = 0;
+int const time_unit = 1000;                 // time for screen refresh
 
 
-// ***
-// Display a pretty game menu on the player 1 mbed. 
-// Do a good job, and make it look nice. Give the player
-// an option to play in single- or multi-player mode. 
-// Use the buttons to allow them to choose.
-int game_menu(void) {
+void display_Temp(void)
+{
+    float V = TEMP;  // Displaying Temp of chip so that player can quit game and cool it.
+    uLCD.printf("\n\n\n\n\n\n\n\nTemp:%4.1F Deg F\n",V);
+}
+
+
+// This Display the game menu on the player 1 mbed to give option to play in single or multiplayer mode.
+// They can use up and down button to make choice, some sound effect added.
+
+int game_menu(void)
+{
+    uLCD.set_font(FONT_8X12);
     uLCD.background_color(BGRD_COL);
     uLCD.textbackground_color(BGRD_COL);
     uLCD.cls();
     uLCD.locate(0,0);
-    uLCD.puts("AGAR SHELL");   
+    uLCD.puts("Welcome to Agar");
+    uLCD.printf("\n\n");
+    wait(2.0);
+    uLCD.printf("Loading Game...");
+    uLCD.printf("\n\n\n\n\n\n");
+    wait(3.0);
+    display_Temp();
+    BlueLED = 1;
     
-    // ***
-    // Spin until a button is pressed. Depending which button is pressed, 
-    // return either SINGLE_PLAYER or MULTI_PLAYER.
+    uLCD.cls();
+
+// Print single player or multiplayer mode. Depending which button is pressed, return either SINGLE_PLAYER or MULTI_PLAYER.
+    uLCD.set_font(FONT_7X8);
+    uLCD.printf("Select Mode:\n\n");
+    uLCD.printf("1P:Press up btn\n\n");
+    uLCD.printf("2P:Press down btn\n");
+    display_Temp();
+    int Mode = 0;
     while(1) {
-        if(!pb_u) { break; }
+        if(!pb_u) {
+            Mode = SINGLE_PLAYER;
+            break;
+        }
+        if(!pb_d) {
+            Mode = MULTI_PLAYER;
+            break;
+        }
     }
-    
-    return SINGLE_PLAYER;
-    
+    return Mode;
 }
 
-// Initialize the game hardware. 
-// Call game_menu to find out which mode to play the game in (Single- or Multi-Player)
+// Initialize the game hardware.
+// Call game_menu to find out which mode to play the game in (Single or MultiPlayer)
 // Initialize the game synchronizer.
-void game_init(void) {
-    
-    led1 = 0; led2 = 0; led3 = 0; led4 = 0;
-    
+void game_init(void)
+{
+    led1 = 0;
+    led2 = 0;
+    led3 = 0;
+    led4 = 0;
+
     pb_u.mode(PullUp);
-    pb_r.mode(PullUp); 
-    pb_d.mode(PullUp);    
+    pb_r.mode(PullUp);
+    pb_d.mode(PullUp);
     pb_l.mode(PullUp);
-    
+
     pc.printf("\033[2J\033[0;0H");              // Clear the terminal screen.
     pc.printf("I'm alive! Player 1\n");         // Let us know you made it this far
 
     // game_menu MUST return either SINGLE_PLAYER or MULTI_PLAYER
-    int num_players = game_menu();
-    
-    GS_init(sync, &uLCD, &acc, &pb_u, &pb_r, &pb_d, &pb_l, num_players, PLAYER1); // Connect to the other player.
-        
+    int num_player = game_menu();
+
+    GS_init(sync, &uLCD, &acc, &pb_u, &pb_r, &pb_d, &pb_l, num_player, PLAYER1); // Connect to the other player.
+
     pc.printf("Initialized...\n");              // Let us know you finished initializing.
     srand(time(NULL));                          // Seed the random number generator.
 
@@ -85,125 +127,381 @@
     GS_update(sync);
 }
 
+// Function for displaying the string
+void prints_string(char* text, int x, int y, int backgrnd, int foregrnd, bool clr)
+{
+    uLCD.background_color(backgrnd);
+    uLCD.textbackground_color(foregrnd);
+    uLCD.set_font(FONT_7X8);
+    if (clr == 1) {
+        uLCD.cls();
+    }
+    uLCD.locate(x,y);
+    uLCD.puts(text);
+    uLCD.printf("\n\n\n\n\n\n");
+    display_Temp();
+}
+
+
 // Display who won!
-void game_over(int winner) {
-    // Pause forever.
-    while(1);
+int game_over(int winner)
+{
+    if (winner == WINNER_P1) {   // P1 wins
+        char P1_WIN[10] = "P1 Won";
+        prints_string(P1_WIN, 0, 0, BGRD_COL, RED, 0);
+        char buzzer[] = "/sd/won.wav";
+        playSound(buzzer);   // Play the sound in the board
+
+    } else if (winner == WINNER_P2) {  // P2 OR AI wins
+        if (num_player == SINGLE_PLAYER) {   // AI wins
+            char AI_WIN[10] = "PC Won";
+            prints_string(AI_WIN, 0, 0, BGRD_COL, RED, 0);
+            char buzzer[] = "/sd/won.wav";
+            playSound(buzzer);   // Play the sound in the board
+
+
+        } else {   // P2 wins
+            char P2_WIN[10] = "P2 Won";
+            prints_string(P2_WIN, 0, 0, BGRD_COL, RED, 0);
+            char buzzer[] = "/sd/won.wav";
+            playSound(buzzer);   // Play the sound in the board
+        }
+
+    } else if (winner == WINNER_TIE) {  // Tied game
+        char NO_WIN[10] = "TIE";
+        prints_string(NO_WIN, 0, 0, BGRD_COL, RED, 0);
+        char buzzer[] = "/sd/won.wav";
+        playSound(buzzer);   // Play the sound in the board
+
+    }
+    while(1) {
+        RedLED = 0;
+        wait(0.75);
+        RedLED = 1;
+
+        if(!pb_r) {
+            uLCD.printf("Loading new Game");
+            wait(1.5);
+            uLCD.cls();
+            uLCD.printf("\n\n\n\n\n\n\n\n\n");
+            display_Temp();
+            return(1);
+        }
+    }
 }
 
 // Take in a pointer to the blobs array. Iterate over the array
 // and initialize each blob with BLOB_init(). Set the first blob to (for example) blue
 // and the second blob to (for example) red. Set the color(s) of the food blobs however you like.
 // Make the radius of the "player blobs" equal and larger than the radius of the "food blobs".
-void generate_blobs(BLOB* blobs) {
-    // ***
+void generate_blobs(BLOB* blobs)
+{
+    int sizePlayer = 15;
+    int sizeFood = 8;
+    for (int i = 0; i < NUM_BLOBS; i++) {
+        int rad = (i == PLAYER1 || i == PLAYER2) ? sizePlayer : sizeFood;   // get the radius
+        int col = (i == PLAYER1 || i == PLAYER2) ? ((i == PLAYER1) ? P1_COL : P2_COL) : FOOD_COL;   // get the color
+        BLOB_init(&blobs[i], rad, col);         //void BLOB_init(BLOB* b, int rad, int color)
+        BLOB_print(blobs[i]);
+    }
 }
 
 
 
-int main (void) {
-    
+int main (void)
+{
+
+Play_again:             // Option to play again
+    int score1 = 0;                             // Player 1's score reseting
+    int score2 = 0;                             // Player 2's score reseting
+
     int* p1_buttons;
     int* p2_buttons;
-    
+
     float ax1, ay1, az1;
     float ax2, ay2, az2;
-    
-    
+
+    float time_step = .01;
+
+    int rect_bl_x, rect_bl_y, rect_ur_x, rect_ur_y;     // rect. boundary, bottom-left, top-right (x,y)
+    float blob_x, blob_y;                                 // pos (x,y) for a blob
+
+
     // Ask the user to choose (via pushbuttons)
     // to play in single- or multi-player mode.
     // Use their choice to correctly initialize the game synchronizer.
-    game_init();  
-    
+    game_init();
+
     // Keep an array of blobs. Use blob 0 for player 1 and
     // blob 1 for player 2.
     BLOB blobs[NUM_BLOBS];
-        
+
     // Pass in a pointer to the blobs array. Iterate over the array
     // and initialize each blob with BLOB_init(). Set the radii and colors
     // anyway you see fit.
     generate_blobs(blobs);
-    
+
 
     while(true) {
-        
-        
+        GS_background_color(sync, SCREEN_BOTH, BGRD_COL);       // paint background colors
+
         // In single-player, check to see if the player has eaten all other blobs.
         // In multi-player mode, check to see if the players have tied by eating half the food each.
         // ***
-        
-        
-        
+        // check based on food eaten
+        if ((score1 + score2) >= (NUM_BLOBS-2) ) {
+            if (score1 > score2 && blobs[PLAYER1].valid == 1) {
+                // P1 wins
+                game_over(WINNER_P1);
+                game_over(WINNER_P1);
+                goto Play_again;   // To play again
+            } else if (score2 > score1 && blobs[PLAYER2].valid == 1) {
+                //P2 || AI wins
+                game_over(WINNER_P2);
+                game_over(WINNER_P1);
+                goto Play_again;   // To play again
+            } else if (score1 == score2) {
+                // Tie game
+                game_over(WINNER_TIE);
+                game_over(WINNER_P1);
+                goto Play_again;   // To play again
+            }
+        }
+        // check based on eating other player
+        if (blobs[PLAYER2].valid == 0) {
+            // P1  wins
+            game_over(WINNER_P1);
+            game_over(WINNER_P1);
+            goto Play_again;   // To play again
+        } else if (blobs[PLAYER1].valid == 0) {
+            // P2 || AI wins
+            game_over(WINNER_P2);
+            game_over(WINNER_P1);
+            goto Play_again;   // To play again
+        }
+
+
         // In both single- and multi-player modes, display the score(s) in an appropriate manner.
         // ***
-        
-        
+        if (num_player == SINGLE_PLAYER) {
+            // disp score top right of screen
+            char scoreBanner[40];
+            sprintf(scoreBanner,"Score:%d ", score1);
+            uLCD.background_color(BGRD_COL);
+            uLCD.textbackground_color(RED);//BGRD_COL);
+            uLCD.locate(10,0);
+            uLCD.puts(scoreBanner);
+
+            //GS_locate(sync, SCREEN_P1, 12,0);     // GS_locate(GSYNC* gs, char screen, int x, int y)
+            //GS_puts(sync, SCREEN_P1, bannerScore, strlen(bannerScore));      // void GS_puts(GSYNC* gs, char screen, char* str, int strlen)
+        } else if (num_player == MULTI_PLAYER) {
+            // disp score top right of screen
+            char bannerScore[40];
+            sprintf(bannerScore,"MS: P1: %2d \n    P2: %2d ", score1, score2);
+            GS_locate(sync, SCREEN_BOTH, 9,0);     // GS_locate(GSYNC* gs, char screen, int x, int y)
+            GS_puts(sync, SCREEN_BOTH, bannerScore, sizeof(bannerScore));      // void GS_puts(GSYNC* gs, char screen, char* str, int strlen)
+        }
+
         // Use the game synchronizer API to get the button values from both players' mbeds.
         p1_buttons = GS_get_p1_buttons(sync);
         p2_buttons = GS_get_p2_buttons(sync);
-        
+
         // Use the game synchronizer API to get the accelerometer values from both players' mbeds.
         GS_get_p1_accel_data(sync, &ax1, &ay1, &az1);
         GS_get_p2_accel_data(sync, &ax2, &ay2, &az2);
-        
-        
+
+
         // If the magnitude of the p1 x and/or y accelerometer values exceed ACC_THRESHOLD,
         // set the blob 0 velocities to be proportional to the accelerometer values.
-        // ***
-        
         // If in multi-player mode and the magnitude of the p2 x and/or y accelerometer values exceed ACC_THRESHOLD,
         // set the blob 0 velocities to be proportional to the accelerometer values.
-        // ***
-        
-        float time_step = .01; 
-        
+        // ****/
+        float scalFact = 1000*(5/3)/(blobs[PLAYER1].rad * 0.5);
+        if (abs(ax1) >= ACC_THRESHOLD)
+            blobs[PLAYER1].vx = ax1 * scalFact;
+        else
+            blobs[PLAYER1].vx = 0;
+
+        if (abs(ay1) >= ACC_THRESHOLD)
+            blobs[PLAYER1].vy = ay1 * scalFact;
+        else
+            blobs[PLAYER1].vy = 0;
+
+
         // Undraw the world bounding rectangle (use BGRD_COL).
         // ***
-        
+        rect_bl_x = 0 - blobs[PLAYER1].old_x;
+        rect_bl_y = 0 - blobs[PLAYER1].old_y;
+        rect_ur_x = WORLD_WIDTH  - blobs[PLAYER1].old_x;
+        rect_ur_y = WORLD_HEIGHT - blobs[PLAYER1].old_y;
+        GS_rectangle(sync, SCREEN_P1, rect_bl_x, rect_bl_y, rect_ur_x, rect_ur_y, BGRD_COL);
+        // multi-player mode
+        if (num_player == MULTI_PLAYER) {
+            rect_bl_x = 0 - blobs[PLAYER2].old_x;
+            rect_bl_y = 0 - blobs[PLAYER2].old_y;
+            rect_ur_x = WORLD_WIDTH  - blobs[PLAYER2].old_x;
+            rect_ur_y = WORLD_HEIGHT - blobs[PLAYER2].old_y;
+            GS_rectangle(sync, SCREEN_P2, rect_bl_x, rect_bl_y, rect_ur_x, rect_ur_y, BGRD_COL);
+        }
+
+
         // Loop over all blobs
         // ***
-            
-            // If the current blob is valid, or it was deleted in the last frame, (delete_now is true), then draw a background colored circle over
-            // the old position of the blob. (If delete_now is true, reset delete_now to false.)  
+        for (int i = 0; i < NUM_BLOBS; i++) {
             // ***
-            
+            if (blobs[i].delete_now == 1) {
+                blob_x = blobs[i].posx - blobs[PLAYER1].old_x;
+                blob_y = blobs[i].posy - blobs[PLAYER1].old_y;
+                GS_circle(sync, SCREEN_P1, blob_x, blob_y, blobs[i].rad, BGRD_COL);
+                if (num_player == MULTI_PLAYER) {
+                    blob_x = blobs[i].posx - blobs[PLAYER2].old_x;
+                    blob_y = blobs[i].posy - blobs[PLAYER2].old_y;
+                    GS_circle(sync, SCREEN_P2, blob_x, blob_y, blobs[i].rad, BGRD_COL);
+                }
+                blobs[i].delete_now = 0;
+            }
+
+
             // Use the blob positions and velocities, as well as the time_step to compute the new position of the blob.
             // ***
-            
-            // If the current blob is blob 0, iterate over all blobs and check if they are close enough to eat or be eaten. 
-            // In multi-player mode, if the player 0 blob is eaten, player 1 wins and vise versa.        
-            // If blob 0 eats some food, increment score1.   
+
+            blobs[i].old_x = blobs[i].posx;
+            blobs[i].old_y = blobs[i].posy;
+            blobs[i].posx += blobs[i].vx * time_step;
+            blobs[i].posy += blobs[i].vy * time_step;
+
+
+
+            // If the current blob is blob 0, iterate over all blobs and check if they are close enough to eat or be eaten.
+            // In multi-player mode, if the player 0 blob is eaten, player 1 wins and vise versa.
+            // If blob 0 eats some food, increment score1.
             // ***
-            
+            if (i == PLAYER1) {
+                for (int j = 1; j < NUM_BLOBS; j++) {
+                    if (j == PLAYER1)   continue;           // skip self
+                    if (blobs[j].valid == 0)    continue;   // skip invalid blobs
+                    // get dist between two blobs
+                    float dist2 = BLOB_dist2(blobs[i], blobs[j]);
+                    if (sqrt(dist2) < blobs[i].rad) {
+                        // danger zone, eat or be eaten
+                        if (blobs[i].rad > blobs[j].rad) {
+                            // P1 is bigger, so P1 eats
+                            blobs[j].valid = 0;     // eaten blob is now invalid
+                            blobs[i].rad = blobs[i].rad + 4;         // P1 inc. size and score
+                            score1++;               // ...
+                            playSound(hitTune);
+                            // undraw smaller sized blob
+                            // void GS_circle(GSYNC* gs, char screen, int x , int y , int radius, int color)
+                            GS_circle(sync, SCREEN_P1, 0, 0, (blobs[i].rad-1), BGRD_COL);
+                            if (num_player == MULTI_PLAYER) {
+                                blob_x = blobs[i].posx - blobs[PLAYER2].old_x;
+                                blob_y = blobs[i].posy - blobs[PLAYER2].old_y;
+                                // void GS_circle(GSYNC* gs, char screen, int x , int y , int radius, int color)
+                                GS_circle(sync, SCREEN_P2, blob_x, blob_y, (blobs[i].rad-1), BGRD_COL);
+                            }
+
+                            if (j == PLAYER2 && num_player == MULTI_PLAYER) {
+                                pc.printf("NOT HERE\n");
+                                game_over(WINNER_P1);       // P2 loses
+                                game_over(WINNER_P1);
+                                goto Play_again;   // To play again
+                            }
+                        } else if (blobs[i].rad < blobs[j].rad) {
+                            // P1 is smaller, so P1 is eaten
+                            blobs[i].valid = 0;     // eaten blob is now invalid
+                            game_over(WINNER_P2);   // P2 || AI wins
+                            game_over(WINNER_P1);
+                            goto Play_again;   // To play again
+                        }
+                    }
+                }
+            }
+
             // If the current blob is blob 1 and we are playing in multi-player mode, iterate over all blobs and check
             // if they are close enough to eat or be eaten. In multi-player mode, if the player 1 blob is eaten, player 0 wins and vise versa.
             // If blob1 eats some food, increment score 2.
             // ***
-            
-            // You have to implement this function.
-            // It should take in a pointer to a blob and constrain that blob to the world.
-            // More details in blob.cpp
-            //BLOB_constrain2world(&blobs[i]);           
-            
-        
+            if (i == PLAYER2) {
+                for (int j = 0; j < NUM_BLOBS; j++) {
+                    if (j == PLAYER2)   continue;           // skip self
+                    if (blobs[j].valid == 0)    continue;   // skip invalid blobs
+                    // get dist between two blobs
+                    float dist2 = BLOB_dist2(blobs[i], blobs[j]);
+                    if (sqrt(dist2) < blobs[i].rad) {
+                        if (blobs[i].rad > blobs[j].rad) {
+                            blobs[j].valid = 0;
+                            blobs[i].rad = blobs[i].rad + 4;
+                            score2++;
+                            playSound(hitTune);
+                            GS_circle(sync, SCREEN_P2, 0, 0, (blobs[i].rad-1), BGRD_COL);
+                            if (num_player == MULTI_PLAYER) {
+                                blob_x = blobs[i].posx - blobs[PLAYER1].old_x;
+                                blob_y = blobs[i].posy - blobs[PLAYER1].old_y;
+                                GS_circle(sync, SCREEN_P1, blob_x, blob_y, (blobs[i].rad-1), BGRD_COL);
+                            }
+
+                            if (j == PLAYER1 && num_player == MULTI_PLAYER) {
+                                game_over(WINNER_P2);
+                                game_over(WINNER_P1);
+                                goto Play_again;   // To play again
+                            }
+                        } else if (blobs[i].rad < blobs[j].rad) {
+                            blobs[i].valid = 0;
+                            if (j == PLAYER1 && num_player == MULTI_PLAYER) {
+                                game_over(WINNER_P1);
+                                game_over(WINNER_P1);
+                                goto Play_again;   // To play again
+                            }
+                        }
+                    }
+                }
+            }
+
+            BLOB_constrain2world(&blobs[i]);
+        }
+
         // Iterate over all blobs and draw them at their newly computed positions. Reference their positions to the player blobs.
         // That is, on screen 1, center the world on blob 0 and reference all blobs' position to that of blob 0.
         // On screen 2, center the world on blob 1 and reference all blobs' position tho that of blob 1.
         // ***
-        
-        
+        for (int i = 0; i < NUM_BLOBS; i++) {
+            if (blobs[i].valid == 1) {
+                blob_x = blobs[i].posx - blobs[PLAYER1].posx;
+                blob_y = blobs[i].posy - blobs[PLAYER1].posy;
+                GS_circle(sync, SCREEN_P1, blob_x, blob_y, blobs[i].rad, blobs[i].color);
+                if (num_player == MULTI_PLAYER) {
+                    blob_x = blobs[i].posx - blobs[PLAYER2].posx;
+                    blob_y = blobs[i].posy - blobs[PLAYER2].posy;
+                    GS_circle(sync, SCREEN_P2, blob_x, blob_y, blobs[i].rad, blobs[i].color);
+                }
+            }
+            blobs[i].delete_now = 1;
+        }
+
+
         // Redraw the world boundary rectangle.
         // ***
-        
+        rect_bl_x = 0 - blobs[PLAYER1].old_x;
+        rect_bl_y = 0 - blobs[PLAYER1].old_y;
+        rect_ur_x = WORLD_WIDTH  - blobs[PLAYER1].old_x;
+        rect_ur_y = WORLD_HEIGHT - blobs[PLAYER1].old_y;
+        GS_rectangle(sync, SCREEN_P1, rect_bl_x, rect_bl_y, rect_ur_x, rect_ur_y, BORDER_COL);
+        // multi-player mode
+        if (num_player == MULTI_PLAYER) {
+            rect_bl_x = 0 - blobs[PLAYER2].posx;
+            rect_bl_y = 0 - blobs[PLAYER2].posy;
+            rect_ur_x = WORLD_WIDTH  - blobs[PLAYER2].posx;
+            rect_ur_y = WORLD_HEIGHT - blobs[PLAYER2].posy;
+            GS_rectangle(sync, SCREEN_P2, rect_bl_x, rect_bl_y, rect_ur_x, rect_ur_y, BORDER_COL);
+        }
+
         // Update the screens by calling GS_update.
         GS_update(sync);
-        
-        // If a button on either side is pressed, the corresponding LED on the player 1 mbed will toggle.
-        // This is just for debug purposes, and to know that your button pushes are being registered.
+
         led1 = p1_buttons[0] ^ p2_buttons[0];
         led2 = p1_buttons[1] ^ p2_buttons[1];
         led3 = p1_buttons[2] ^ p2_buttons[2];
         led4 = p1_buttons[3] ^ p2_buttons[3];
-    } 
-    
+    }
+
 }
\ No newline at end of file
--- a/misc.h	Sun Mar 20 03:38:40 2016 +0000
+++ b/misc.h	Sat Mar 18 14:55:51 2017 +0000
@@ -1,25 +1,25 @@
 #ifndef MISC_H__
-#define MISC_H__
+    #define MISC_H__
 
-#define U_BUTTON 0
-#define R_BUTTON 1
-#define D_BUTTON 2
-#define L_BUTTON 3
+    #define U_BUTTON 0
+    #define R_BUTTON 1
+    #define D_BUTTON 2
+    #define L_BUTTON 3
 
-#define WINNER_P1   0
-#define WINNER_P2   1
-#define WINNER_TIE  2
+    #define WINNER_P1   0
+    #define WINNER_P2   1
+    #define WINNER_TIE  2
 
 
-// Feel free to adjust any of these values as you see fit.
-#define WORLD_WIDTH  256
-#define WORLD_HEIGHT 256
+    // Feel free to adjust any of these values as you see fit.
+    #define WORLD_WIDTH  512
+    #define WORLD_HEIGHT 512
 
-#define ACC_THRESHOLD 0.20
+    #define ACC_THRESHOLD 0.20
 
-#define BGRD_COL   0x0F0066
-#define FOOD_COL   0xFFFFFF
-#define P1_COL     0xBB0CE8
-#define P2_COL     0xFF0030
-#define BORDER_COL 0xFFFFFF
+    #define BGRD_COL   0x000000
+    #define FOOD_COL   0xFFFFFF
+    #define P1_COL     0xBB0CE8
+    #define P2_COL     0xFF0030
+    #define BORDER_COL 0xFFFFFF
 #endif //MISC_H__
\ No newline at end of file