Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE mbed wave_player
Fork of PacMan_Skeleton_unlock by
Revision 1:fbda247b843b, committed 2018-03-29
- Comitter:
- rconant6
- Date:
- Thu Mar 29 05:05:51 2018 +0000
- Parent:
- 0:be33a1fad8c0
- Commit message:
- Adding files;
Changed in this revision
--- /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
