Java Documentation
Java Documentation
Table of Contents
1. Team Work
2. Introduction
3. Problem Description
4. Related Work
5. Proposed Approaches
6. Implementation Details
7. Experimental Results and Statistical Tests
8. Conclusions and Future Work
Declaration of Authorship
We hereby certify that the project report we are submitting is entirely our own
original team work, except where otherwise indicated. We are aware of the
University’s regulations concerning plagiarism, including those regulations con-
cerning disciplinary actions that may result from plagiarism. Any use of the
works of any other author, in any form, is properly acknowledged at their point
of use.
Parth Gajera, 1380680
Devansh Kumar, 1380664
Ekta Balhotra, 1379109
Nancy Balar, 1398122
1
1 Team Work
Team Members
1. Parth Gajera (1380680): Sorting out the main algorithm for the game
2. Devansh Kumar (1380664): Designing the Graphical User Interface
3. Ekta Balhotra (1379109): Database Integration and the final project docu-
mentation
4. Nancy Balar (1398122): Database Integration and final project documenta-
tion
We had our weekly Team Review Meetings every week on Thursdays either
in person or over Discord to check our progress in the project and weekly tasks
were assigned to each one of the team members and reviewed every week so
that the workload can be balanced All of us were constantly brainstorming for
the ideas of how we can develop this game in the best way possible regardless
of the department we were assigned to and all these ideas and approaches were
discussed in a very healthy way in the weekly Team Review Meetings
In case of problems, that we faced along the way, all the team members dis-
cussed them and came up with collective solutions which helped us overcome
the obstacles in the most optimal way
In the first week of our brainstorming, we decided to approach the problem
in the most basic way, which was by thinking about what exactly is the basic
idea behind the game. The basic idea behind the game was to find the shortest
distance between the apple and the snake. In the previous semesters, we have
learned a lot of Algorithms that can be used to find the shortest distance be-
tween the given two points some of which have also been discussed in the later
sections. So each one of us started implementing these Algorithms in order to
find the shortest distance in the most optimal way and the team member who
was successful in finding the most optimal way took the task further by involv-
ing Artificial Intelligence in it. So after the first week of brainstorming on the
right Algorithm, we finalized A* as our main approach for solving this game.
In the second week, we continued helping each other in sorting out the Algo-
rithm further while implementing Artificial Intelligence to it which was one of
the biggest challenges faced by us in the whole project. In the third week, one
of our teammates started working on the Graphical User Interface of the game,
because after the Algorithm it is the second most important thing while de-
signing this project because, in case of designing a game from the scratch, it is
very important that it looks interesting enough for the user to play it again and
again
2
In the fourth week, we were done with sorting out the Algorithm for single-
player and multiplayer but implementing Artificial Intelligence was still a work
in progress. Alongside, the Graphical User Interface was also designed and fi-
nalized for both the single-player and the multiplayer mode so considering the
second week of the project we were quite in a good position and highly moti-
vated to proceed further.
Since the concepts of how to make a Graphical User Interface were completely
new for us as beginners so we had to also learn all the concepts from the start
in order to implement them in our project. For building the Graphical User
Interface, we mainly focused on learning the concepts of Java Swing and AWT
which were quite interesting and challenging at the same time.
In the fifth week, we were almost done with sorting out our Algorithm with the
implementation of Artificial Intelligence too and now we thought of integrating
a Database into it in order to display and update the high scores. Again con-
sidering ourselves as beginners in regard to Java as a programming language,
we started learning the concepts of integrating a Database into Java which was
quite hard for us to get a hang of considering the increasing pressure due to
the passing time but we did it eventually and at this point, we were done with
almost everything that we needed for our project, the only thing that was left
was integrating everything together which was done in the sixth week.
In this week we particularly worked on integrating everything together and also
started working on our Java Documentation side by side. Apart from integrat-
ing things together, we also focused on the betterment of our Algorithm and
Graphical User Interface. We also introduced sound effects to our game in order
to make it even more interesting for the user to play.
No doubt the combined effort of our time helped us meet the deadlines on time,
but one another thing that actually helped us improve our project and quenched
our thirst to learn new things was the feedback talks that were organized for
us. Not only did it help us keep a check on time but the valuable feedback from
our professor helped us in improving our project a lot by showing us where we
were lacking and how we could improve it further and the idea of showing our
progress through an impromptu presentation also helped us boost our confi-
dence and prepared us well for our final presentation
2 Introduction
General Project Idea
Snake is one of the most popular games that all of us must have played at some
point of time in our childhood, so everyone is quite clear about what the basic
idea of the game is, still we would like to explain what the basic idea behind
this game is.
It includes a snake that moves around in a grid searching for an apple, and
each time it eats an apple, the player scores a point and the body of the snake
increases in its length.
3
The catch here is that the snake should not touch the sides of the grid or into
its own body otherwise the person will lose the game. It becomes interesting
to play because the length of the body increases as the player progresses in the
game.
Our project was not only designing this simple game but also introducing Arti-
ficial Intelligence to it, which means the snake will move on its own, finding the
shortest way possible to eat the apple
During our brainstorming sessions, we thought of introducing three modes in
our game namely, Single Player, Multiplayer, and Artificial Intelligence
In the single-player mode, as the name suggests, a single player will control
the snake in order to grab the apple increasing his score. This mode is not
implemented with Artificial Intelligence, hence the player himself will control
the snake, giving it directions by clicking on the suitable keys which were hard
coded.
In the multiplayer mode, two players play against each other, and the one with
the highest score in other words the user controlling the snake which has eaten
most of the apples wins the game. Since there were two players competing
against each other, so two snakes were required in this case
Lastly in the Artificial Intelligence mode, we integrated our Algorithm with Ar-
tificial Intelligence, which means there were two snakes on the panel but they
were not controlled by the user as in the earlier cases, rather they were moving
on their own according to the coded Algorithm and competing against each
other in finding the shortest way to the apple
Apart from the different modes, a high score list with a separate panel was also
included in the game, which at the end of the game displayed the score of the
player playing the game and also updated the high score list when needed
3 Problem Description
Finding the right Algorithm
1. Find the shortest distance (Continuously changing)
2. Considering Obstacles which are moving in every single Frame which being
refreshed
3. Array-List of Frame Pixels (2D)
4. Snake body(2D)
5. Apple Coordinate(2D)
6. Boundaries
7. To solve out weather neighbors are free as well as inside our Frame
8. Choose the best possible Neighbor
9. Array-List of Snakes, coordinate of apple are continuously changing
10. Developing own Datatype of neighbors and Snake Manhattan Distance
11. Give direction according to best possible neighbor of snake head
14. Create Objects of all classes and do with OOP Concept with help and class
4
and related method
The main problem faced while developing the Snake Game was to find the
shortest distance possible from snake’s head to the apple considering all the
obstacles which are there, such as the second snake, boundaries of our Game
Panel. So, we started by analyzing different algorithm based on path and cost
to reach target node, which includes:
For understanding the Algorithm, we first learned about the basic functionality
of A* Algorithm which includes:
Manhattan Distance: this is the basic shortest path, not considering any Ob-
stacles
To check the cost of that path: g(n)
To check the cost of the remaining path: h(n)
To pick out the minimum f(x) = g(n) + h(n) and explore that until we get the
5
targeted node
Last problem was to make a Class of neighbors which holds all attributes of
neighbors and that includes X-Coordinates, Y-Coordinates, Parents of that
neighbor and Manhattan Distance.
Learning AWT
Even though Swing has replaced AWT but we still had to use AWT to develop
GUI. It is platform independent therefore Components are displayed according
to the Operating system we are using.
The [Link].* provides classes for TextField, Label, TextArea but for develop-
ment of our game, mostly we used Swing, unless we wanted to use ActionLis-
tener.
Learning ActionListener
Whenever we created a button and it was clicked, it was detected by the class Ac-
tionListener. Officially the Interface that is imported is [Link];
It has only 1 method i.e public void actionPerformed
Learning [Link]
When we start the game, a background music is played, which, was a trouble
for us since we did not really have any experience handling Sounds in Java.
After Stack Overflowing a few hours and after reading through Java Oracle
website we found out import [Link].*;. This package provides an
interface for the capture, mixing digital audio.
But just learning about [Link] was not enough, because we were not able
to access the Audioclips just through that. Therefore we had to use import
[Link];. Since during the first 4 weeks, we did Kattis and other Exercise
Questions, we were able to learn about File management and were able to im-
plement file management without any difficulties.
Learning MyKeyAdapter
In our Game Project, we implemented 3 Modes of Gameplay, SINGLEPLAYER,
MULTIPLAYER, ARTIFICIAL INTELLIGENT. In order to implement single-
player and multiplayer, we had to give the user the access to keyboard and its
keys.
User had to guide the snake to the Apple themself, with the help of UP, DOWN,
6
LEFT, RIGHT keys. In order to do that the class MyKeyAdapter which ex-
tended KeyAdapter was used with the method public void keyPressed(KeyEvent
e). This method is implemented under @Override. In order to understand it
better a code snippet is added below.
In terms of multiplayer, the basic logic of working of the both the snakes was
same. The only different thing was. there were more switch([Link]())
cases.
Database
7
had to use the concept of JDBC Driver (From the Java programming language,
there is global data access through the Java Database Connectivity (JDBC)
API. You can access practically any data source, including relational databases,
spreadsheets, and flat files, using the JDBC API). In order to connect to the
Database we have to type in the URL (Database URL) which includes IP ad-
dress and port number. After building the connection the next issue was to
know the methods that are used to call the functions of the database because
the connection established between the Java code and the Database was of no
use to us if we did not know how to call the functions of our Database in our
main code. After following all the above steps, a connection was formed with
the Database and with the help of SQL query statements, we were able to get
the required out on the “Scoreboard” Panel. The next hurdle that we were
facing after sorting out the connection issue with the main code was in the case
when a single player with the same name was added to the list of “Scoreboard”.
When we were trying to add the Player with the same name, the new entry
was showing again as a separate row in Database. But as per requirements, we
wanted it to update the score instead of creating a new entry. For this issue
we tried to figure out a solution for it. We created if – else conditional loop to
check whether the Player with the same name already exist in the database or
not. If the player already exists in the Database, the query will try to grasp
the score of that Player, and it will try to update it with new score. At the end
there was an error, which was highlighting the Result Set (The result set is an
object that symbolizes a collection of data that is typically returned in response
to a query from a data source. The requested data components are held in rows
and columns of the result set, which can be moved around using the cursor.).
I was unaware about the situation that one needs to close the Resultset and
Statement separately although the Connection is closed afterwards. For exam-
ple, if for some reason you are using a ”primitive” type of database pooling and
you call “[Link]()”, the connection will be returned to the pool and
the ResultSet/Statement will never be closed and then you will run into many
different new problems! So you can’t always count on “[Link]()” to
clean up. It is wise to always explicitly close ResultSets, Statements and Con-
nections when you are finished with them as the implementation of close could
vary between database drivers.
While integrating the Graphical User Interface with the Database, the major
problem that we faced was not knowing where to call the Database class in
the main code, due to this we were having trouble, displaying the scores of the
players because as a result of this problem, the functions of the database were
not being called properly and hence there were a lot of errors encountered while
displaying the score
Another hurdle that we faced, while we were integrating this Database with the
Graphical User Interface in our code was fetching the data from the database
8
and showing the desired output on our GUI instead of the terminal. For in-
stance, if a player played this game, at the end his high score must be stored
as an entry along with his name in our database, and then this entry must be
shown as an output on the Graphical User Interface of our Score Board Panel
4 Related Work
Since we all were beginners in Java, even after understanding java SWING,
AWT, ACTIONLISTENER, we were not good enough to start making a snake
game already.
TicTacToe
In order to gain some experience about using swing and making GUI, we started
with TICTACTOE game. After gaining some more experience with java Swing
we started with snake AI.
We learned about the different types of Layouts, that a Panel has, and how to
align the containers that we add on the Panel and how to customise them. A
code snippet is shared below, that clears how the containers are added to the
Panel. And how they are customized.
9
We started with a simple UI which was made just using JFrame, JPanel
and some of the other classes from Swing package. Even after developing this
application we were not able to develop the snake Game. Not only that, it was
still difficult for us, to even create a snake. Creating a snake happened with
the help of Graphics class and with the help of JPanel class, which has a public
void paintComponent method, which can @Overriden. With the help of this
method, we were able to initiate the drawing process of the Snake, Background,
and apple the spawn on the screen at random location.
So as we have already mentioned in the above sections, the basic idea of this
game is, that the snake finds the shortest path to reach the apple every time
the coordinates of the apple change since they are generated randomly.
In order to find the shortest path, we came across three suitable algorithms
which we could implement in our game. These Algorithms have been discussed
below:
10
In this algorithm, the root node is the head of the snake, the root checks for the
available neighboring nodes which are nothing else but positions on the grid at
the present depth before going deeper. It terminates when the fruit is found
It is obviously better than the first discussed algorithm since the algorithm is
finding the coordinates of the apple as it goes deeper, but it still has a major
disadvantage that is, the length of the snake, which increases after each eaten
apple is not taken into consideration, this means that the algorithm works per-
fectly well until the increasing length of the snake interrupts the shortest path
to the apple
3. Dijkstra Algorithm
A graph search algorithm called Dijkstra’s algorithm determines the shortest
route between two nodes in a graph. By determining the shortest route be-
tween the snake’s current location and the apple’s location, you may use it to
make the snake go in the direction of the apple in a game of Snake. At the
beginning of the Project we tried to solve the path according to this algorithm.
The Dijkstra algorithm for the Snake game operates as follows:
Create a priority queue, and then add the snake’s beginning location to it.
The beginning point should be noted as visited.
While there are still items in the priority queue:
a. Remove the node from the queue with the lowest priority.
b. Verify that the apple is the dequeued node. If so, we’ve discovered the short-
est route.
c. Adding its unvisited neighbors to the queue and marking them as visited if
the dequeued node is not the apple. Based on the distance to the current node,
update their distances.
Using the data kept in the nodes, the shortest route may be found from the
apple to the beginning place. The snake will use this algorithm to move as
swiftly as possible toward the apple while avoiding barriers like walls or its own
body.
11
To better comprehend how Dijkstra’s algorithm functions for the game of Snake,
let’s look at an illustration.
Think about a 5x5 2D grid where the snake starts at location (0, 0) and the
apple is at place (3, 3). Each cell in the grid is a node in a graph that represents
the grid.
1. Create a priority queue from scratch and add the snake’s beginning point (0,
0) to it with 0. The number of steps needed to get to the food is represented
by this distance.
2. The beginning point should be noted as visited.
3. While there are still items in the priority queue:
a. Remove the node from the queue with the lowest priority (and shortest dis-
tance). It is in this instance (0, 0).
b. Verify that the apple is the dequeued node (3, 3). If so, we’ve discovered the
shortest route.
c. Add its unvisited neighbors to the queue and mark them as visited if the
dequeued node is not the apple (3, 3). Depending on the distance to the current
node, adjust their distances (0, 0). For instance, (0, 0)’s neighbors are (0, 1),
(1, 0), and (1, 1). These neighbors’ separations have been changed to 1.
d. Continue performing steps 3a to 3c until the apple is located or the line is
finished.
Using the data kept in the nodes, the shortest path can be found from the apple
(3, 3) to the beginning place (0, 0). The ultimate route would resemble this:
(0, 0) -¿ (0, 1) -¿ (0, 2) -¿ (0, 3) -¿ (1, 3) -¿ (2, 3) -¿ (3, 3).
In a game of Snake, this is how Dijkstra’s algorithm determines the shortest
path. The algorithm makes sure the snake travels as quickly as possible to the
apple while avoiding barriers like walls or its own body.
This could be illustrated with the help of the following diagram:
12
4. A* Algorithm
A* is a graph search technique that calculates the shortest path between two
nodes in a network while taking into account both the anticipated distance from
the starting node and the actual distance to the target node.
Here is how the Snake game’s A* algorithm operates:
Create an open list (priority queue) from scratch and add the snake’s beginning
location to it. Nodes that have not yet been visited are found on the open list.
To determine the starting place’s F-value, which is the sum of the predicted
distance to the target node and the distance from the starting node (G-value),
mark the starting point as visited (H-value). Based on the cost of moving from
the starting node to the current node, the G-value calculates the actual distance
from the starting node. The predicted distance to the target node, known as the
H-value, is determined using a heuristic algorithm. The Manhattan distance,
which is the total of the distances between the current node and the target node
in both the horizontal and vertical directions, is a typical heuristic function for
a Snake game.
While there are items on the open list:
a. Dequeue the node from the open list with the lowest F-value and designate
13
it as the current node.
b. Verify that the node in question is the food. If so, we’ve discovered the
shortest route.
c. Adding the node’s unvisited neighbors to the open list if the current node is
not the food. They then calculate their F-values by multiplying their G-value
by their H-value, which is updated dependent on the cost of moving from their
present node to the neighboring node.
d. Keep going back to steps 3a through 3c until the meal is located or the open
list is finished.
In a game of Snake, this is how the A* algorithm determines the shortest path.
The F-value, which combines a node’s distance from the starting node and its
predicted distance to the target node, determines which nodes are given the
highest priority by the A* algorithm. This makes it possible for the algorithm
to more quickly and effectively determine the shortest route to the foods.
Let’s take a simple example of a Snake game with a 3x3 grid, where the snake
starts at (1,1) and the food is at (3,3). Here’s how the A* algorithm would
work:
Initialize the open list with the starting position of the snake at (1,1) and mark
it as visited. The F-value of the starting node is calculated as F = G + H,
where G = 0 (the distance from the starting node) and H = Manhattan dis-
tance between (1,1) and (3,3) = 2. So, F = 0 + 2 = 2.
Dequeue the node with the lowest F-value from the open list, which is the start-
ing node (1,1), and mark it as the current node.
Check if the current node is the food. Since it is not, add its unvisited neighbors
to the open list and calculate their F-values. For example, the neighbors of (1,1)
are (1,2), (2,1), and (2,2). The G-value of (1,2) is 1 (the movement cost from
(1,1) to (1,2)), H-value is 1 (the Manhattan distance between (1,2) and (3,3)),
and F-value is 2. The G-value of (2,1) is 1, H-value is 2, and F-value is 3. The
G-value of (2,2) is 2, H-value is 1, and F-value is 3.
Dequeue the node with the lowest F-value, which is (1,2), and mark it as the
current node. Check if the current node is the food. Since it is not, add its
unvisited neighbors to the open list and calculate their F-values. For example,
the neighbors of (1,2) are (1,3) and (2,2). The G-value of (1,3) is 2, H-value is
0, and F-value is 2. The G-value of (2,2) is 2, H-value is 1, and F-value is 3.
Dequeue the node with the lowest F-value, which is (1,3), and check if the cur-
rent node is the food. Since it is the food, we have found the shortest path,
which is (1,1) -¿ (1,2) -¿ (1,3).
Our project is mostly based on A* star algorithm. We made 3 lists for sepa-
rating the paths that has been calculated with the help of the algorithm. The
detailed description of the code is represented in the Algorithm description sec-
tion of this documentation.
14
nodes, though.
The traditional shortest-path finding algorithm, Dijkstra’s algorithm ranks nodes
purely by their distance from the starting node. It is a breadth-first search
method that investigates every path that could lead from the starting node and
modifies the distances between them as it proceeds.
In contrast, the A* method outperforms Dijkstra’s algorithm. Nodes are ranked
according on their proximity to the target node and their anticipated distance
from the starting node. A heuristic function, which is a gauge of how close a
node is to the target node, is used to determine the estimated distance. A* is
quicker and more effective than Dijkstra’s algorithm because it can prioritize
nodes that are more likely to go to the target node thanks to this heuristic
function.
The primary distinction between Dijkstra’s algorithm and A* algorithm in a
Snake game is how they select the route to the food. Dijkstra’s algorithm will
investigate every route that could lead to the food, but A* algorithm will give
priority to routes that are more likely to do so. As a result, A* algorithm lo-
cates the shortest path to the food quicker and more effectively than Dijkstra’s
method.
The A* algorithm is generally preferred due to its speed and efficiency in finding
the shortest path based on both the distance from the starting node and the
estimated distance to the target node, even though Dijkstra’s algorithm and A*
algorithm can both be used to find the shortest path in a Snake game.
5 Proposed Approaches
Algorithms
[Link] coding the directions of the Snake with respect to the Co-
ordinates of the Apple
While developing the GUI in the initial phase of the Project, we thought of
a simple Algorithm, that could make snake move without the help of the player
using the keyboard, but since it was a very basic algorithm it could only make
the snake move, and if the head of the snake bit its tail, it was not able to detect
that, it was a fault and. Game should be over by them.
Pseudocode 1
Obviously, this algorithm was not enough to make snake move without making
pass through its body, which in scenario would kill it. So we worked for a week
on improving this algorithm and we got a pretty good working algorithm, which
was able to make snake move towards the apple successfully without getting out
with an avg. score of 30 Apples every game.
15
Pseudocode 2
Obviously, this algorithm was not enough to make snake move without making
pass through its body, which in scenario would kill it. So we worked for a week
on improving this algorithm and we got a pretty good working algorithm, which
was able to make snake move towards the apple successfully without getting out
with an avg. score of 30 Apples every game.
16
The code given above, is an part of the whole Algorithm that we developed in
the initial weeks. This part explains, for example the apple has spawned on
the co-ordinates that are above the snake. The direction in which the snake is
moving at that movement is determined and if it not ’D’. Neighbors of the head
of the snake will be checked, in which if the coordinate above the head of the
snake is free, then snake will change its direction towards the Apple i.e. ‘U’. If
the UNIT BLOCK above the snake’s head is blocked either with the Snake’s
other Body parts or by the 2nd snake, then the direction will be either ‘L’ or
‘R’.
In order choose between these two directions, same process is followed again.
Same is the case with the part of the code shown below. If the apple has spawned
on the co-ordinates that are to the ‘LEFT’ of the snake. The direction in which
the snake is moving at that movement is determined and if it not ‘R’. Neighbors
of the head of the snake will be checked, in which if the coordinate on the left of
the snake’s head is free, then snake will change its direction towards the Apple
i.e. ‘L’. If the UNIT BLOCK to the left of snake’s head is blocked either with
the Snake’s other Body parts or by the 2nd snake, then the direction will be
either ‘U’ or ‘D’.
In order choose between these two directions, same process is followed again.
This is then repeated for both the cases that are not listed above i.e., if the
Apple has spawned to the RIGHT or to the SOUTH of the snakes head
17
Dijkstra Algorithm
This code implements the Dijkstra algorithm for finding the shortest path in
a [Link] algorithm uses a priority queue (implemented as a Java Priori-
tyQueue) to store the vertices of the graph based on their distance from the
source vertex. In the first line, the PriorityQueue is initialized with a custom
comparator that compares vertices based on their distance property. The source
vertex’s distance property is set to 0, and the source vertex is added to the pri-
ority queue. The while loop continues until the priority queue is empty. In each
iteration of the loop, the vertex with the smallest distance is extracted from the
priority queue using the poll() method. If the extracted vertex has not been
processed yet (as indicated by its processed property), it is marked as processed
and its neighbors’ distances are updated if a shorter path to them is found.
The updated distances cause the vertices’ positions in the priority queue to be
re-ordered, so the next iteration of the loop will extract the vertex with the new
smallest distance. This process continues until all vertices have been processed,
and the final distances represent the shortest path from the source vertex to all
other vertices in the graph.
18
A* Algorithm
This code is implementing a search algorithm A*, to find a path from a starting
position to an end position (represented by the coordinates of an apple) in a 2D
grid. It uses two lists, ”open” and ”close”, to keep track of the nodes that have
been visited and the nodes that need to be visited. The algorithm starts with
the node in ”open” with the lowest distance to the end position and adds its
neighbors to ”open”. If a neighbor is the end position, the loop stops. If not,
the current node is added to ”close” and removed from ”open”. The algorithm
repeats until the end position is found or there are no more nodes in ”open”.
Input/Output Format
In regard to our game, as mentioned earlier, three modes have been introduced
in our game, single player, multiplayer, and Artificial Intelligence. For each of
the modes, a separate Graphical User Interface has been designed so that the
user can distinguish between them.
In the case of single-player mode and multiplayer mode, we have included text
fields by using the concepts of Java Swing. These text fields act as input for
our user where he enters his name, in the case of multiplayer mode two users
are present so there are two text fields for each of the users to enter their name.
In the case of Artificial Intelligence, no text fields have been included since it is
not controlled by the user, so there is no need to enter their names.
As an output, we have designed a separate Graphical User Interface for display-
ing our high scores.
19
In the single-player mode, the maximum number of apples eaten by the snake
is shown at the end as the score, the user got while playing the game, as an
output.
In the multiplayer mode and the Artificial Intelligence mode, the user (multi-
player mode) or the snake (Artificial Intelligence mode), the maximum number
of apples eaten by the snake is shown as an output on the high score panel
This high score panel gets updated each time with a new high score as the user
plays the game again and again, due to the integrated database, as hence we
have an updated version of the high score panel each time the user plays the
game
Not only the updated high score, but the user also gets to see the list of the
other users who have played this game till now along with their high scores, be-
cause all the names that are taken as input from the users and the high scores
that are calculated, as the user reaches the end of the game, are stored in the
connected database and then shown as an output
6 Implementation Details
1. Algorithm
To Implement an Algorithm we started step by step to construct our code and
that steps includes:
SnakeBody:
As for start, main task in Algorithm was creating a Datatype which shows the
basic functionality and requirements of Snake
20
This code defines a class Snakebody that has two instance variables snake x coordinate
and snake y coordinate that represent the x and y coordinates of a snake body
part in a game. The class has a constructor that takes in two integer arguments
to initialize these values and two getter methods to access these values.
NeighborsClass:
As an A* Algorithm, neighbor plays a critical role to find out the shortest path
from Snake head to Apple Coordinates.
21
The neighbors2 class is a simple class that contains two variables, neighbors x
and neighbors y, that represent the x and y coordinates of a neighbor. It also
has an variable distance to store the distance between the current node and
the neighbor node, as well as total free neighbors, which is the number of free
neighbors.
Additionally, the class has two variables, parent x and parent y, to store the x
and y coordinates of the parent node. The class has two constructors. The first
constructor takes in two parameters, neighbors x and neighbors y, and sets the
variables with the same name to these values.
The second constructor takes in five parameters, neighbors x, neighbors y, dis-
tance, parent x, and parent y, and sets the variables with the same name to
these values. The class also has a set of getter methods to retrieve the values of
each variable.
22
ArrayList: for open and close List:
OpenList:
Here comes all neighbors which still needs to be process
CloseList:
Once neighbor which is in OpenList gets processed, then it will add in CloseList
Manhattan Distance:
It’s a shortest distance from one point to another.
Manhattan Distance =| x 1 −x 2 | + | y 1 −y 2 |
23
This is a method is free that takes a neighbors2 object n as its argument. The
method checks if the location represented by the neighbors2 object is free i.e.
not occupied by a snake. To do this, the method checks if the x and y coordi-
nate of the neighbors2 object is not present in two separate lists of Snakebody
objects called snakes and snakes2.
The method increments the value of a by 1 if the x and y coordinate of the
neighbors2 object is found in the list snakes. Similarly, the method increments
the value of a2 by 1 if the x and y coordinate of the neighbors2 object is found
in the list snakes2.
Finally, the method returns true if both a and a2 are equal to 0, meaning the
location is not occupied by any snake, and returns false otherwise, meaning the
location is occupied.
24
is in closeList or not:
This code is checking if a given neighbors2 object n is not in the list close. The
close list is used to store the coordinates of neighbors that have already been
processed. The function returns true if n is not in close, and false otherwise.
The function loops over all elements in the close list, and for each element it
checks if the neighbors x and neighbors y values of n are equal to the corre-
sponding values of the current element in the loop. If they are equal, it means
that n is already in close, so the function returns false. If the loop finishes
without finding a matching element, the function returns true.
25
If c is not equal to 0, the method returns true as the next position of n is an
apple. Otherwise, the method returns false.
Final Implementation
This is a constructor for the A Star Algorithm class. It initializes the member
variables with the values passed as parameters. The member variables being
initialized are:
Snakes : ArrayList of first snake
snakes2 : ArrayList of Second snake
apple x coordinate
apple y coordinate
snake x : Head of Snake(X-Coordinate)
snake y : Head of Snake (Y-Coordinate)
number of apple
If next neighbor is apple, then algorithm will simply return the coordinates of
Apple and accordingly direction will be chosen.
If that’s not the Case, then algorithm will continue until it will not find the
coordinate of Apple or until it will not reach to Apple.
26
If next neighbor is not an Apple, then Head of a Snake will add to OpenList
and visit all neighbor of SnakeHead.
This code is part of a loop that is finding the node with the smallest distance
value in a list of nodes called ”open”. The loop iterates through all elements
in the ”open” list. For each iteration, it checks if the distance value of the
current node is smaller than the current maximum value stored in the ”max”
variable. If it is, then the ”max” value is updated to the current distance value
and the index of the node is stored in ”current i”. After the loop, ”current i”
will contain the index of the node with the smallest distance in the ”open” list.
27
For Loop will iterate for 4 times: UP, DOWN, LEFT, RIGHT. And create an
Object of class ‘neighbors2’ n and set a parent of that Object to a current neigh-
bors: ‘[Link] x()’ and ‘[Link] y()’.
If n is a coordinate of apple than flag value will became false and continue to
next while loop, where while loop got terminated.
If not so, then n will check if the node is not in the close list, is a free, and is a
neighbor, and if all conditions are met, it adds the n to the open list.
This code is checking if the current position of the snake is present in the close
list. If it is, the code retrieves the dir x and dir y values for the position from
the close list and calls the direction call function with these values.
The close list is used to keep track of the positions that the snake has already
visited, while the open list is used to keep track of the positions that are yet
to be visited. The dir x and dir y values represent the direction that the snake
should take to reach its next position.
The code uses a loop to iterate over the close list in reverse order (from the end
to the start). For each position in the close list, the code checks if the current
position of the snake matches the position stored in the list. If a match is found,
the code retrieves the dir x and dir y values for that position and calls the di-
rection call function with these values. The loop is exited once a match is found.
28
This code is a function called ”direction call”. Given two input parameters x
and y, it returns a character that represents a direction based on the relative
positions of the current snake’s position and the target position. If x is equal
to snake x + 25 and y is equal to snake y, it returns the character ’R’ which
means the snake should move right. If x is equal to snake x - 25 and y is equal
to snake y, it returns the character ’L’ which means the snake should move left.
If x is equal to snake x and y is equal to snake y + 25, it returns the character
’D’ which means the snake should move down. If none of the above conditions
are met, it returns the character ’U’ which means the snake should move up.
Final Algorithm
29
30
31
32
33
2. GUI
MenuBar
Before User wants to play the game. They had to select, which mode they
wanted to play. We have included 3 different modes to play this game. Single
player
• Single Player
• Multiplayer
• AI
In order to make that happen a class MenuBar was created which extends JPanel
and implements ActionListener. which used classes like JPanel JFrame Image-
Icon and JButton to create the user interface that we created. A code snippet
and the UI is shared below.
In order to give more immersive experience to the user, we also used classes
like Clip AudioInputStream to add background game music for the game.
34
For user to choose which he mode he wanted to play, he has to click one on
the 3 above listed buttons. If those buttons were just implemented without
@Overriden actionPerformed method, it would not have been possible to start
the gameplay.
A code snippet is shared below, to explain how and which buttons respond and
which way.
35
Game mode
Single player, multi player and artificial intelligent mode of the game work on
the same GUI concept where startPanelSingle extends JFrame and implements
ActionListener.
This class is used to get user Input, before user starts playing game, they are
asked to enter their name/names, so that their scores can be updated in the
Databases. Code snippet and GUI are explained and displayed below.
36
The UIs displayed above, take names from the user and then store them with
the at the end reached score in the Database.
This is a Java code for a graphical user interface class ”startPanelSingle” which
extends JFrame and implements ActionListener. The class creates a JFrame
window with a JLabel, a JTextField, a JComboBox, a JButton and a JPanel.
The window has a size of 600x200, title ”Snake MultiPlayer”, is not resizable,
centered and set to close on exit. The JPanel uses null layout and has a preferred
size of 500x200.
The JButton has an action listener which disposes the current window and
opens a new window ”SinglePlayer” when clicked. The JLabel displays the text
”name : ”, the JTextField allows the user to enter a name and the JComboBox
displays a list of color choices. The components are positioned on the JPanel
using setBounds method.
This is better understood with the snippet listed below.
37
After taking the name/names of the user/users, the actual gameplay starts,
where user guide the snake to the apple’s location.
2 players play in multiplayer mode and both of them guide their snakes to the
location of the apple, the snake that ate the apple first, is elongated and the
score of that snake is incremented.
This is the snippet of the Single player game, where user himself guides the
snake to the destination, with the help of ‘UP’, ‘DOWN’, ‘RIGHT’, ‘LEFT’
arrow keys.
38
The UI given below is the is snippet of the Multiplayer mode, where 2 snakes
are running simultaneously and 2 players control the snakes where Snake 1 is
controlled by ‘UP’, ‘DOWN’, ‘RIGHT’, ‘LEFT’ arrow keys and Snake 2 is con-
trolled by ‘W, ‘S’, ‘D, ‘A’ arrow keys.
After users have completely played the game, and at least one of them has
gotten out, then their scores are fetched and stored with their names in the
Database.
39
In terms of the AI Gameplay, snakes(2) move automatically according to the
algorithms that we developed, ‘Hard coded’ ‘A*’. A user interface of that
gameplay is listed down below.
40
Painting all this on the JPanel was not at easy task, at a little bit too much to
understand and figure out for us beginners. But here also the Java documenta-
tion on the Oracle website and the Stack Overflow helped us a lot.
In order to explain how these things were painted on the Jpanel code snippets
from the different parts of the codes are displayed below.
41
This Java code defines several static and instance variables for a game. The
static constants are:
• screenWidth: the width of the game screen in pixels
• screenHeight: the height of the game screen in pixels
This Java code loads two audio files and sets them up for Background mu-
sic/playback using the Java Sound API. The two audio files are:
• ”Snake/[Link]”
• ”Snake/[Link]”
42
For each audio file, the following steps are performed:
• A File object is created using the file path
• An AudioInputStream is created using the File object and the getAudioIn-
putStream() method of the AudioSystem class.
These Clip objects are likely used to play sound effects in the game, such as a
hiss sound and an eating sound.
After running the constructor, the 2 predefined methods startGame() and paint-
Component(Graphics g)are called.
The startGame() method creates a new apple, sets running to true, creates a
new Timer with a delay of DELAY milliseconds and sets this as the action lis-
tener, and starts the timer.
The paintComponent(Graphics g) method is a method of the JComponent class
and it is used to paint or draw the components. In this code, it first calls the
[Link](g) method to make sure that the parent class’s painting
functionality is properly executed. Then it calls the draw(g) method to draw
the game components.
In draw method then, the whole background, Snakes, Apple and the scores
that are displayed below are painted.
43
The game first checks if the game is running or not using the ”running” variable.
If the game is not running, it will call the ”gameOver” method.
It draws the background image that can be seen in the images displayed above.
Drawing of the Snake, is done through the for loop, where i iterates through the
body parts of the snake and draw it on the screen with the color of your choice,
here we have chosen CYAN.
After that, the score each player, players or even the Ai bots have scored are
drawn on the screen and then the score apple icon is drawn based on the number
44
of apples eaten.
Up until here was the difficult part of drawing graphics on the panel in terms
of GUI.
newApple() method is the method, where the coordinates applesx and applesy
are decided with the help of random operator and if the coordinates of the apple
were falling on the body of snake, a new method named fixApple() would be
called, which further would call the newApple() method again, to change the
spawning coordinates of the Apple.
In this part of the code, checkApple() method checks if the apple that was
spawned was eaten or not, and it was done when, the head of the snake was
able to reach the coordinates of the Apple without hitting the other snake or
tail of itself. If that was the case, then newApple() method was called again, to
spawn the Apple at new coordinates and a sound effect will be played, so that
the user feels like the snake has actually eaten something.
45
In this part of the game, checkCollisions() method would check if there were
any collisions that occurred while playing, if yes, the running would be negated
and the game would stop and scores and names of the users will updated in the
Database.
gameOver() method is responsible for showing the game over screen at the end
and play the game over music.
3. Database
Connection to the database:
The program uses JDBC (Java Database Connectivity) to connect to the database.
The connection details are stored in the following variables:
mysql db url: the URL of the database, in this case it’s a local database with
IP address [Link] and port 3306, and the database name is jdbc snake ai.
46
mysql db user: the username to access the database.
mysql pass: the password to access the database.
Reading Input:
A BufferedReader object is created to read input from the user. The program
asks for the user’s name and stores it in the ”name” variable.
Checking if the name exists in the database:
47
Multiplayer:
If the mode of the game is “Multi Player”, the Game Panel will ask to enter
two names. The respective scores will be saved in the Database according to
the Player name.
Compare the score between 2 Player:
As shown in the above code, in case of “Multiplayer”, it will compare the score
of both the Players and display the highest score on the top.
Used Libraries:
We need to add the “[Link]” Package to work with our Database and make
a connection with the SQL Workbench. The [Link] package contains API for
the following:
Making a connection with a database via the DriverManager facility
Sending SQL statements to a database
Retrieving and updating the results of a query
Standard mappings for SQL types to classes and interfaces in the Java program-
ming language
Custom mapping an SQL user-defined type (UDT) to a class in the Java pro-
gramming language
Metadata
Exceptions
We would like to briefly describe the concepts we have used for this Database.
Connection interface — provides tools for managing connections and their char-
acteristics as well as techniques for producing statements
Statement — used to send basic SQL statements
PreparedStatement — used to send prepared statements or basic SQL state-
ments (derived from Statement)
48
ResultSet interface — The outcome of a database query is represented via the
Java JDBC ResultSet interface. The paragraph describing inquiries demon-
strates how a query’s return value is represented as a [Link]. ResultSet.
executeUpdate() — Executes the specified SQL statement, which could be an
INSERT, UPDATE, or DELETE command, as well as a SQL command that
produces no output, like a SQL DDL command.
SQLException — When there is an issue accessing the data, most methods raise
SQLException; however, certain methods may do so for other reasons.
IOException — the default class for exceptions thrown while utilizing streams,
files, and directories to access data
RuntimeException — when a user invokes a method in the wrong way. A
method, for instance, may check to see if one of its inputs is inadvertently null.
The method may throw an unchecked exception called a NullPointerException
if one of the arguments is null.
Above shown are the statistical results of the comparison between the hard-
coded Algorithm and the A* Algorithm, and as per the results, it came out that
every time the A* Algorithm performed 60 to 70 times better in comparison to
the hard-coded Algorithm.
49
8 Conclusions and Future Work
1. How was the teamwork
Being a team of four individuals, who haven’t had any previous experience
in working with the programming language Java, designing a full-fledged game
with the implementation of Artificial Intelligence but quite a challenge. At first,
each one of us was quite nervous about whether we will be able to deliver our
best or not and do justice to this project and the expectations of our professor,
but then as every beginner does, we too started from the start.
The way this project-oriented module was designed, helped us a lot in brushing
up our concepts right from the basics and then improving them to the much
higher advanced levels.
In the first part of the project, we were given weekly assignments on Kattis,
which involved problems that were not only interesting and tricky to solve but
also helped us practice our basics, which is quite important if you start learning
a new programing language.
We built up our basics by solving these problems on weekly basis as our assign-
50
ments and eventually learned a lot of new concepts in Java. It started off with
basic statement printing and went up to learning the Object Oriented Program-
ming Concepts in Java.
Since all of us were beginners, there were a lot of healthy discussions throughout
while working on this project. Everybody’s opinion was taken into considera-
tion and whenever there was difficulty in understanding any concept of Java,
all the other team members took an initiative to help each other in trying to
understand the concept.
Every time a new concept was introduced or was required by the project, we
all sat together discussed it thoroughly, watched videos over the internet for
easier implementations, referred books and shared all the information among
each other so that all were benefited and learnt something new out of it which
ideally the goal of doing this project
Weekly meetups were organized over Discord or personally at the University,
however it suited the majority of the team members, weekly tasks were assigned
to each one of us and these tasks were then discussed in these weekly meetups
and the team was quick and responsive whenever there was a problem
Apart from the weekly meetups, we were also quite active in our class, and
always questioned whenever there were some doubts present. We took full ben-
efit of the Feedback talks organised by our Professor. We took that chance as
an opportunity to get our progress checked, and also boost our confidence by
presenting our progress in front of the rest of the students.
Each one of us had their parts prepared and presented accordingly and by this
everyone got an equal opportunity to share the stage and present and nobody
felt left out
Punctuality and the motivation to deliver our best also helped our team to give
their best and complete the project on time while managing all the other mod-
ules
Even though each one of us was working on a separate part of the project,
namely Algorithm Sorting, Graphical User Interface, and Database, still every-
one was always available in times of need which created a kind of the positive
balance between the team members, and because of this balance and good un-
derstanding among each other we were able to balance the workload of this
project with the other modules and by doing this, the rest of our modules were
not compromised and hence everything fall back into the place
In a nutshell, the team was well balanced and got along well with each other and
due to all these qualities we progressed together, learning new concepts on the
way, experimenting with different examples, and hence completing our project
on time.
51
project, the questions we from all the levels, from basic to hard which was good
for our learning, we started off with some basic stuff like getting familiar with
the syntax since it was a bit hard for us remember in comparison to the other
programming languages that we learned till now
We started practicing a few simple problems, through that we practiced the
basic syntax of a java program, how to take the input from the user and how
to print the output on the terminal, as discussed it was a bit hard to remember
the syntax at first but as we practiced those Kattis problems on weekly basis,
we got a hang of it and became comfortable with it
After getting comfortable with the syntax and the input output format in Java,
we learned the concepts of Object Oriented Programming too. We learned how
the basic concepts of Object Oriented Programming like Inheritance, Abstrac-
tion, Encapsulation and Polymorphism are implemented in Java. What inter-
esting was the implementation of the concept of Multiple Inheritance in Java,
we all know that the concept of Multiple Inheritance is not directly supported
in Java because of the ambiguity that is caused by the compiler, so in order to
implement Multiple Inheritance in Java, we use the concept of Interfaces
Like this there were many concepts that made Java a very interesting language
for us to learn
52
development Due to availability of packages like Graphics, AWT etc, it is one
of the most popular languages that are used now a days in developing number
of softwares and applications
While learning we did not just learn the basic syntax and input output stuff,
rather also got introduced to the Object Oriented Programming part of Java,
which included numerous interesting concepts like String Builder, implementa-
tion of Multiple Inheritance by using Interfaces etc by solving the problems
As we were assigned this project, the first thing that came to our mind was
that its a game that is popular among the kids a lot and kids find it interesting
when the game they are playing has a lot of interesting graphics involved and
also cool sounds in the [Link] we were sure that we had to work a lot
on the Graphics of the game to make it interesting for the user to play For
the graphics part, we learned the concepts of Java Swing and AWT Java The
Swing Framework is a part of the Java Foundation Classes that is used to create
manage windowed applications. It is built using the AWT (Abstract Window
Toolkit) API and is entirely written in Java.
There are many types of classes included in the [Link] package that provide
classes of Java Swing API such as JButton, JTextField, JTextArea, JRadioBut-
ton, JCheckbox, JMenu, JColorChooser, etc which we learned about at first
while learning the concepts and then implemented the same while designing the
Graphical User Interface for our game. We created various buttons, Menus and
Jframes by using these concepts. In Java Swing, you can create a Frame either
by using the concept of Interfaces or by implementing Inheritance. And hence
all the frames that were needed while making the game, were made by using
these concepts.
53
draw(), which was used to draw the various shapes or fill(), which was used to
fill the colour in the objects
54
in prepared Statement objects. The PreparedStatement object offers a feature
to execute a parameterized query rather than hard coding queries.
In a nutshell, by using the concepts of JDBC Driver Class and the Prepared-
Statement, we learned how to integrate a Database in Java, which not only en-
hanced the quality of our project but also deepened our knowledge of Databases
further
Apart from the technical stuff that we learned while doing this project, we cant
ignore the fact that it also taught us how to work in a team, and what all qual-
ities does one need in order bring everyone together and work in a professional
and positive atmosphere. Everything, figuring out the project from the start to
solving the problems at step together, we learned what exactly a positive team
spirit is and how important it is in order to develop a software or an application
55
Reinforcement Learning
A rapidly developing and fascinating area of AI is reinforcement learning. Rein-
forcement learning, at its most basic, entails an agent, a setting, a set of actions
the agent may take, and a reward function that rewards the agent for good
actions or punishes the agent for bad actions. The agent adjusts its parameters
as it explores the environment to maximize its own expected reward. The agent
in Snake’s case is undoubtedly the snake. The NxN board serves as the setting
(with many possible states of this environment depending on where the food
and the snake are located). Turning left, right, or continuing straight are all
options.
Deep Reinforcement Learning (DRL) combines deep neural networks and the
aforementioned principles of RL. Recently, DRL has been used to create super-
human chess and go systems, teach computers to play Atari games using only
the pixels on the screen as input, and manage robots.
Deep Q-Learning
DRL has a unique subset called Deep Q-Learning. Although initially difficult to
understand, the logic behind it is very elegant. The ”Q function,” which takes
the current environment state as input and outputs a vector containing expected
rewards for each potential action, is taught to the neural network. After that,
the agent can choose the course of action that maximizes the Q function. The
game then changes the environment based on this action and assigns a reward
(for example, +10 for eating an apple, -10 for hitting a wall). A neural net-
work with randomly initialized inputs simply approximates the Q function at
the start of training.
This is where the Bellman Equation comes in. The neural network is directed
in the right direction using this equation to approximate Q. The Bellman Equa-
56
tion’s output increases as the network does. Importantly, the definition of the
Q function contains recursion.
The cool thing about watching Snake AI use Deep Q-Learning to train itself
is that you can watch its live exploration and exploitation process. The snake
may pass away after 5 moves in some games. Although this may initially seem
disappointing, keep in mind that there is a cost involved, and the network will
update itself to prevent similar actions in the future. In some games, the snake
survives for a very long time, grows a very long tail, and receives a lot of rewards.
To help the snake play better in the future, the actions are either positively or
negatively reinforced.
Pros: It’s a really stylish and cool idea. Aside from setting up the environ-
ment and reward system, RL can be used for a wide variety of other tasks.
In my experience, it converges more quickly than genetic algorithms due to its
ability to utilize gradient descent rather than random mutation.
Cons: Initially a little difficult to understand. Similar to the genetic algorithm,
the performance of the model depends on the inputs that are made available
to the network; more inputs entail more model parameters, which lengthens
training time.
57