diff --git a/2048 b/2048
index 9282b48a78ef1c2e12b4549b31ee62da69605d49..c7c546fcb6a8996c9f964d9987173c168731fa75 100755
Binary files a/2048 and b/2048 differ
diff --git a/include/2048.hpp b/include/2048.hpp
index 7ae5bbcd9a88874c7ef0907a5858469c832e7220..a3b667aae7bc80eefbef24e52fcd3d12370375a4 100644
--- a/include/2048.hpp
+++ b/include/2048.hpp
@@ -10,20 +10,22 @@ class Game2048 {
 private:
     Tile board[SIZE][SIZE];
     bool moved;
+    int score;
 
     void spawnTile();
-    void resetBoard();
+    void addToScore(int value);
 
 public:
     Game2048();
+    void resetBoard(); // Made public for restart functionality
     void drawBoard();
     void moveLeft();
     void moveRight();
     void moveUp();
     void moveDown();
     bool canMove();
-    int getScore();
-    const Tile (*getBoard() const)[SIZE]; // Return Tile array instead of int array
+    int getScore() const;
+    const Tile (*getBoard() const)[SIZE];
 };
 
 #endif
\ No newline at end of file
diff --git a/include/Extra.hpp b/include/Extra.hpp
index 539aa832bc5f6faf54ea2f358b6a17e0f363adba..e380a77ad2ea5e0a928f970c463fd5944690694f 100644
--- a/include/Extra.hpp
+++ b/include/Extra.hpp
@@ -5,5 +5,26 @@
 
 void initializeGame();
 void cleanupGame();
+void initColors(); // New function to initialize color pairs
+
+// Define color pair constants
+enum ColorPairs {
+    COLOR_PAIR_DEFAULT = 1,
+    COLOR_PAIR_2 = 2,
+    COLOR_PAIR_4 = 3,
+    COLOR_PAIR_8 = 4,
+    COLOR_PAIR_16 = 5,
+    COLOR_PAIR_32 = 6,
+    COLOR_PAIR_64 = 7,
+    COLOR_PAIR_128 = 8,
+    COLOR_PAIR_256 = 9,
+    COLOR_PAIR_512 = 10,
+    COLOR_PAIR_1024 = 11,
+    COLOR_PAIR_2048 = 12,
+    COLOR_PAIR_HIGHER = 13
+};
+
+// Function to get color pair based on tile value
+int getTileColorPair(int value);
 
 #endif
\ No newline at end of file
diff --git a/include/UI.hpp b/include/UI.hpp
index 36c9d787942f3bf5191318334c3073f7d6aac0ea..1e52a83003bb997c5b3254fdd82dbf87843a44f5 100644
--- a/include/UI.hpp
+++ b/include/UI.hpp
@@ -8,7 +8,9 @@ class UI {
 public:
     void drawBoard(const Game2048& game);
     void handleInput(Game2048& game);
-    void showGameOver();
+    void showGameOver(Game2048& game); // Modified to allow restart
+    void displayScore(const Game2048& game);
+    void displayInstructions(); // New method to show game instructions
 };
 
 #endif
\ No newline at end of file
diff --git a/src/2048.cpp b/src/2048.cpp
index 6e64e22e4d47f2e1500d28601674e19a45e5ac61..dd59286d8271c2b77d812ad18cef2eee55370d2f 100644
--- a/src/2048.cpp
+++ b/src/2048.cpp
@@ -4,12 +4,13 @@
 #include <ctime>
 #include <vector>
 
-Game2048::Game2048() {
+Game2048::Game2048() : score(0) {
     std::srand(std::time(0));
     resetBoard();
 }
 
 void Game2048::resetBoard() {
+    score = 0;
     for (int i = 0; i < SIZE; ++i)
         for (int j = 0; j < SIZE; ++j)
             board[i][j].setValue(0);
@@ -31,6 +32,10 @@ void Game2048::spawnTile() {
     }
 }
 
+void Game2048::addToScore(int value) {
+    score += value;
+}
+
 void Game2048::drawBoard() {
     clear();
     for (int i = 0; i < SIZE; ++i) {
@@ -49,7 +54,9 @@ void Game2048::moveLeft() {
         for (int j = 0; j < SIZE; ++j) {
             if (board[i][j].getValue() != 0) {
                 if (index > 0 && temp[index - 1] == board[i][j]) {
-                    temp[index - 1] *= 2;
+                    int mergedValue = board[i][j].getValue() * 2;
+                    temp[index - 1].setValue(mergedValue);
+                    addToScore(mergedValue); // Add to score when tiles merge
                     moved = true;
                 } else {
                     temp[index++] = board[i][j];
@@ -72,7 +79,9 @@ void Game2048::moveRight() {
         for (int j = SIZE - 1; j >= 0; --j) {
             if (board[i][j].getValue() != 0) {
                 if (index < SIZE - 1 && temp[index + 1] == board[i][j]) {
-                    temp[index + 1] *= 2;
+                    int mergedValue = board[i][j].getValue() * 2;
+                    temp[index + 1].setValue(mergedValue);
+                    addToScore(mergedValue); // Add to score when tiles merge
                     moved = true;
                 } else {
                     temp[index--] = board[i][j];
@@ -95,7 +104,9 @@ void Game2048::moveUp() {
         for (int i = 0; i < SIZE; ++i) {
             if (board[i][j].getValue() != 0) {
                 if (index > 0 && temp[index - 1] == board[i][j]) {
-                    temp[index - 1] *= 2;
+                    int mergedValue = board[i][j].getValue() * 2;
+                    temp[index - 1].setValue(mergedValue);
+                    addToScore(mergedValue); // Add to score when tiles merge
                     moved = true;
                 } else {
                     temp[index++] = board[i][j];
@@ -118,7 +129,9 @@ void Game2048::moveDown() {
         for (int i = SIZE - 1; i >= 0; --i) {
             if (board[i][j].getValue() != 0) {
                 if (index < SIZE - 1 && temp[index + 1] == board[i][j]) {
-                    temp[index + 1] *= 2;
+                    int mergedValue = board[i][j].getValue() * 2;
+                    temp[index + 1].setValue(mergedValue);
+                    addToScore(mergedValue); // Add to score when tiles merge
                     moved = true;
                 } else {
                     temp[index--] = board[i][j];
@@ -144,11 +157,7 @@ bool Game2048::canMove() {
     return false;
 }
 
-int Game2048::getScore() {
-    int score = 0;
-    for (int i = 0; i < SIZE; ++i)
-        for (int j = 0; j < SIZE; ++j)
-            score += board[i][j].getValue();
+int Game2048::getScore() const {
     return score;
 }
 
diff --git a/src/2048.o b/src/2048.o
index be2aee928509ea705690354e04eb0040bf3447ae..8980af415a3af453f1c2406f739659a30b323ac5 100644
Binary files a/src/2048.o and b/src/2048.o differ
diff --git a/src/Extra.cpp b/src/Extra.cpp
index 66f1cbad7cb73214f50a154c7e1e9a898adbaf50..da68b9dcdb63c8c9de7ffa328edb8ba51304e37c 100644
--- a/src/Extra.cpp
+++ b/src/Extra.cpp
@@ -6,6 +6,47 @@ void initializeGame() {
     noecho();
     keypad(stdscr, TRUE);
     curs_set(0);
+    
+    // Initialize colors
+    if(has_colors()) {
+        start_color();
+        initColors();
+    }
+}
+
+void initColors() {
+    // Initialize color pairs
+    init_pair(COLOR_PAIR_DEFAULT, COLOR_BLACK, COLOR_WHITE);
+    init_pair(COLOR_PAIR_2, COLOR_BLACK, COLOR_GREEN);
+    init_pair(COLOR_PAIR_4, COLOR_BLACK, COLOR_CYAN);
+    init_pair(COLOR_PAIR_8, COLOR_BLACK, COLOR_BLUE);
+    init_pair(COLOR_PAIR_16, COLOR_BLACK, COLOR_MAGENTA);
+    init_pair(COLOR_PAIR_32, COLOR_BLACK, COLOR_RED);
+    init_pair(COLOR_PAIR_64, COLOR_WHITE, COLOR_BLUE);
+    init_pair(COLOR_PAIR_128, COLOR_WHITE, COLOR_MAGENTA);
+    init_pair(COLOR_PAIR_256, COLOR_WHITE, COLOR_RED);
+    init_pair(COLOR_PAIR_512, COLOR_WHITE, COLOR_YELLOW);
+    init_pair(COLOR_PAIR_1024, COLOR_BLACK, COLOR_YELLOW);
+    init_pair(COLOR_PAIR_2048, COLOR_WHITE, COLOR_GREEN);
+    init_pair(COLOR_PAIR_HIGHER, COLOR_WHITE, COLOR_RED);
+}
+
+int getTileColorPair(int value) {
+    switch(value) {
+        case 0: return COLOR_PAIR_DEFAULT;
+        case 2: return COLOR_PAIR_2;
+        case 4: return COLOR_PAIR_4;
+        case 8: return COLOR_PAIR_8;
+        case 16: return COLOR_PAIR_16;
+        case 32: return COLOR_PAIR_32;
+        case 64: return COLOR_PAIR_64;
+        case 128: return COLOR_PAIR_128;
+        case 256: return COLOR_PAIR_256;
+        case 512: return COLOR_PAIR_512;
+        case 1024: return COLOR_PAIR_1024;
+        case 2048: return COLOR_PAIR_2048;
+        default: return COLOR_PAIR_HIGHER; // For values > 2048
+    }
 }
 
 void cleanupGame() {
diff --git a/src/Extra.o b/src/Extra.o
index c65d8bce46bd620e67c5c97fa4d9dd37416bd3a8..432792b0a7526b491a41031367d7f06027aadfd2 100644
Binary files a/src/Extra.o and b/src/Extra.o differ
diff --git a/src/UI.cpp b/src/UI.cpp
index 37f775b7e32ac2e6f75f5702c63e2de40344a37b..630870ca801c9bfe897577fda39d6e8a7c25c13e 100644
--- a/src/UI.cpp
+++ b/src/UI.cpp
@@ -1,17 +1,59 @@
 #include "UI.hpp"
 #include "2048.hpp"
+#include "Extra.hpp"
 #include <ncurses.h>
+#include <cstdlib>
 
 void UI::drawBoard(const Game2048& game) {
     clear();
+    
+    // Display title
+    attron(A_BOLD);
+    mvprintw(0, 0, "2048 Game");
+    attroff(A_BOLD);
+    
+    // Display the board
     for (int i = 0; i < SIZE; ++i) {
         for (int j = 0; j < SIZE; ++j) {
-            mvprintw(i * 2, j * 5, "%4d", game.getBoard()[i][j].getValue());
+            int value = game.getBoard()[i][j].getValue();
+            int colorPair = getTileColorPair(value);
+            
+            // Calculate position for the tile
+            int yPos = i * 2 + 2;
+            int xPos = j * 6;
+            
+            // Draw the tile with color
+            attron(COLOR_PAIR(colorPair) | A_BOLD);
+            if (value != 0) {
+                mvprintw(yPos, xPos, "%5d", value);
+            } else {
+                mvprintw(yPos, xPos, "     "); // Empty tile
+            }
+            attroff(COLOR_PAIR(colorPair) | A_BOLD);
         }
     }
+    
+    // Display the score with highlight
+    displayScore(game);
+    
+    // Display instructions
+    displayInstructions();
+    
     refresh();
 }
 
+void UI::displayScore(const Game2048& game) {
+    attron(COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
+    mvprintw(0, SIZE * 6 + 2, "Score: %d", game.getScore());
+    attroff(COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
+    
+    mvprintw(SIZE * 2 + 3, 0, "Score: %d", game.getScore());
+}
+
+void UI::displayInstructions() {
+    mvprintw(SIZE * 2 + 4, 0, "Controls: Arrow keys to move, 'r' to restart, 'q' to quit");
+}
+
 void UI::handleInput(Game2048& game) {
     int ch = getch();
     switch (ch) {
@@ -19,10 +61,27 @@ void UI::handleInput(Game2048& game) {
         case KEY_RIGHT: game.moveRight(); break;
         case KEY_UP: game.moveUp(); break;
         case KEY_DOWN: game.moveDown(); break;
+        case 'r': case 'R': game.resetBoard(); break; // Restart on 'r' key
+        case 'q': case 'Q': endwin(); exit(0); break; // Quit on 'q' key
     }
 }
 
-void UI::showGameOver() {
-    mvprintw(SIZE * 2, 0, "Game Over! Press any key to exit.");
-    getch();
+void UI::showGameOver(Game2048& game) {
+    attron(COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
+    mvprintw(SIZE * 2 + 6, 0, "GAME OVER!");
+    attroff(COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
+    
+    mvprintw(SIZE * 2 + 7, 0, "Press 'r' to restart or 'q' to quit");
+    refresh();
+    
+    while (true) {
+        int ch = getch();
+        if (ch == 'r' || ch == 'R') {
+            game.resetBoard();
+            break;
+        } else if (ch == 'q' || ch == 'Q') {
+            endwin();
+            exit(0);
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/UI.o b/src/UI.o
index 6884c76d42125ee5b58f5bdb8aee7765dd1e54f6..30433495b505e870cdf9860ba7f717ff9de76884 100644
Binary files a/src/UI.o and b/src/UI.o differ
diff --git a/src/main.cpp b/src/main.cpp
index 2ad697ab6c0dab29229113e1775bc6093e3458db..8708fb433038bf557f1965c71437a41a2a6c18e5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4,6 +4,7 @@
 #include <ncurses.h>
 
 int main() {
+    // Initialize the game and colors
     initializeGame();
 
     Game2048 game;
@@ -16,8 +17,9 @@ int main() {
         ui.drawBoard(game);
 
         if (!game.canMove()) {
-            ui.showGameOver();
-            break;
+            ui.showGameOver(game);
+            // After restart, redraw the board
+            ui.drawBoard(game);
         }
     }
 
diff --git a/src/main.o b/src/main.o
index 81e031e499cf37f1c37af6a7495a82b1b505cd12..618be4a5c4dc1eefa3ddc87ac01405fe3e818fbd 100644
Binary files a/src/main.o and b/src/main.o differ