PACMAN Game Application - Final Review Report
PACMAN Game Application - Final Review Report
A PROJECT REPORT
Submitted By
June 2024
1
Sri Sivasubramaniya Nadar College of Engineering
(An Autonomous Institution, Affiliated to Anna University)
BONAFIDE CERTIFICATE
Date:
2
TABLE OF CONTENTS
Abstract: ................................................................................................................................... 4
Acknowledgements: ................................................................................................................. 5
1. Introduction: ........................................................................................................................ 6
2. Problem Statement: ............................................................................................................. 6
3. Further Exploration of the Problem Statement:............................................................... 7
4. Architecture Diagram: ........................................................................................................ 8
5. Structured Analysis Using Data Flow Diagram: .............................................................. 9
a. Level 0 DFD: ..................................................................................................................... 9
b. Level 1 DFD: ..................................................................................................................... 9
c. Level 2 DFD: ................................................................................................................... 10
6. Structure Charts derived from Data Flow Diagrams: ................................................... 11
7. Structured Analysis Using Activity Diagram: ................................................................. 12
8. Functions Flowcharts: ....................................................................................................... 14
9. Breadth First Search (BFS) Algorithm Code:................................................................. 24
10. Description of Each Module: .......................................................................................... 26
11. Implementation: ............................................................................................................... 33
a. Data Organization:......................................................................................................... 33
b. Libraries Used: ............................................................................................................... 35
c. User Interface Design: .................................................................................................... 36
i. Character info & Start screen: ................................................................................... 36
ii. Game Difficulty Selection: ......................................................................................... 36
iii. Loading Screen: ......................................................................................................... 37
iv. Gameplay Screen: ...................................................................................................... 37
v. Scatter Mode (Extra Feature): .................................................................................. 38
vi. Early Move Detection (Extra Feature): ................................................................... 38
viii. Gameplay Snapshots:.............................................................................................. 39
viii. Game-End Screens: ................................................................................................. 41
d. Platform used for Code Development: ......................................................................... 42
12. Observations with Respect to Society: ........................................................................... 42
13. Legal and Ethical Perspectives: ...................................................................................... 43
14. Limitations of Our Solution ............................................................................................ 43
15. Learning Outcomes: ........................................................................................................ 44
16. Timeline: ........................................................................................................................... 45
17. References:........................................................................................................................ 46
3
Abstract:
4
Acknowledgements:
5
1. Introduction:
Our PACMAN project, an exciting venture that combines the classic gameplay
of PACMAN with modern programming techniques.
This project is implemented in the C programming language and utilizes the
Raylib library for the graphical interface. Our PACMAN project is a faithful
recreation of the classic arcade game.
Players navigate PACMAN through a maze, collecting pellets, avoiding ghosts,
and aiming to clear the board. The project includes all the essential elements of
the original game, including the four unique ghosts and power pellets.
2. Problem Statement:
6
3. Further Exploration of the Problem Statement:
1. Scoring System: The scoring system has been changed in our game to help
motivate the players. For example, the points awarded for eating a ghost
increase for each consecutive ghost eaten while a single power pellet is
active.
a. We double the points for each consecutive ghost is eaten while a
single power pellet is active (that is, 9 seconds)
2. Sound Effects and Music: The game includes sound effects and music to
enhance the gaming experience. For example, a sound could play in the
loading screen, when Pacman eats a pellet and when Pacman eats a super
pellet, etc.
3. Graphics: The game includes animations for Pacman and the ghosts, and
the when the Pacman dies, a death animation takes place.
4. User Interface: The game includes a user interface that displays the ghost
information, points allotted to different pellets, current score, high score,
the number of lives remaining.
6. Ghost AI: Each ghost targets the Pacman differently, allowing the ghosts
to use different strategies to try to catch Pacman, such as trying to corner
him or cut off his escape routes.
7
4. Architecture Diagram:
Explanation:
An architecture diagram is a visual representation that depicts the high-level
structure of a system. It provides an overview of a system and its components,
and how those components interact with each other.
The User first inputs the moves using the keyboard into the Input module. Then
the move is validated and then executed. Then accordingly Pacman’s position is
8
updated. Then the movement data of Pacman is given as input to the Ghost AI
Database and the Points Database which store this data. They update the Ghosts’
Position and the Points (according to the number and kind of pellets collected)
respectively.
Then all this is given as input to the Game Status Database which stores these
data. Then updates Game status such as points, remaining lives, etc.
All these movements of the Pacman and Ghosts is displayed on the screen using
the Graphics Module (Raylib Library).
a. Level 0 DFD:
Explanation:
The user refers to the player interacting with the Pacman game interface.
This game is a one-player type. As the user opens the game file, he is
directly brought to the graphical user interface via the C program.
b. Level 1 DFD:
Explanation:
The user moves which is stored in the data cache. The program then has a
module which validates the move, another module in order to update the
position and one more that updates the game score. The game state is then
established, and the next move may be inputted by the player.
9
c. Level 2 DFD:
Explanation:
The module which validates the move, takes the move from the user as
input and first checks if the Pacman is still alive and then it checks if the
Pacman collides with the wall, if not then it sends the valid move to the
next module.
The module which updates the move, gets the output from Validate Move
Module as input, that is the valid move then checks the direction in which
Pacman should move, then increments the move counter in the given
direction, and then finally moves the Pacman in the given direction.
The module which updates the score, gets the output from Update Position
Module as input, then checks if the Pacman is in contact with pellets or
super pellets, and then checks is Pacman has collected enough super pellets
to eat ghosts and if yes, then it updates the control such that Pacman is
allowed to consume ghosts and rewards points accordingly to the number
of ghosts consumed. Then it updates the score by recording the number of
pellets and super pellets consumed and the points are calculated and
rewarded accordingly. Then the new score is displayed finally.
10
6. Structure Charts derived from Data Flow Diagrams:
Structure Chart partitions the system into black boxes (functionality of the
system is known to the users, but inner details are unknown).
a. Inputs are given to the black boxes and appropriate outputs are
generated.
b. Modules at the top level are called modules at low level.
c. Components are read from top to bottom and left to right.
d. When a module calls another, it views the called module as a black
box, passing the required parameters and receiving results.
There are 2 ways of converting a DFD into a structure chart: Transform Analysis,
and Transaction Analysis.
Transform Analysis is suited for systems with very few options, where a single
type of data processing occurs, while Transaction Analysis is suited for systems
where there are many possible options for the user to choose.
Since in our project, the user only gives input moves for the Pacman through the
keyboard, we thought Transform Analysis was the best.
The main Play Game module is split into 3 modules, one for validating the moves,
one for updating the positions, and one for updating score.
11
7. Structured Analysis Using Activity Diagram:
Explanation:
An activity diagram is essentially an elaborate control flow representation of
the program. In a game such as Pacman, such a diagram better states the
functionality as compared to a data flow diagram.
As displayed in the diagram, it contains all the sequences and possible
outcomes of each move carried out by the player - whether he encounters a maze
wall, collides with a ghost, the effects when he has eaten super pellet, etc.
12
If player gets hit by a ghost without having eaten a super pellet, the number of
lives is reduced by one and the game restarts, until player has lost three lives after
which the game concludes.
Score is kept track of based on Pacman’s consumption of pellets and ghosts
when powered up; when a score of 5000 is reached, Pacman gains back a life.
The game ends with a win when all pellets and super pellets present on the
game screen are consumed by Pacman.
Key Components:
1. Player Actions:
o Movement: The player controls Pac-Man, moving him up, down,
left, or right through the maze.
o Pellet Consumption: Pac-Man eats small pellets as he moves over
them.
o Super Pellet Consumption: When Pac-Man eats a super pellet, he
gains the ability to eat ghosts temporarily.
13
8. Functions Flowcharts:
void drawMaze(char maze[MAZE_HEIGHT][MAZE_WIDTH])
14
void updatePosition(Vector2 *pos, Direction *direction, Direction
*buffer_direction, char maze[MAZE_HEIGHT][MAZE_WIDTH], char Char)
15
16
17
void checkCollisionWithPellets(Vector2 pos, char
maze[MAZE_HEIGHT][MAZE_WIDTH], int *score, Sound *sound1, Sound
*sup_siren)
18
int avoidRotation(Vector2 *pos, Direction *direction,Direction
*buffer_direction, char maze[MAZE_HEIGHT][MAZE_WIDTH], char Char)
19
bool isValidPosition(Vector2Int position)
20
bool ghostcollisionpacman(Vector2 pos, Vector2Int ghostPos)
21
Vector2Int RandomPos(Vector2 pos, Vector2Int ghostPos)
22
int countPellets(char maze[MAZE_HEIGHT][MAZE_WIDTH])
23
9. Breadth First Search (BFS) Algorithm Code:
Vector2Int parent[MAZE_HEIGHT][MAZE_WIDTH];
memset(parent, -1, sizeof(parent));
queue[rear++] = start;
visited[start.row][start.col] = true;
*pathLength = length;
Vector2Int* reversedPath =
(Vector2Int*)malloc(sizeof(Vector2Int) * length);
for (int i = 0; i < length; i++) {
reversedPath[i] = path[length - 1 - i];
}
free(path);
free(queue);
return reversedPath;
}
Vector2Int directions[] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
for (int i = 0; i < 4; i++) {
Vector2Int next = {current.row + directions[i].row,
current.col + directions[i].col};
if (isValidPosition(next) && !visited[next.row][next.col])
{
queue[rear++] = next;
24
visited[next.row][next.col] = true;
parent[next.row][next.col] = current;
}
}
}
free(queue);
return NULL;
}
(*ghostMoveCounter)++;
if (*ghostMoveCounter >= speed) {
if (*path != NULL && *pathIndex < *pathLength) {
*ghostPos = (*path)[*pathIndex];
(*pathIndex)++;
}
*ghostMoveCounter = 0;
}
DrawTexture(ghost, ghostPos->col * 20, ghostPos->row * 20, WHITE);
}
25
10. Description of Each Module:
void drawMaze(char maze[MAZE_HEIGHT][MAZE_WIDTH])
This function is responsible for drawing the maze on the screen based on a 2D
array representation.
This function checks if the next position in the intended direction of movement
is valid (not blocked by a wall).
● Parameters:
o Vector2 pos - the current position of Pac-Man.
o Direction direction - the current movement direction of Pac-Man.
o Direction buffer_direction - the direction input buffered for the next
move.
o char maze - a 2D array representing the maze layout.
o char Char - the character representing a wall.
● Functionality: It checks if the next cell in the intended direction is a wall.
If it is, the buffered direction is reset to STOP. Returns 1 if there's a wall
and 0 otherwise.
void updatePosition(Vector2 *pos, Direction *direction, Direction
*buffer_direction, char maze[MAZE_HEIGHT][MAZE_WIDTH], char Char)
This function updates the position of Pac-Man based on the current and buffered
direction inputs.
● Parameters:
o Vector2 pos - the current position of Pac-Man.
o Direction direction - the current movement direction of Pac-Man.
o Direction buffer_direction - the direction input buffered for the next
move.
26
o char maze - a 2D array representing the maze layout.
o char Char - the character representing a wall.
● Functionality: It updates the position based on the direction while
checking for collisions with walls and wrapping around the maze
boundaries.
void checkCollisionWithPellets(Vector2 pos, char
maze[MAZE_HEIGHT][MAZE_WIDTH], int *score, Sound *sound1, Sound
*sup_siren)
This function checks if Pac-Man has collided with pellets or power pellets and
updates the score accordingly.
● Parameters:
o Vector2 pos - the current position of Pac-Man.
o char maze - a 2D array representing the maze layout.
o int score - a pointer to the current score.
o Sound sound1 - sound to play when a small pellet is eaten.
o Sound sup_siren - sound to play when a large pellet is eaten.
● Functionality: It checks the current cell for pellets (.) or power pellets (O),
updates the score, plays the appropriate sound, and removes the pellet from
the maze.
void drawPacman(Vector2 pos, Direction direction, Texture2D sprite)
● Parameters:
o Vector2 pos - the current position of Pac-Man.
o Direction direction - the current movement direction of Pac-Man.
o Texture2D sprite - the texture to use for drawing Pac-Man.
● Functionality: It adjusts the position, rotation, and draws Pac-Man based
on the current direction.
27
void drawlives(Texture2D spriteOpen)
This function checks whether a given position within a maze is valid and
accessible.
This function checks if the position of Pacman is the same as the position of a
ghost, indicating a collision.
● Parameters:
o Vector2 pos - A structure representing the position of Pac-Man in
floating-point coordinates (in pixels).
o Vector2Int ghostPos - A structure representing the position of a
ghost in integer coordinates (grid-based).
● Functionality: This function converts Pac-Man's floating-point position to
an integer grid position and checks if it matches the ghost's position. If they
match, it means Pac-Man has collided with the ghost.
28
Vector2Int* findShortestPath(Vector2Int start, Vector2Int target,
int* pathLength)
29
3. BFS Traversal:
a. The main BFS loop runs while there are positions in the queue.
b. The current position is dequeued and checked if it is the target
position. If it is, the path reconstruction begins.
c. For the current position, all possible adjacent positions (up, down,
left, right) are explored.
d. If an adjacent position is valid (within bounds, not a wall, and not
visited), it is enqueued, marked as visited, and its parent is set to the
current position.
4. Path Reconstruction:
a. When the target position is found, the path is reconstructed by
backtracking from the target position to the start position using the
parent map.
b. The path is stored in an array, and then reversed to get the path from
start to target.
5. Return Path:
a. The function returns the path and its length.
30
● Functionality: The function divides the x and y coordinates of the input
pos by 20 (the grid cell size) and casts the result to an integer. This
effectively converts the continuous floating-point position to discrete
integer grid coordinates.
● Local Variables
o Vector2Int distfright - Stores the distance vector between Pac-Man's
position and the randomly generated ghost position (ghostPos).
o Vector2Int distcorner - Stores the distance vector between Pac-
Man's position and each corner position in the corner array.
o Vector2Int corner[4] - An array containing four corner positions in
the maze grid.
● Functionality:
1. Generate Random Ghost Position
2. Calculate Distance from Pacman to Random Ghost Position
3. Check if Pacman is close to Ghost Random Position
4. If Pacman is close to Ghost Random Position, then check Distance
between the Pacman and the Corners
5. If the Pacman is close to a corner, the return another corner which is
not close to the Pacman
6. If all else fails, return a Random Corner
31
void moveGhost(Texture2D ghost, Vector2Int* ghostPos, Vector2Int
targetPosghost, int* ghostMoveCounter, Vector2Int** path, int*
pathIndex, int* pathLength, int speed)
● Functionality:
1. Path Calculation:
▪ Checks if there is no valid path (*path == NULL) or if the
ghost has reached the end of the current path (*pathIndex >=
*pathLength).
▪ If so, frees the memory allocated for the current path (if any)
and calculates a new shortest path (findShortestPath) from the
current ghost position (*ghostPos) to the target position
(targetPosghost).
2. Incrementing Movement Counter
3. Moving the Ghost
▪ Checks if the ghost move counter (*ghostMoveCounter) has
reached the specified speed (speed).
▪ If true, moves the ghost to the next position in the path
((*path)[*pathIndex]), increments the path index
(*pathIndex), and resets the move counter.
32
4. Drawing the Ghost
▪ Draws the ghost (ghost) at its current position (ghostPos->col
* 20, ghostPos->row * 20) on the screen.
The countPellets function is used to count the number of pellets (both regular
pellets and power pellets) in a maze.
● Parameters:
o char maze[MAZE_HEIGHT][MAZE_WIDTH] - A 2D array
representing the layout of the maze. Each cell in the maze can
contain various characters representing different elements like walls,
empty spaces, regular pellets ('.'), and power pellets ('O').
● Functionality: The function iterates over every cell in the maze to count
the total number of pellets present.
11. Implementation:
a. Data Organization:
33
typedef enum GameScreen {
DESCRIBE,
DIFFICULTY,
DIFF_SELECTION,
LOADING,
GAMEPLAY,
REMAININGLIVES,
GAMEOVER,
GAMEWIN
} GameScreen;
34
Text Files
● This code snippet is used to update the high score for a game based
on the current score.
● It determines which high score file to use based on the game level,
reads the existing high score from the file, and updates the file if the
current score is higher than the existing high score.
b. Libraries Used:
Raylib Library
The Raylib library is a simple and easy-to-use tool for creating graphical
applications, including games. In the context of making a Pac-Man game, Raylib
provides a set of functions that help handle graphics, input, and other game
development tasks such as:
● Initialization and Window Management
● Input Handling
● Drawing Textures and Shapes
● Animations
● Collision Detection
● Audio
● Game State Management
● Pathfinding and Ghost Movement
35
c. User Interface Design:
The first screen, listed as DESCRIBE in the GameScreen dataset, displays the
character info of the Ghosts (although all of them will not be included) as well as
info on the points scored by consuming the pellets – we wanted to recreate the
originality of the game. Then, a blinking “Press enter to start” prompt is
displayed.
36
The DESCRIBE screen leads to the difficulty selection screen, namely
DIFFICULTY and DIFF_SELECTION. Difficulty is increased by speeding up
the ghost. Once a choice is selected, a blinking “Press Enter to Start” message is
displayed.
Once the “Enter” key is pressed on the keyboard, the screen changes from
DIFF_SELECTION to LOADING. To simulate the game starting up, we
designed a loading screen which is synced up with the Pac-Man start up music –
the game is shown to be “loaded” as soon as the theme finishes playing.
The gameplay screen displays the maze, score and Pac-Man is spawned below
the ghost’s cage. From here, the player inputs movements to Pac-Man via the
arrow keys.
37
v. Scatter Mode (Extra Feature):
This screen shows the “Scatter Mode” feature - whereby the ghosts first move
to different positions before targeting Pacman; this occurs during the start of
the game and each time a life is lost.
Another extra feature we were able to include, mirroring the original Pac-Man
game, is the early move detection. That is, when travelling through a straight
tunnel path, if the player tries to move in another direction, Pac-Man will
automatically move into the next available tunnel in that direction.
In fig. A, if the player attempts to move right after crossing the tunnel, Pac-Man
will move by itself into the next available tunnel in right direction (fig. B).
38
Fig. a Fig. b
39
When Pacman eats a super pellet(red),
the ghosts become “frightened” and
move randomly away from Pacman. If
Pacman manages to eat a ghost, it
becomes a pair of eyes which travels
back to the ghost cage.
40
Suppose if the player loses a life, after the
death animation plays, this screen is
displayed.
If the player either collects all the pellets, or loses all his lives, the Game-End
screen is displayed accordingly. If the user decides to play again by pressing ‘Y’,
the game restarts at the same difficulty and the Gameplay starts immediately. By
pressing ‘N’, the user exits from the game window.
41
d. Platform used for Code Development:
We used Visual Studio Code for the Code Development and Google Drive for
Sharing the code among the teammates. We obtained the pictures, audio and the
maze structure for the Pacman game from Google.
Developing a Pacman game is not just about coding and gameplay mechanics, it
also intersects with broader societal aspects.
Beyond Gaming: When Pacman arrived in 1980, it transcended the realm of
video games. It became a cultural phenomenon, spawning merchandise, cartoons,
and even a hit song. The yellow circle with an insatiable appetite left an indelible
mark on popular culture.
Fashion and Literature: Pacman inspired a Martin Amis novel and even
influenced fashion collections. Its iconic imagery found its way into various
creative expressions.
Design Innovation: Pacman’s design innovation paved the way for impactful
gameplay. By exploring these fundamental techniques, game developers continue
to broaden the expressive possibilities in modern games.
Timeless Gameplay: Pacman’s enduring appeal lies in its timeless gameplay
mechanics. The pursuit of dots, evading ghosts, and gobbling power pellets
resonate with players across generations.
Arcade Boom: Before Pacman, games like Space Invaders dominated arcades
worldwide. These games fuelled the arcade boom, creating a social space for
gamers.
Nostalgia: Pacman evokes nostalgia for a simpler gaming era. Its iconic
characters and maze-chase gameplay evoke fond memories for those who grew
up playing it.
42
13. Legal and Ethical Perspectives:
Legal Perspective:
● Copyright Law: The original Pac-Man game is protected by copyright
law. This means that you cannot use the exact graphics, sounds, or
significant portions of the original game’s code without permission from
the copyright holder.
● Trademark Law: The name “Pac-Man” and the distinctive character
designs are likely protected by trademark law. Using these in your clone
could potentially infringe on these trademarks.
Ethical Perspective:
● Plagiarism: Even if it’s technically legal to create a clone, copying another
game’s design without adding anything new or unique could be considered
unethical, as it doesn’t respect the original creator’s effort and creativity.
● Learning vs. Profit: If you’re creating the clone purely for personal
learning and not distributing it or making money from it, this is generally
seen as more acceptable.
Performance:
While C and Raylib can offer good performance, creating a highly optimized
game can still be challenging and require a deep understanding of both the
language and the library.
43
Business Viability:
The game offers basic functionality with limited features. To be commercially
viable, consider adding features such as multiplayer modes, achievements, and
power-ups.
Lack of Modularity:
The code lacks modularity and separation of concerns. Functions are tightly
coupled, and there is significant repetition. For example, direction handling and
collision detection could be abstracted into separate functions to enhance
readability and maintainability.
44
16. Timeline:
45
17. References:
https://www.geeksforgeeks.org/unified-modeling-language-uml-activity-diagrams/
46