diff --git a/app/src/main/java/brickbreaker/App.java b/app/src/main/java/brickbreaker/App.java
index 4ab69aee324fe4900bbadee34b5b1c9debe34516..a18c0a57e7bb771609c246be6024cf3c8b168e21 100644
--- a/app/src/main/java/brickbreaker/App.java
+++ b/app/src/main/java/brickbreaker/App.java
@@ -7,13 +7,13 @@ import javax.swing.JFrame;
 
 public class App {
     public static void main(String[] args) {
-        		JFrame obj = new JFrame();
-		GamePanel gamePanel = new GamePanel();
-		obj.setBounds(10, 10, 700, 600);
-		obj.setTitle("Brick Breaker");
-		obj.setResizable(false);
-		obj.setVisible(true);
-		obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-		obj.add(gamePanel);
+        JFrame obj = new JFrame();
+        GamePanel gamePanel = new GamePanel();
+	obj.setBounds(10, 10, 700, 600);
+	obj.setTitle("Brick Breaker");
+	obj.setResizable(false);
+	obj.setVisible(true);
+	obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+	obj.add(gamePanel);
     }
 }
diff --git a/app/src/main/java/brickbreaker/Ball.java b/app/src/main/java/brickbreaker/Ball.java
new file mode 100644
index 0000000000000000000000000000000000000000..3cc1a80a41117588f3eed7890d8c6c484debec03
--- /dev/null
+++ b/app/src/main/java/brickbreaker/Ball.java
@@ -0,0 +1,69 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package brickbreaker;
+
+import java.awt.Color;
+import java.awt.Graphics;
+
+/**
+ *
+ * @author Suman
+ */
+public class Ball {
+    private Vector position;
+    private Vector direction;
+    public int radius;
+    public Color color;
+    
+    public Ball(int posX, int posY, int dirX, int dirY, int radius,Color color) {
+        this.position = new Vector(posX, posY);
+        this.direction = new Vector(dirX, dirY);
+        this.radius = radius;
+        this.color = color;
+    }
+    
+    public void setPosition(int posX, int posY) {
+        this.position = new Vector(posX, posY);
+    }
+    
+    public void setDirection(int dirX, int dirY) {
+        this.direction = new Vector(dirX, dirY);
+    }
+    
+    public Vector getPosition() {
+        return this.position;
+    }
+    
+    public Vector getDirection() {
+        return this.direction;
+    }
+    
+    public void move(){
+        position.x += direction.x;
+        position.y += direction.y;
+    }
+    
+    public void checkForWallCollisions() {
+        if (position.x <= 0) { // Left wall collision
+        position.x = 0; // Set the ball at the left edge
+        direction.x = Math.abs(direction.x); // Reverse the x direction
+        }
+
+        if (position.x + radius >= 680) { // Right wall collision
+            position.x = 680 - radius; // Set the ball at the right edge
+            direction.x = -Math.abs(direction.x); // Reverse the x direction
+        }
+
+        if (position.y <= 0) { // Top wall collision
+            position.y = 0; // Set the ball at the top edge
+            direction.y = Math.abs(direction.y); // Reverse the y direction
+        }
+    }
+    
+    public void draw(Graphics graphics) {
+        graphics.setColor(this.color); // ball color
+        graphics.fillOval(position.x, position.y, radius, radius);
+    }
+}
diff --git a/app/src/main/java/brickbreaker/GameComponents/Brick.java b/app/src/main/java/brickbreaker/GameComponents/Brick.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c03328ae0a154f8d76c8e2420ad846b0b395a2f
--- /dev/null
+++ b/app/src/main/java/brickbreaker/GameComponents/Brick.java
@@ -0,0 +1,37 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package brickbreaker.GameComponents;
+
+import brickbreaker.Vector;
+import java.awt.Color;
+import java.awt.Graphics2D;
+
+/**
+ *
+ * @author Suman
+ */
+public class Brick {
+    private Vector position;
+    private int width;
+    private int height;
+    private Color color;
+    private Boolean hasPowerUp;
+
+    public Brick(int x, int y, int width, int height, Color color, Boolean hasPowerUp) {
+        this.position = new Vector(x, y);
+        this.width = width;
+        this.height = height;
+        this.color = color;
+        this.hasPowerUp = hasPowerUp;
+    }
+
+    public void draw(Graphics2D g) {
+        g.setColor(this.color); // brick color
+        g.fillRect(this.position.x, this.position.y, width, height);
+
+        g.setColor(Color.BLACK);
+        g.drawRect(this.position.x, this.position.y, width, height);
+    }
+}
diff --git a/app/src/main/java/brickbreaker/GameComponents/DefaultBrickFactory.java b/app/src/main/java/brickbreaker/GameComponents/DefaultBrickFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..a086497915ea29eaa5f346db78717e6b7205c463
--- /dev/null
+++ b/app/src/main/java/brickbreaker/GameComponents/DefaultBrickFactory.java
@@ -0,0 +1,21 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package brickbreaker.GameComponents;
+
+import brickbreaker.GameComponents.Brick;
+import brickbreaker.Interfaces.BrickFactory;
+import java.awt.Color;
+
+/**
+ *
+ * @author Suman
+ */
+public class DefaultBrickFactory implements BrickFactory {
+    @Override
+    public Brick createBrick(int x, int y, int width, int height, Boolean hasPowerUp) {
+        Color color = Color.decode("#FF0000");
+        return new Brick(x, y, width, height, color, hasPowerUp);
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/brickbreaker/GameMapBuilder.java b/app/src/main/java/brickbreaker/GameMapBuilder.java
index f946281ee346d71d59d365e836fe9f3c15800f60..3b6562e4b87d12743c7916572ee3c3f81a38b2c2 100644
--- a/app/src/main/java/brickbreaker/GameMapBuilder.java
+++ b/app/src/main/java/brickbreaker/GameMapBuilder.java
@@ -4,6 +4,8 @@
  */
 package brickbreaker;
 
+import brickbreaker.GameComponents.Brick;
+import brickbreaker.Interfaces.BrickFactory;
 import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Graphics2D;
@@ -12,45 +14,49 @@ import java.awt.Graphics2D;
  *
  * @author Suman
  */
-class GameMapBuilder {
+public class GameMapBuilder {
 	
 	public int map [][];
 	public int brickWidth;
 	public int brickHeight;
-	
+	private BrickFactory brickfactory;
+        private final int maxNoOfPowerUps = 5;
 	// this creates the brick of size 4x8
-	public GameMapBuilder(int row, int col) {
-		map = new int [row][col];
-		for (int i = 0; i < map.length; i++) { 
-			for (int j=0; j< map[0].length;j++) {
-				map[i][j] = 1;
-			}
-		}
-		
-		brickWidth = 540/col;
-		brickHeight = 150/row;
+	public GameMapBuilder(int row, int col, BrickFactory brickFactory) {
+            map = new int [row][col];
+            for (int i = 0; i < map.length; i++) { 
+                for (int j=0; j< map[0].length;j++) {
+                    map[i][j] = 1;
+                }
+            }
+            brickWidth = 50;
+            brickHeight = 20;
+            this.brickfactory = brickFactory;
 	}
 	
 	// this draws the bricks
 	public void draw(Graphics2D g) {
-		for (int i = 0; i < map.length; i++) {
-			for (int j=0; j< map[0].length;j++) {
-				if(map[i][j] > 0) {
-					g.setColor(new Color(0XFF8787)); // brick color
-					g.fillRect(j*brickWidth + 80, i*brickHeight + 50, brickWidth, brickHeight);
-					
-					g.setStroke(new BasicStroke(4));
-					g.setColor(Color.BLACK);
-					g.drawRect(j*brickWidth + 80, i*brickHeight + 50, brickWidth, brickHeight);
-				}
-			}
-			
-		}
+            
+            int numberOfPowerUps = (int) (Math.random() * maxNoOfPowerUps );
+            for (int i = 0; i < map.length; i++) {
+                for (int j=0; j< map[0].length;j++) {
+                    if(map[i][j] > 0) {
+                      
+                        boolean hasPowerUp = false;
+                        if(numberOfPowerUps > 0) {
+                            hasPowerUp = Math.random() < 0.5;
+                        }
+                        if(hasPowerUp) numberOfPowerUps--;
+                        Brick brick = brickfactory.createBrick(j*brickWidth, i*brickHeight, brickWidth, brickHeight, hasPowerUp);
+                        brick.draw(g);
+                    }
+                }
+            }
 	}
 	
 	// this sets the value of brick to 0 if it is hit by the ball
 	public void setBrickValue(int value, int row, int col) {
-		map[row][col] = value;
+            map[row][col] = value;
 	}
 
 }
\ No newline at end of file
diff --git a/app/src/main/java/brickbreaker/GamePanel.java b/app/src/main/java/brickbreaker/GamePanel.java
index eee55338ebf3dc32c85873916e9bbefc848e4cd9..9dc12eee9e0e1054f323ff8b01f449f6fb9d14d3 100644
--- a/app/src/main/java/brickbreaker/GamePanel.java
+++ b/app/src/main/java/brickbreaker/GamePanel.java
@@ -1,34 +1,46 @@
 package brickbreaker;
 
+import brickbreaker.Interfaces.BrickFactory;
+import brickbreaker.Interfaces.GameObserver;
+import brickbreaker.GameComponents.DefaultBrickFactory;
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 
 public class GamePanel extends JPanel implements KeyListener, ActionListener {
     private boolean play = true;
     private int score = 0;
 
-    private int totalBricks = 21;
+    private int totalBricks;
+    private int rows = 10;
+    private int columns = 14;
 
     private Timer timer;
     private int delay = 8;
 
-    private int playerX = 310;
+    private int paddle = 310;
+
+    private List<Ball> balls = new ArrayList<>(); // Use List interface instead of ArrayList
 
-    private Vector ballPosition;
-    private Vector ballDirection;
     private String font = "MV Boli";
 
     private GameMapBuilder map;
 
     public GamePanel() {
-        this.ballPosition = new Vector(120, 350);
-        this.ballDirection = new Vector(-1, -2);
-        
-        map = new GameMapBuilder(4, 8);
+        Color color = Color.decode("#8B4513");
+        this.balls.add(new Ball(350, 450, 2, -2, 20, color)); // Adjust the initial ball position and direction
+        color = Color.decode("#008080");
+        this.balls.add(new Ball(380, 420, -2, 2, 50, color));
+        this.totalBricks = rows * columns;
+
+        BrickFactory brickfactory = new DefaultBrickFactory();
+        map = new GameMapBuilder(rows, columns, brickfactory);
         addKeyListener(this);
         setFocusable(true);
         setFocusTraversalKeysEnabled(false);
@@ -36,45 +48,64 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener {
         timer.start();
     }
 
+    private List<GameObserver> observers = new ArrayList<>();
+
+    public void addObserver(GameObserver observer) {
+        observers.add(observer);
+    }
+
+    public void removeObserver(GameObserver observer) {
+        observers.remove(observer);
+    }
+    
     protected void paintComponent(Graphics graphics) {
         super.paintComponent(graphics);
-
+        if (balls.isEmpty()) {
+            gameOver(graphics, "Game Over", Color.BLACK);
+        }   
         // background color
         graphics.setColor(Color.green);
         graphics.fillRect(1, 1, 692, 592);
 
         map.draw((Graphics2D) graphics);
 
-        graphics.fillRect(0, 0, 3, 592);
-        graphics.fillRect(0, 0, 692, 3);
-        graphics.fillRect(691, 0, 3, 592);
 
         graphics.setColor(Color.blue);
-        graphics.fillRect(playerX, 550, 100, 12);
+        graphics.fillRect(paddle, 550, 100, 20);
+
+        Iterator<Ball> ballsIterator = balls.iterator();
 
-        graphics.setColor(Color.RED); // ball color
-        graphics.fillOval(ballPosition.x, ballPosition.y, 20, 20);
+        while (ballsIterator.hasNext()) {
+            Ball ball = ballsIterator.next();
+            Vector ballPosition = ball.getPosition();
+
+            if (ballPosition.y > 560) {
+                ballsIterator.remove();
+                continue;
+            } else {
+                ball.checkForWallCollisions();
+            }
+
+            ball.draw(graphics);
+        }
 
         graphics.setColor(Color.black);
         graphics.setFont(new Font("MV Boli", Font.BOLD, 25));
         graphics.drawString("Score: " + score, 520, 30);
 
-        if (totalBricks <= 0) { // if all bricks are destroyed then you win
-            
+        if (totalBricks <= 0) {
             Color color = new Color(0XFF6464);
             gameOver(graphics, "You Won", color);
-            
         }
-
-        if (ballPosition.y > 570) { // if ball goes below the paddle then you lose
+        
+        if (balls.isEmpty()) {
             gameOver(graphics, "Game Over", Color.BLACK);
         }
+
     }
-    
-    public void gameOver(Graphics graphics, String gameOverText,Color color) {
+
+    public void gameOver(Graphics graphics, String gameOverText, Color color) {
         play = false;
-        ballDirection.x = 0;
-        ballDirection.y = 0;
         graphics.setColor(color);
         graphics.setFont(new Font(font, Font.BOLD, 30));
         graphics.drawString(gameOverText + ", Your Score: " + score, 190, 300);
@@ -82,113 +113,100 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener {
         graphics.setFont(new Font(font, Font.BOLD, 20));
         graphics.drawString("Press Enter to Restart", 230, 350);
     }
-    
+
     @Override
     public void actionPerformed(ActionEvent arg0) {
         if (play) {
-            // Ball - Pedal interaction
-            if (new Rectangle(ballPosition.x, ballPosition.y, 20, 20).intersects(new Rectangle(playerX, 550, 100, 8))) {
-                ballDirection.y = -ballDirection.y;
-            }
-            for (int i = 0; i < map.map.length; i++) { // Ball - Brick interaction
-                for (int j = 0; j < map.map[0].length; j++) { // map.map[0].length is the number of columns
-                    if (map.map[i][j] > 0) {
-                        int brickX = j * map.brickWidth + 80;
-                        int brickY = i * map.brickHeight + 50;
-                        int brickWidth = map.brickWidth;
-                        int brickHeight = map.brickHeight;
-
-                        Rectangle rect = new Rectangle(brickX, brickY, brickWidth, brickHeight);
-                        Rectangle ballRect = new Rectangle(ballPosition.x, ballPosition.y, 20, 20);
-                        Rectangle brickRect = rect;
-
-                        if (ballRect.intersects(brickRect)) {
-                            map.setBrickValue(0, i, j);
-                            totalBricks--;
-                            score += 5;
-
-                            if (ballPosition.x + 19 <= brickRect.x || ballPosition.x + 1 >= brickRect.x + brickRect.width)
-                                ballDirection.x = -ballDirection.x;
-                            else {
-                                ballDirection.y = -ballDirection.y;
+            for (Ball ball : balls) {
+                Vector ballPosition = ball.getPosition();
+                Vector ballDirection = ball.getDirection();
+
+                if (new Rectangle(ballPosition.x, ballPosition.y, ball.radius, ball.radius).intersects(new Rectangle(paddle, 550, 100, 8))) {
+                    ballDirection.y = -ballDirection.y;
+                    ball.setDirection(ballDirection.x, ballDirection.y);
+                }
+
+                for (int i = 0; i < map.map.length; i++) {
+                    for (int j = 0; j < map.map[0].length; j++) {
+                        if (map.map[i][j] > 0) {
+                            int brickX = j * map.brickWidth;
+                            int brickY = i * map.brickHeight;
+                            int brickWidth = map.brickWidth;
+                            int brickHeight = map.brickHeight;
+
+                            Rectangle brickRect = new Rectangle(brickX, brickY, brickWidth, brickHeight);
+                            Rectangle ballRect = new Rectangle(ballPosition.x, ballPosition.y, ball.radius, ball.radius);
+                            
+                            
+                            if (ballRect.intersects(brickRect)) {
+                                map.setBrickValue(0, i, j);
+                                totalBricks--;
+                                score += 5;
+
+                                if (ballPosition.x + 19 <= brickRect.x || ballPosition.x + 1 >= brickRect.x + brickRect.width) {
+                                    ballDirection.x = -ballDirection.x;
+                                } else {
+                                    ballDirection.y = -ballDirection.y;
+                                }
                             }
                         }
-
                     }
-
                 }
+                ball.setDirection(ballDirection.x, ballDirection.y);
+                ball.move(); // Call the move() method to update the ball's position
             }
-
-            ballPosition.x += ballDirection.x;
-            ballPosition.y += ballDirection.y;
-            if (ballPosition.x < 0) { // if ball hits the left wall then it bounces back
-                ballDirection.x = -ballDirection.x;
-            }
-            if (ballPosition.y < 0) { // if ball hits the top wall then it bounces back
-                ballDirection.y = -ballDirection.y;
-            }
-            if (ballPosition.x > 670) { // if ball hits the right wall then it bounces back
-                ballDirection.x = -ballDirection.x;
-            }
-
         }
 
-         repaint();
+        repaint();
     }
 
     @Override
     public void keyTyped(KeyEvent arg0) {
-
     }
 
     @Override
     public void keyPressed(KeyEvent arg0) {
-        if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) { // if right arrow key is pressed then paddle moves right
-            if (playerX >= 600) {
-                playerX = 600;
+        if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
+            if (paddle >= 600) {
+                paddle = 600;
             } else {
                 moveRight();
-
             }
         }
-        if (arg0.getKeyCode() == KeyEvent.VK_LEFT) { // if left arrow key is pressed then paddle moves left
-            if (playerX < 10) {
-                playerX = 10;
+        if (arg0.getKeyCode() == KeyEvent.VK_LEFT) {
+            if (paddle < 10) {
+                paddle = 10;
             } else {
                 moveLeft();
-
             }
         }
 
-        if (arg0.getKeyCode() == KeyEvent.VK_ENTER) { // if enter key is pressed then game restarts
+        if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {
             if (!play) {
                 play = true;
-                ballPosition.x = 120;
-                ballPosition.y = 350;
-                ballDirection.x = -1;
-                ballDirection.y = -2;
+                Color color = Color.decode("#8B4513");
+                this.balls.add(new Ball(350, 450, 1, -1, 20, color)); // Adjust the initial ball position and direction
                 score = 0;
-                totalBricks = 21;
-                map = new GameMapBuilder(7, 8);
+                totalBricks = rows * columns;
+                BrickFactory brickfactory = new DefaultBrickFactory();
+                map = new GameMapBuilder(rows, columns, brickfactory);
 
                 repaint();
             }
         }
-
     }
 
-    public void moveRight() { // paddle moves right by 50 pixels
+    public void moveRight() {
         play = true;
-        playerX += 50;
+        paddle += 50;
     }
 
-    public void moveLeft() { // paddle moves left by 50 pixels
+    public void moveLeft() {
         play = true;
-        playerX -= 50;
+        paddle -= 50;
     }
 
     @Override
     public void keyReleased(KeyEvent arg0) {
-
     }
 }
diff --git a/app/src/main/java/brickbreaker/Interfaces/BrickFactory.java b/app/src/main/java/brickbreaker/Interfaces/BrickFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba3cedf49965393e114c2bcd82789b8ef0849bbe
--- /dev/null
+++ b/app/src/main/java/brickbreaker/Interfaces/BrickFactory.java
@@ -0,0 +1,16 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template
+ */
+package brickbreaker.Interfaces;
+
+import brickbreaker.GameComponents.Brick;
+import java.awt.Color;
+
+/**
+ *
+ * @author Suman
+ */
+public interface BrickFactory {
+    Brick createBrick(int x, int y, int width, int height, Boolean hasPowerup);
+}
diff --git a/app/src/main/java/brickbreaker/Interfaces/GameObserver.java b/app/src/main/java/brickbreaker/Interfaces/GameObserver.java
new file mode 100644
index 0000000000000000000000000000000000000000..e30d97edfd0ee602fcef7ab61fee8d9ee2e0c55f
--- /dev/null
+++ b/app/src/main/java/brickbreaker/Interfaces/GameObserver.java
@@ -0,0 +1,14 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template
+ */
+package brickbreaker.Interfaces;
+
+/**
+ *
+ * @author Suman
+ */
+public interface GameObserver {
+    void onGameOver(int finalScore);
+    void onGameWin(int finalScore);
+}