Ransom Conant / Mbed 2 deprecated MbedPacman

Dependencies:   4DGL-uLCD-SE mbed wave_player

Fork of PacMan_Skeleton_unlock by ECE 2035 TA

Files at this revision

API Documentation at this revision

Comitter:
rconant6
Date:
Thu Mar 29 05:05:51 2018 +0000
Parent:
0:be33a1fad8c0
Commit message:
Adding files;

Changed in this revision

doubly_linked_list.cpp Show annotated file Show diff for this revision Revisions of this file
ghost.cpp Show annotated file Show diff for this revision Revisions of this file
ghost.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
pacman.cpp Show annotated file Show diff for this revision Revisions of this file
pacman.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doubly_linked_list.cpp	Thu Mar 29 05:05:51 2018 +0000
@@ -0,0 +1,251 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "doubly_linked_list.h"
+
+DLinkedList* create_dlinkedlist(void) {
+    DLinkedList* newList = (DLinkedList*)malloc(sizeof(DLinkedList));
+    newList->head = NULL;
+    newList->tail = NULL;
+    newList->current = NULL;
+    newList->size = 0;
+    return newList;
+}
+
+LLNode* create_llnode(void* data) {
+    LLNode* newNode = (LLNode*)malloc(sizeof(LLNode));
+    newNode->data = data;
+    newNode->previous = NULL;
+    newNode->next = NULL;
+    return newNode;    
+}
+
+void insertHead(DLinkedList* dLinkedList, void* data){
+  LLNode* newNode = create_llnode(data);
+  if(dLinkedList->head == NULL){
+    dLinkedList->size++;
+    dLinkedList->head = newNode;
+    dLinkedList->tail = newNode;
+  }else{
+    dLinkedList->size++;
+    newNode->next = dLinkedList->head;
+    (dLinkedList->head)->previous = newNode;
+    dLinkedList->head = newNode;
+  }
+}
+
+
+void insertTail(DLinkedList* dLinkedList, void* data){
+  LLNode* newNode = create_llnode(data);
+  if(dLinkedList->tail == NULL){
+    dLinkedList->size++;
+    dLinkedList->head = newNode;
+    dLinkedList->tail = newNode;
+  }else{
+    dLinkedList->size++;
+    newNode->previous = dLinkedList->tail;
+    (dLinkedList->tail)->next = newNode;
+    dLinkedList->tail = newNode;
+  }
+}
+
+int insertAfter(DLinkedList* dLinkedList, void* newData){
+  LLNode* newNode = create_llnode(newData);
+  if(dLinkedList->current == NULL)
+    return 0;
+  else{
+    if(dLinkedList->current == dLinkedList->tail){
+	insertTail(dLinkedList, newData);
+	return 1;
+    }
+    else{
+    	dLinkedList->size++;
+    	newNode->previous = dLinkedList->current;
+    	newNode->next = (dLinkedList->current)->next;
+   	((dLinkedList->current)->next)->previous = newNode;
+    	(dLinkedList->current)->next = newNode;
+	return 1;
+    }
+  }
+
+}
+
+
+int insertBefore(DLinkedList* dLinkedList, void* newData){
+  LLNode* newNode = create_llnode(newData);
+  if(dLinkedList->current == NULL)
+    return 0;
+  else{
+    if(dLinkedList->current == dLinkedList->head){
+	insertHead(dLinkedList, newData);
+	return 1;
+    }
+    else{
+    	dLinkedList->size++;
+    	newNode->next = dLinkedList->current;
+    	newNode->previous = (dLinkedList->current)->previous;
+   	((dLinkedList->current)->previous)->next = newNode;
+    	(dLinkedList->current)->previous = newNode;
+	return 1;
+    }
+  }
+
+}
+
+
+
+void* deleteBackward(DLinkedList* dLinkedList){
+  if(dLinkedList->current == NULL)
+	return NULL;
+  else{
+	if(dLinkedList->current == dLinkedList->head){
+		if((dLinkedList->current)->next == NULL){
+		   free(dLinkedList->head);
+		   dLinkedList->head = NULL;
+		   dLinkedList->tail = NULL;
+		   dLinkedList->current = NULL;
+		   return NULL;
+		}
+		else{
+		   dLinkedList->head = (dLinkedList->current)->next;
+		   free((dLinkedList->head)->previous);
+		   dLinkedList->current = NULL;
+		   return NULL;
+		}
+	}
+	else{
+		if(dLinkedList->current == dLinkedList->tail){
+		   dLinkedList->tail = (dLinkedList->current)->previous;
+		   (dLinkedList->tail)->next = NULL;
+		   free(dLinkedList->current);
+		   dLinkedList->current = dLinkedList->tail;
+		   return (dLinkedList->current)->data;	
+		}
+		else{
+		   ((dLinkedList->current)->next)->previous = (dLinkedList->current)->previous;
+		   ((dLinkedList->current)->previous)->next = (dLinkedList->current)->next;
+		   free(dLinkedList->current);
+		   dLinkedList->current = (dLinkedList->current)->previous;
+		   return (dLinkedList->current)->data;
+		}
+	}
+  }
+
+}
+
+
+
+void* deleteForward(DLinkedList* dLinkedList){
+  if(dLinkedList->current == NULL)
+	return NULL;
+  else{
+	if(dLinkedList->current == dLinkedList->tail){
+		if((dLinkedList->current)->previous == NULL){
+		   free(dLinkedList->tail);
+		   dLinkedList->head = NULL;
+		   dLinkedList->tail = NULL;
+		   dLinkedList->current = NULL;
+		   return NULL;
+		}
+		else{
+		   dLinkedList->tail = (dLinkedList->current)->previous;
+		   free((dLinkedList->tail)->next);
+		   dLinkedList->current = NULL;
+		   return NULL;
+		}
+	}
+	else{
+		if(dLinkedList->current == dLinkedList->head){
+		   dLinkedList->head = (dLinkedList->current)->next;
+		   (dLinkedList->head)->previous = NULL;
+		   free((dLinkedList->head)->previous);
+		   dLinkedList->current = dLinkedList->head;
+		   return (dLinkedList->current)->data;	
+		}
+		else{
+		   ((dLinkedList->current)->next)->previous = (dLinkedList->current)->previous;
+		   ((dLinkedList->current)->previous)->next = (dLinkedList->current)->next;
+		   free(dLinkedList->current);
+		   dLinkedList->current = (dLinkedList->current)->next;
+		   return (dLinkedList->current)->data;
+	
+		}
+	}
+  }
+}
+
+
+void destroyList(DLinkedList* dLinkedList){
+  if(dLinkedList->head != NULL){
+    getHead(dLinkedList);
+    while(deleteForward(dLinkedList)){};
+  }
+  free(dLinkedList);
+}
+
+
+
+void* getHead(DLinkedList* dLinkedList){
+  if (dLinkedList->head == NULL)
+	return NULL;
+  else{
+	dLinkedList->current = dLinkedList->head;
+	return (dLinkedList->head)->data;
+  }
+	
+	
+}
+
+
+
+void* getTail(DLinkedList* dLinkedList){
+  if (dLinkedList->tail == NULL)
+	return NULL;
+  else{
+	dLinkedList->current = dLinkedList->tail;
+	return (dLinkedList->tail)->data;
+  }
+
+}
+
+
+
+void* getCurrent(DLinkedList* dLinkedList){
+  if (dLinkedList->current == NULL)
+	return NULL;
+  else{
+	return (dLinkedList->current)->data;
+  }
+
+}
+
+
+
+void* getNext(DLinkedList* dLinkedList){
+  if (dLinkedList->current == NULL || (dLinkedList->current)->next == NULL)
+	return NULL;
+  else{
+	dLinkedList->current = (dLinkedList->current)->next;
+	return (dLinkedList->current)->data;
+  }
+
+}
+
+
+
+void* getPrevious(DLinkedList* dLinkedList){
+  if (dLinkedList->current == NULL|| (dLinkedList->current)->previous == NULL)
+	return NULL;
+  else{
+	dLinkedList->current = (dLinkedList->current)->previous;
+	return (dLinkedList->current)->data;
+  }
+
+}
+
+
+int getSize(DLinkedList* dLinkedList){
+  return dLinkedList->size;
+
+}
+
+
--- a/ghost.cpp	Fri Feb 24 17:33:27 2017 +0000
+++ b/ghost.cpp	Thu Mar 29 05:05:51 2018 +0000
@@ -148,24 +148,51 @@
 
 
 void ghost_init(void){
-    //Your code here
+    ghostDLL = create_dlinkedlist();
 }
 
 // Public functions
 void ghost_create(unsigned int blk_x, unsigned int blk_y, unsigned int color)
 {
-    //Your code here  
+    GHOST* newGhost = (GHOST*)malloc(sizeof(GHOST));
+    newGhost->x = blk_x;
+    newGhost->y = blk_y;
+    newGhost->color = color;
+    insertHead(ghostDLL, (void*)newGhost);
 }
 
 DLinkedList* get_ghost_list(void) {
     //Your code here
-    return NULL;
+    return ghostDLL;
 }
 
 void ghost_show(DLinkedList* list)
 {
     //Your code here
     //Functions like map_draw_grid, clean_blk, draw_ghost may be useful
+    GHOST* newGhost = (GHOST*)getHead(list);
+    while(newGhost){
+        draw_ghost(newGhost->x,newGhost->y,newGhost->color);
+        newGhost = (GHOST*)getNext(list);
+    }
+}
+
+int ghost_collision(DLinkedList* list, int pac_x, int pac_y, int invuln){
+    GHOST* newGhost = (GHOST*)getHead(list);
+    while(newGhost){
+        if(newGhost->x == pac_x && newGhost->y == pac_y){
+            if(invuln > 0){
+                newGhost->ghost_motion = GHOST_DIED;
+                return 10;
+            }
+            else{
+                return 1;
+            }
+        
+        }
+        newGhost = (GHOST*)getNext(list);
+    }
+    return 0;
 }
 
 void ghost_random_walk(void)
--- a/ghost.h	Fri Feb 24 17:33:27 2017 +0000
+++ b/ghost.h	Thu Mar 29 05:05:51 2018 +0000
@@ -53,7 +53,7 @@
     GHOST_MOTION ghost_motion;  ///< the motion of the ghost  
 } GHOST;
 
-//Initialize an empety doublely linked list
+//Initialize an empty doublely linked list
 void ghost_init(void);
 
 /** Create a ghost with given position and color. Then add to the ghost doublely linked list
@@ -75,6 +75,8 @@
 */
 DLinkedList* get_ghost_list(void);
 
+int ghost_collision(DLinkedList* list, int x, int y, int invuln);
+
 
 /** Extra Feature Function:
     Create a super ghost with given position and color. Then add to the super ghost doublely linked list
--- a/main.cpp	Fri Feb 24 17:33:27 2017 +0000
+++ b/main.cpp	Thu Mar 29 05:05:51 2018 +0000
@@ -38,6 +38,7 @@
 DigitalIn right_pb(p22); // push bottem
 DigitalIn up_pb(p23);    // push bottem
 DigitalIn down_pb(p24);  // push bottem
+DigitalOut myled(LED1);  // LED
 uLCD_4DGL uLCD(p9,p10,p11); // LCD (serial tx, serial rx, reset pin;)
 Serial pc(USBTX,USBRX);     // used by Accelerometer
 MMA8452 acc(p28, p27, 100000); // Accelerometer
@@ -64,13 +65,36 @@
     timer.start();
     tick = timer.read_ms();
     pre_tick = tick;
-    
+    int lives = 3, level = 0, invuln = 0, diff = 0;
     // Initialize the buttons        
     left_pb.mode(PullUp);  // The variable left_pb will be zero when the pushbutton for moving the player left is pressed    
     right_pb.mode(PullUp); // The variable rightt_pb will be zero when the pushbutton for moving the player right is pressed        
     up_pb.mode(PullUp);    //the variable fire_pb will be zero when the pushbutton for firing a missile is pressed
     down_pb.mode(PullUp);  //the variable fire_pb will be zero when the pushbutton for firing a missile is pressed
-    
+     
+    uLCD.cls();
+    uLCD.locate(0,0);
+    uLCD.printf("SELECT GAME MODE");
+    uLCD.locate(0,4);
+    uLCD.printf("1) EASY");
+    uLCD.locate(0,8);
+    uLCD.printf("2) MEDIUM");
+    uLCD.locate(0,12);
+    uLCD.printf("3) HARD");
+    while(1){  
+        if(down_pb == 0){
+            diff = 1;
+            break;
+        }
+        if(up_pb == 0){
+            diff = 2;
+            break;
+        }
+        if(right_pb == 0){
+            diff = 3;
+            break;
+        }
+    }   
     while(1)
     {
         /// [Example of the game control implementation]
@@ -78,9 +102,20 @@
         uLCD.cls();
         map_init();
         pacman_init(8,9); // Center of the map
+        
     
         //Your code here
         //Initiate & create & show the ghosts  
+        ghost_init();
+        ghost_create(8,7,0xFF0000);
+        if(diff > 0)
+            ghost_create(7,5,0x00FF00);
+        if(diff > 1)
+            ghost_create(9,5,0xFFFF00);
+        if(diff > 2)
+            ghost_create(8,5,0x00FFFF);
+        DLinkedList* ghostL = get_ghost_list();
+        ghost_show(ghostL);
     
         //[Demo of play sound file]
         //playSound("/sd/wavfiles/BUZZER.wav");
@@ -92,13 +127,91 @@
             /// 2. Implement the code to get user input and update the Pacman
             /// -[Hint] Implement the code to move Pacman. You could use either push-button or accelerometer. <br>
             /// The accelerometer's function readXYZGravity() might be useful. 
+            if(left_pb == 0 && right_pb == 0){
+                lives++;
+                level++;
+                break;
+            }
+            
+            if(up_pb == 0 && down_pb == 0){
+                lives = 0;
+            }
+            
+            double x,y,z;
+            acc.readXYZGravity(&x,&y,&z);
+            if(x > .4 || left_pb == 0)
+                pacman_set_action(PACMAN_HEADING_LEFT);
+            if(x < -.4 || right_pb == 0)
+                pacman_set_action(PACMAN_HEADING_RIGHT);
+            if(y > .4 || down_pb == 0)
+                pacman_set_action(PACMAN_HEADING_DOWN);
+            if(y < -.4 || up_pb == 0)
+                pacman_set_action(PACMAN_HEADING_UP);
+            
+            //uLCD.locate(0,1);
+            //uLCD.printf("lives:%d",lives);
+            
+            
+            GRID grid_info = map_get_grid_status(0,0);
+            uLCD.filled_rectangle(grid_info.x,grid_info.y-GRID_SIZE,grid_info.x+(8*GRID_SIZE),grid_info.y,BACKGROUND_COLOR);
+            int i = 0;
+            while(i < lives){
+                GRID grid_info = map_get_grid_status(i,0);
+                int screen_x = grid_info.x + GRID_RADIUS;
+                int screen_y = grid_info.y - GRID_RADIUS;
+                uLCD.filled_circle(screen_x, screen_y, GRID_RADIUS, PACMAN_COLOR);
+                uLCD.filled_rectangle(screen_x,screen_y-1,screen_x+GRID_SIZE,screen_y+1, BACKGROUND_COLOR);
+                i++;
+            }
+            
         
             if((tick-pre_tick)>500){ // Time step control
-                 pre_tick = tick;
-            
+                pre_tick = tick;
+                
+                
             /// 3. Update the Pacman on the screen
             /// -[Hint] You could update the position of Pacman here based on the input at step 2. <br>
-            
+                //pacman_update_position();
+                
+                invuln += pacman_update_position(level);
+                
+                if (invuln > 0){
+                     pacman_add_score(ghost_collision(ghostL, pacman_get_x(), pacman_get_y(), invuln));
+                     invuln -= 500;
+                     myled = 1;
+                }
+                else{
+                    if(ghost_collision(ghostL, pacman_get_x(), pacman_get_y(), invuln)){
+                        lives -= ghost_collision(ghostL, pacman_get_x(), pacman_get_y(), invuln);
+                        int j = 0;
+                        while(j<10){
+                            pacman_clear();
+                            pacman_init(8,9);
+                            j++;
+                        }
+                    }
+                    myled = 0;
+                }
+                
+                ghost_random_walk();
+                
+                if (invuln > 0){
+                    pacman_add_score(ghost_collision(ghostL, pacman_get_x(), pacman_get_y(), invuln));
+                }
+                else{
+                    if(ghost_collision(ghostL, pacman_get_x(), pacman_get_y(), invuln)){
+                        lives -= ghost_collision(ghostL, pacman_get_x(), pacman_get_y(), invuln);
+                        int j = 0;
+                        while(j<10){
+                            pacman_clear();
+                            pacman_init(8,9);
+                            j++;
+                        }
+                    }
+                }
+                
+                ghost_show(ghostL);
+
             }
         
         /// 4. Implement the code to check the end of game.
@@ -106,8 +219,26 @@
         /// One tricky scenario is that: Pacman is at grid (3,3) and is heading to (3,4), while the ghost is at grid (3,4) and is heading to (3,3).
         /// Either at time t or t+1, you will see that the Pacman and the ghost are not on the same grid.
         /// However, the Pacman should be caught by ghost with this movement.
+            if (lives == 0){
+                pacman_clear();
+                timer.stop();
+                uLCD.locate(9,0);
+                uLCD.printf("GAME OVER");
+                
+                if(up_pb == 0 && left_pb == 0){
+                    lives = 3;
+                    level = 0;
+                    timer.start();
+                    pacman_reset_score();
+                    break;
+                }
+            } 
         /// -[Hint] Check whether Pacman win the game <br>
-       
+            if (map_remaining_cookie() == 0){
+                lives++;
+                level++;
+                break;
+            }
         }
     }
 }
--- a/pacman.cpp	Fri Feb 24 17:33:27 2017 +0000
+++ b/pacman.cpp	Thu Mar 29 05:05:51 2018 +0000
@@ -26,8 +26,26 @@
 #include "pacman.h"
 
 PLAYER pacman;
-int score;
+
+
+int score, highscore;
 
+void pacman_add_score(int add){
+    score += add;
+}
+int pacman_get_x(void){
+    return pacman.grid_x;
+}
+
+int pacman_get_y(void){
+    return pacman.grid_y;
+}
+
+void pacman_reset_score(void){
+    score = 0;
+    uLCD.locate(0,0);
+    uLCD.printf("score:%d",score);
+}
 void pacman_init(int grid_x, int grid_y){
     pacman.motion = PACMAN_HEADING_RIGHT;
     pacman.status = PACMAN_WAIT_COMMAND;
@@ -35,8 +53,10 @@
     pacman.grid_y = grid_y;
     map_eat_cookie(grid_x,grid_y); //clear the cookie on the grid.
     pacman_draw();
-    score = 0;
+    uLCD.locate(0,0);
     uLCD.printf("score:%d",score);
+    uLCD.locate(9,1);
+    uLCD.printf("best:%d",highscore);
 }
 
 void pacman_draw(void){
@@ -81,10 +101,11 @@
     pacman.status = PACMAN_RUNNING;
 }
 
-void pacman_update_position(void){
+int pacman_update_position(int level){
     GRID next_grid_info;
     int x = pacman.grid_x;
     int y = pacman.grid_y;
+    int value = 0;
     if(pacman.status==PACMAN_RUNNING){
         switch(pacman.motion){
             case PACMAN_HEADING_UP:
@@ -126,12 +147,24 @@
             if(next_grid_info.status>=GRID_COOKIE){
                 map_eat_cookie(x,y);
                 score++;
-                if(next_grid_info.status==GRID_SUPER_COOKIE) //one super cookie worth 5 points
+                if(next_grid_info.status==GRID_SUPER_COOKIE){ //one super cookie worth 5 points
                     score+=4;
+                    
+                    if(level <= 4)
+                        value = (5000-(1000*level));
+                    else
+                        value = 1000;
+                        
+                }
                 uLCD.locate(0,0);
                 uLCD.printf("score:%d",score);
+                if(score > highscore)
+                    highscore = score;
+                uLCD.locate(9,1);
+                uLCD.printf("best:%d",highscore);
+               
             }
         }
     }
-        
+    return value; 
 }
\ No newline at end of file
--- a/pacman.h	Fri Feb 24 17:33:27 2017 +0000
+++ b/pacman.h	Thu Mar 29 05:05:51 2018 +0000
@@ -48,6 +48,15 @@
     PACMAN_STATUS status;  ///< See enum CITY_STATUS
 } PLAYER;
 
+/** Resets the score for pacman
+
+*/
+int pacman_get_x(void);
+int pacman_get_y(void);
+void pacman_add_score(int add);
+
+void pacman_reset_score(void);
+
 /** Initialize a pacman with given position. The default mostion is PACMAN_HEADING_RIGHT
     and status is PACMAN_WAIT_COMMAND. 
     @param blk_x The horizontal position in the grid.
@@ -68,7 +77,7 @@
 void pacman_set_action(PACMAN_MOTION motion);
 
 // Update the pacman's position in map
-void pacman_update_position(void);
+int pacman_update_position(int level);
 
 
 #endif
\ No newline at end of file