2048 Puzzle
2048 Puzzle
2048 Puzzle
Paknajol, Kathmandu
This project involved implementing a digital version of the popular puzzle game 2048 using
Java. The game requires the player to move numbered tiles around a grid and combine them to
reach the goal of creating a tile with a value of 2048. The implementation included features such
as score tracking and a graphical user interface developed with Java's Swing library. The goal of
the project was to provide an entertaining and challenging game while demonstrating proficiency
in Java programming. The project was successful in achieving this objective, resulting in a fully
functional implementation of the 2048 game.
i
Acknowledgement
I would like to express my sincere gratitude to the faculty and staff of NCCS College for
providing me with an excellent learning environment and the opportunity to work on this project.
I would particularly like to thank our teacher, Mr. Yuba Raj Devkota, for his invaluable
guidance, support, and encouragement throughout the project. His expertise, insights, and
suggestions were instrumental in helping me to understand the complexities of the game and to
develop a functional and engaging implementation of 2048.
Finally, I would like to acknowledge the developers of the original 2048 game for creating such
an addictive and challenging puzzle that has inspired so many adaptations and variations. Their
creativity and innovation have set a high standard for game development and have provided me
with a valuable learning experience in Java programming.
ii
Table of Contents
Abstract.............................................................................................................................................i
Acknowledgement...........................................................................................................................ii
Introduction......................................................................................................................................1
Objectives........................................................................................................................................1
Problem Statement...........................................................................................................................2
DSA topics used..............................................................................................................................2
Source Codes...................................................................................................................................3
Board.java....................................................................................................................................3
ColorScheme.java......................................................................................................................11
Controls.java..............................................................................................................................12
Game.java..................................................................................................................................13
Grid.java....................................................................................................................................14
Tile.java.....................................................................................................................................17
Window.java..............................................................................................................................18
Main.java...................................................................................................................................20
Output............................................................................................................................................21
Conclusion.....................................................................................................................................22
Reference.......................................................................................................................................23
Introduction
2048 is a popular single player sliding block puzzle game that was created by Italian
developer Gabriele Cirulli in March 2014. The game is played on a 4x4 grid, and the objective is
to slide numbered tiles on the grid to combine them and create a tile with the number 2048.
Each turn, the player can slide all the tiles on the grid in one of four directions: up, down, left, or
right. If two tiles with the same number collide, they merge into a tile with double the value. For
example, if two tiles with the number 2 collide, they merge into a tile with the number 4. The
game is won when a tile with the number 2048 is created, but the game continues even after that
point.
Objectives
Implementing game mechanics that allow players to slide tiles in all four
directions and merge tiles with the same value.
Creating an algorithm that generates new tiles on the grid after each move.
Providing options for customizing the game, such as changing the tile colors or
grid size.
Ensuring that the game is optimized for performance and can run on a variety of
devices and platforms.
1
Problem Statement
The problem statement of a 2048 game typically involves creating a challenging and engaging
gameplay experience for the player. The game involves a 4x4 grid of tiles that can be moved in
four directions: up, down, left, and right. The objective of the game is to slide tiles around the
grid and merge tiles with the same value to create a tile with a value of 2048.
The game becomes increasingly difficult as the player merges tiles and creates larger tiles with
higher values. The player must strategize and plan their moves carefully to avoid running out of
space on the grid and to prevent tiles from becoming stuck in corners or along the edges.
The problem statement also involves implementing efficient algorithms to slide and merge tiles,
generate new tiles, and check for game over conditions. The game should be optimized for
performance and should run smoothly on a variety of devices and platforms.
Arrays and matrices: To represent the game board and tiles, and to perform operations on
them such as merging and sliding.
Searching and sorting: To search for available empty cells and to sort tiles based on their
value.
Recursion: To implement the algorithms that slide tiles and merge tiles recursively.
Graph traversal algorithms: To check for game over conditions, such as when the game
board is full and no more moves can be made.
2
HashMap: To store key-value pairs of integer and Color objects.
Source Codes
Board.java
package game;
import java.util.ArrayList;
import java.util.List;
/**
* Board
* @author petrnemecek
*
*/
public class Board {
/**
* {@link Constructor}
*
*/
public Board(int size) {
super();
this.size = size;
this.emptyTiles = this.size * this.size;
this.tiles = new ArrayList<>();
start();
}
3
private void initialize() {
for (int row = 0; row < this.size; row++) {
tiles.add(new ArrayList<Tile>());
for (int col = 0; col < this.size; col++) {
tiles.get(row).add(new Tile());
}
}
}
/**
* merges two touching {@link Tile} with the same number into one
* @param sequence of {@link Tile}
* @return merged sequence of {@link Tile}
*/
private List<Tile> mergeTiles(List<Tile> sequence) {
for (int l = 0; l < sequence.size() - 1; l++) {
if (sequence.get(l).getValue() == sequence.get(l + 1).getValue()) {
int value;
if ((value = sequence.get(l).merging()) == 2048) {
gameover = true;
}
score += value;
sequence.remove(l + 1);
genNewTile = true; // board has changed its state
emptyTiles++;
}
}
return sequence;
}
/**
* creates empty {@link Tile} instances and adds them to the left (resp. top) of merged
sequence to fit the board
* @param merged sequence of {@link Tile}
* @return refilled sequence with required number of empty {@link Tile}
*/
private List<Tile> addEmptyTilesFirst(List<Tile> merged) {
for (int k = merged.size(); k < size; k++) {
merged.add(0, new Tile());
}
return merged;
}
5
/**
* creates empty {@link Tile} instances and adds them to the right (resp. bottom) of
merged sequence to fit the board
* @param merged sequence of {@link Tile}
* @return refilled sequence with required number of empty {@link Tile}
*/
private List<Tile> addEmptyTilesLast(List<Tile> merged) { // boolean last/first
for (int k = merged.size(); k < size; k++) {
merged.add(k, new Tile());
}
return merged;
}
return moved;
}
return moved;
}
return moved;
}
return moved;
}
List<Tile> moved;
moved = removeEmptyTilesCols(row);
moved = mergeTiles(moved);
moved = addEmptyTilesLast(moved);
moved = setColToBoard(moved, row);
List<Tile> moved;
7
moved = removeEmptyTilesCols(row);
moved = mergeTiles(moved);
moved = addEmptyTilesFirst(moved);
moved = setColToBoard(moved, row);
List<Tile> moved;
moved = removeEmptyTilesRows(row);
moved = mergeTiles(moved);
moved = addEmptyTilesLast(moved);
moved = setRowToBoard(moved, row);
List<Tile> moved;
moved = removeEmptyTilesRows(row);
moved = mergeTiles(moved);
moved = addEmptyTilesFirst(moved);
moved = setRowToBoard(moved, row);
8
if (gameover) {
// end(true);
setWonOrLost("WON");
} else {
if (isFull()) {
if (!isMovePossible()) {
// you lost (board is full with no tiles to merge)
// end(false);
setWonOrLost("LOST");
}
} else {
newRandomTile(); // game continues
}
}
}
ColorScheme.java
package game;
import java.awt.Color;
import java.util.HashMap;
public ColorScheme() {
initBackrounds();
}
11
return background.get(value);
}
Controls.java
package game;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
@Override
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
switch (keyCode) {
case KeyEvent.VK_UP:
Game.BOARD.moveUp();
break;
case KeyEvent.VK_DOWN:
Game.BOARD.moveDown();
break;
case KeyEvent.VK_LEFT:
Game.BOARD.moveLeft();
break;
case KeyEvent.VK_RIGHT:
12
Game.BOARD.moveRight();
break;
case KeyEvent.VK_ESCAPE:
Game.WINDOW.dispose();
break;
default:
break;
}
Game.BOARD.isGameOver();
//Game.BOARD.show();
Game.WINDOW.repaint();
Game.java
package game;
}
Grid.java
package game;
import java.awt.Color;
import java.awt.Font;
13
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JPanel;
public Grid() {
super(true); // turn on doublebuffering
}
drawBackground(g);
drawTitle(g);
drawScoreBoard(g);
drawBoard(g);
g.setColor(Game.COLORS.getTileColor(value));
final int size = value < 100 ? 36 : value < 1000 ? 32 : 24;
final Font font = new Font(FONT, Font.BOLD, size);
g.setFont(font);
String s = String.valueOf(value);
final FontMetrics fm = g.getFontMetrics(font);
if (value != 0) {
Game.BOARD.getTileAt(y, x).setPosition(y, x); // tile gets its new
position
g.drawString(s, xOffset + (TILE_SIZE - w) / 2, yOffset + TILE_SIZE -
(TILE_SIZE - h) / 2 - 2);
}
}
16
Tile.java
package game;
public Tile() {
new Tile(0);
}
17
return (this.value += this.value);
}
/**
* checks whether numbered (nonzero) tile changes its position
* @param row
* @param col
* @return true if tile changed its position, false if not
*/
public boolean hasMoved(int row, int col) {
return (!isEmpty() && ((this.row != row) || (this.col != col)));
}
@Override
public String toString() {
return "Tile [value=" + value + "]";
}
Window.java
package game;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
18
/**
* Window
* @author petrnemecek
*
*/
/**
*
*/
private static final long serialVersionUID = -8804446439773037674L;
private int width = 375;
private int height = 450;
this.setResizable(false);
this.setFocusable(true); // set focus on window so KeyListener works
Main.java
package game;
new Game();
}
}
Output
20
Image 1: 2048 puzzle game
In conclusion, the 2048 game created in Java is a simple yet addictive puzzle game that can be
enjoyed by people of all ages. As a developer, it was a fun and challenging project to work on,
and it allowed me to practice my skills in programming, game development, and user interface
design. Through this project, I learned the importance of planning, organization, and attention to
21
detail in software development. Overall, I hope that others will enjoy playing it as much as I
enjoyed making it.
Reference
22
stack overflow. (2023, 03 09). From stack overflow: www.stackoverflow.com
w3schools. (2023, 03 09). From w3schools: www.w3schools.com
23