diff --git a/2048 b/2048
deleted file mode 100755
index c7c546fcb6a8996c9f964d9987173c168731fa75..0000000000000000000000000000000000000000
Binary files a/2048 and /dev/null differ
diff --git a/Makefile b/Makefile
index 30620e687d1412a80c9f4ef2aa656d574bc48c9c..8ccb1dea4b9b576b2ad19bcef74b14c310ffd1d0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,28 +1,28 @@
-# Compiler and flags
-CXX = g++
-CXXFLAGS = -std=c++11 -Wall -Wextra -Iinclude
-LDFLAGS = -lncurses  # Add this for linking ncurses
+CC = g++
+CFLAGS = -std=c++11 -Wall -I include
+LDFLAGS = -lncurses
 
-# Source files
-SRC = src/2048.cpp src/UI.cpp src/Extra.cpp src/Tile.cpp src/main.cpp
+SRCDIR = src
+OBJDIR = obj
+BINDIR = bin
 
-# Object files
-OBJ = $(SRC:.cpp=.o)
+# Source files
+SOURCES = $(wildcard $(SRCDIR)/*.cpp)
+OBJECTS = $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SOURCES))
+EXECUTABLE = $(BINDIR)/2048
 
-# Target executable
-TARGET = 2048
+# Create directories if they don't exist
+$(shell mkdir -p $(OBJDIR) $(BINDIR))
 
-# Default target
-all: $(TARGET)
+all: $(EXECUTABLE)
 
-# Link object files to create the executable
-$(TARGET): $(OBJ)
-	$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJ) $(LDFLAGS)  # <-- Add $(LDFLAGS) here
+$(EXECUTABLE): $(OBJECTS)
+	$(CC) $(OBJECTS) -o $@ $(LDFLAGS)
 
-# Compile source files into object files
-%.o: %.cpp
-	$(CXX) $(CXXFLAGS) -c $< -o $@  # <-- TAB indentation
+$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
+	$(CC) $(CFLAGS) -c $< -o $@
 
-# Clean up build artifacts
 clean:
-	rm -f $(OBJ) $(TARGET)  # <-- TAB indentation
\ No newline at end of file
+	rm -rf $(OBJDIR)/*.o $(EXECUTABLE)
+
+.PHONY: all clean
\ No newline at end of file
diff --git a/bin/2048 b/bin/2048
new file mode 100755
index 0000000000000000000000000000000000000000..646381373d323dc17565e3794d0c5796fde902f5
Binary files /dev/null and b/bin/2048 differ
diff --git a/include/GameMode.hpp b/include/GameMode.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a815dde893bad728557d71e6dd424dcc142c1ef5
--- /dev/null
+++ b/include/GameMode.hpp
@@ -0,0 +1,104 @@
+#ifndef GAMEMODE_HPP
+#define GAMEMODE_HPP
+
+#include <string>
+
+enum class GameModeType {
+    CLASSIC,
+    TIMED,
+    POWERUP,
+    CHALLENGE,
+    TUTORIAL
+};
+
+class GameMode {
+protected:
+    GameModeType type;
+    std::string name;
+    std::string description;
+
+public:
+    GameMode(GameModeType type, const std::string& name, const std::string& description);
+    virtual ~GameMode() = default;
+    
+    virtual void initialize() = 0;
+    virtual bool update(float deltaTime) = 0;
+    virtual void render() = 0;
+    
+    GameModeType getType() const;
+    const std::string& getName() const;
+    const std::string& getDescription() const;
+};
+
+// Classic mode - original 2048 gameplay
+class ClassicMode : public GameMode {
+public:
+    ClassicMode();
+    void initialize() override;
+    bool update(float deltaTime) override;
+    void render() override;
+};
+
+// Timed mode - play against the clock
+class TimedMode : public GameMode {
+private:
+    float timeLimit;
+    float timeRemaining;
+    
+public:
+    TimedMode();
+    void initialize() override;
+    bool update(float deltaTime) override;
+    void render() override;
+    
+    float getTimeRemaining() const;
+};
+
+// PowerUp mode - special abilities and boosters
+class PowerUpMode : public GameMode {
+private:
+    int powerUpCount;
+    bool doubleScoreActive;
+    bool removeRowActive;
+    bool freezeTimeActive;
+    
+public:
+    PowerUpMode();
+    void initialize() override;
+    bool update(float deltaTime) override;
+    void render() override;
+    
+    void activatePowerUp(int type);
+};
+
+// Challenge mode - reach specific goals
+class ChallengeMode : public GameMode {
+private:
+    int targetScore;
+    int targetTile;
+    int movesLimit;
+    int movesUsed;
+    
+public:
+    ChallengeMode();
+    void initialize() override;
+    bool update(float deltaTime) override;
+    void render() override;
+};
+
+// Tutorial mode - learn to play
+class TutorialMode : public GameMode {
+private:
+    int tutorialStep;
+    bool waitingForInput;
+    
+public:
+    TutorialMode();
+    void initialize() override;
+    bool update(float deltaTime) override;
+    void render() override;
+    
+    void advanceTutorialStep();
+};
+
+#endif
\ No newline at end of file
diff --git a/include/UI.hpp b/include/UI.hpp
index 1e52a83003bb997c5b3254fdd82dbf87843a44f5..6f583b0e559456cf98f7c6f4f48648da2531801b 100644
--- a/include/UI.hpp
+++ b/include/UI.hpp
@@ -2,15 +2,80 @@
 #define UI_HPP
 
 #include <ncurses.h>
+#include <vector>
+#include <string>
 #include "2048.hpp"
+#include "GameMode.hpp"
+
+enum class UIState {
+    MAIN_MENU,
+    MODE_SELECTION,
+    GAME_PLAYING,
+    PAUSE_MENU,
+    GAME_OVER,
+    TUTORIAL
+};
 
 class UI {
+private:
+    UIState currentState;
+    int selectedMenuOption;
+    std::vector<std::string> mainMenuOptions;
+    std::vector<std::string> modeSelectionOptions;
+    std::vector<std::string> pauseMenuOptions;
+    GameModeType currentGameMode;
+    
+    // Window management
+    WINDOW* mainWindow;
+    WINDOW* gameWindow;
+    WINDOW* scoreWindow;
+    WINDOW* infoWindow;
+    
+    // For animations and transitions
+    float transitionTimer;
+    bool isTransitioning;
+
 public:
+    UI();
+    ~UI();
+    
+    void initialize();
     void drawBoard(const Game2048& game);
     void handleInput(Game2048& game);
-    void showGameOver(Game2048& game); // Modified to allow restart
+    void showGameOver(Game2048& game);
     void displayScore(const Game2048& game);
-    void displayInstructions(); // New method to show game instructions
+    void displayInstructions();
+    
+    // New menu-related methods
+    void drawMainMenu();
+    void drawModeSelection();
+    void drawPauseMenu();
+    void handleMenuInput();
+    
+    // Game mode management
+    void setGameMode(GameModeType mode);
+    GameModeType getGameMode() const;
+    
+    // Tutorial-specific rendering
+    void drawTutorial(int step);
+    
+    // PowerUp mode-specific UI
+    void drawPowerUpInterface(const PowerUpMode& powerUpMode);
+    
+    // Timed mode-specific UI
+    void drawTimerInterface(float timeRemaining);
+    
+    // Challenge mode-specific UI
+    void drawChallengeInterface(int targetScore, int targetTile, int movesRemaining);
+    
+    // State management
+    void setState(UIState newState);
+    UIState getState() const;
+    
+    // Utility methods
+    void drawCenteredText(WINDOW* win, int y, const std::string& text, bool highlight = false);
+    void createWindows();
+    void destroyWindows();
 };
 
 #endif
\ No newline at end of file
diff --git a/obj/2048.o b/obj/2048.o
new file mode 100644
index 0000000000000000000000000000000000000000..4cf51d0ff32df9b8ccd4253c4c7450419797ce66
Binary files /dev/null and b/obj/2048.o differ
diff --git a/src/Extra.o b/obj/Extra.o
similarity index 100%
rename from src/Extra.o
rename to obj/Extra.o
diff --git a/obj/GameMode.o b/obj/GameMode.o
new file mode 100644
index 0000000000000000000000000000000000000000..89923a74ad3a2e02561691fad69613a1ba3df67b
Binary files /dev/null and b/obj/GameMode.o differ
diff --git a/src/Tile.o b/obj/Tile.o
similarity index 100%
rename from src/Tile.o
rename to obj/Tile.o
diff --git a/obj/UI.o b/obj/UI.o
new file mode 100644
index 0000000000000000000000000000000000000000..9d33e9f70128cb9f24de4a552ec79a45c72dd76e
Binary files /dev/null and b/obj/UI.o differ
diff --git a/obj/main.o b/obj/main.o
new file mode 100644
index 0000000000000000000000000000000000000000..cbacafd64565d02669a72545504e1172c2d17029
Binary files /dev/null and b/obj/main.o differ
diff --git a/src/2048.cpp b/src/2048.cpp
index dd59286d8271c2b77d812ad18cef2eee55370d2f..c775f6dd3c52f0391f4c4f9e89e94b66fb38ba70 100644
--- a/src/2048.cpp
+++ b/src/2048.cpp
@@ -36,16 +36,6 @@ void Game2048::addToScore(int value) {
     score += value;
 }
 
-void Game2048::drawBoard() {
-    clear();
-    for (int i = 0; i < SIZE; ++i) {
-        for (int j = 0; j < SIZE; ++j) {
-            mvprintw(i * 2, j * 5, "%4d", board[i][j].getValue());
-        }
-    }
-    refresh();
-}
-
 void Game2048::moveLeft() {
     moved = false;
     for (int i = 0; i < SIZE; ++i) {
@@ -163,4 +153,4 @@ int Game2048::getScore() const {
 
 const Tile (*Game2048::getBoard() const)[SIZE] {
     return board;
-}
\ No newline at end of file
+}
diff --git a/src/2048.o b/src/2048.o
deleted file mode 100644
index 8980af415a3af453f1c2406f739659a30b323ac5..0000000000000000000000000000000000000000
Binary files a/src/2048.o and /dev/null differ
diff --git a/src/GameMode.cpp b/src/GameMode.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d5e605b899ad14246ae04cbbd264d71b1fc35f03
--- /dev/null
+++ b/src/GameMode.cpp
@@ -0,0 +1,150 @@
+#include "GameMode.hpp"
+#include <ncurses.h>
+
+GameMode::GameMode(GameModeType type, const std::string& name, const std::string& description)
+    : type(type), name(name), description(description) {
+}
+
+GameModeType GameMode::getType() const {
+    return type;
+}
+
+const std::string& GameMode::getName() const {
+    return name;
+}
+
+const std::string& GameMode::getDescription() const {
+    return description;
+}
+
+// Classic Mode Implementation
+ClassicMode::ClassicMode()
+    : GameMode(GameModeType::CLASSIC, "Classic", "The original 2048 game. Combine tiles to reach 2048!") {
+}
+
+void ClassicMode::initialize() {
+    // Nothing special needed for classic mode
+}
+
+bool ClassicMode::update(float deltaTime) {
+    // Classic mode has no time-based updates
+    return true;
+}
+
+void ClassicMode::render() {
+    // Rendering handled by the main UI class
+}
+
+// Timed Mode Implementation
+TimedMode::TimedMode()
+    : GameMode(GameModeType::TIMED, "Timed", "Race against the clock! Score as high as possible before time runs out."),
+      timeLimit(180.0f), // 3 minutes
+      timeRemaining(180.0f) {
+}
+
+void TimedMode::initialize() {
+    timeRemaining = timeLimit;
+}
+
+bool TimedMode::update(float deltaTime) {
+    timeRemaining -= deltaTime;
+    return timeRemaining > 0.0f;
+}
+
+void TimedMode::render() {
+    // Rendering handled by the UI class
+}
+
+float TimedMode::getTimeRemaining() const {
+    return timeRemaining;
+}
+
+// PowerUp Mode Implementation
+PowerUpMode::PowerUpMode()
+    : GameMode(GameModeType::POWERUP, "Power-Up", "Use special powers to boost your score!"),
+      powerUpCount(3),
+      doubleScoreActive(false),
+      removeRowActive(false),
+      freezeTimeActive(false) {
+}
+
+void PowerUpMode::initialize() {
+    powerUpCount = 3;
+    doubleScoreActive = false;
+    removeRowActive = false;
+    freezeTimeActive = false;
+}
+
+bool PowerUpMode::update(float deltaTime) {
+    // Power-up specific logic
+    return true;
+}
+
+void PowerUpMode::render() {
+    // Rendering handled by the UI class
+}
+
+void PowerUpMode::activatePowerUp(int type) {
+    if (powerUpCount <= 0) return;
+    
+    powerUpCount--;
+    
+    switch (type) {
+        case 1: // Double score
+            doubleScoreActive = true;
+            break;
+        case 2: // Remove row
+            removeRowActive = true;
+            break;
+        case 3: // Freeze time
+            freezeTimeActive = true;
+            break;
+    }
+}
+
+// Challenge Mode Implementation
+ChallengeMode::ChallengeMode()
+    : GameMode(GameModeType::CHALLENGE, "Challenge", "Complete specific objectives within constraints."),
+      targetScore(5000),
+      targetTile(512),
+      movesLimit(100),
+      movesUsed(0) {
+}
+
+void ChallengeMode::initialize() {
+    movesUsed = 0;
+}
+
+bool ChallengeMode::update(float deltaTime) {
+    return movesUsed < movesLimit;
+}
+
+void ChallengeMode::render() {
+    // Rendering handled by the UI class
+}
+
+// Tutorial Mode Implementation
+TutorialMode::TutorialMode()
+    : GameMode(GameModeType::TUTORIAL, "Tutorial", "Learn how to play 2048."),
+      tutorialStep(0),
+      waitingForInput(true) {
+}
+
+void TutorialMode::initialize() {
+    tutorialStep = 0;
+    waitingForInput = true;
+}
+
+bool TutorialMode::update(float deltaTime) {
+    // Tutorial is not time-based
+    return true;
+}
+
+void TutorialMode::render() {
+    // Rendering handled by the UI class
+}
+
+void TutorialMode::advanceTutorialStep() {
+    tutorialStep++;
+    waitingForInput = true;
+}
\ No newline at end of file
diff --git a/src/UI.cpp b/src/UI.cpp
index 630870ca801c9bfe897577fda39d6e8a7c25c13e..3486cb957467fe2b8726820ea6568291f560e777 100644
--- a/src/UI.cpp
+++ b/src/UI.cpp
@@ -1,16 +1,182 @@
 #include "UI.hpp"
 #include "2048.hpp"
 #include "Extra.hpp"
+#include "GameMode.hpp"
 #include <ncurses.h>
 #include <cstdlib>
+#include <chrono>
+
+UI::UI() : currentState(UIState::MAIN_MENU), selectedMenuOption(0), 
+    mainWindow(nullptr), gameWindow(nullptr), scoreWindow(nullptr), infoWindow(nullptr),
+    transitionTimer(0.0f), isTransitioning(false), currentGameMode(GameModeType::CLASSIC) {
+    
+    // Initialize menu options
+    mainMenuOptions = {"Play Game", "Select Mode", "Tutorial", "Quit"};
+    modeSelectionOptions = {"Classic", "Timed", "Power-Up", "Challenge", "Back"};
+    pauseMenuOptions = {"Resume", "Restart", "Main Menu", "Quit"};
+}
+
+UI::~UI() {
+    destroyWindows();
+}
+
+void UI::initialize() {
+    createWindows();
+}
+
+void UI::createWindows() {
+    int maxY, maxX;
+    getmaxyx(stdscr, maxY, maxX);
+    
+    // Main window covers the entire screen
+    mainWindow = newwin(maxY, maxX, 0, 0);
+    keypad(mainWindow, TRUE);
+    
+    // Game window for the actual 2048 board
+    gameWindow = newwin(SIZE * 2 + 2, SIZE * 6 + 2, 2, (maxX - (SIZE * 6 + 2)) / 2);
+    box(gameWindow, 0, 0);
+    
+    // Score window for displaying score and other game info
+    scoreWindow = newwin(3, 20, 2, maxX - 25);
+    box(scoreWindow, 0, 0);
+    
+    // Info window for instructions and status messages
+    infoWindow = newwin(5, maxX - 4, maxY - 6, 2);
+    box(infoWindow, 0, 0);
+}
+
+void UI::destroyWindows() {
+    if (mainWindow) delwin(mainWindow);
+    if (gameWindow) delwin(gameWindow);
+    if (scoreWindow) delwin(scoreWindow);
+    if (infoWindow) delwin(infoWindow);
+}
+
+void UI::setState(UIState newState) {
+    currentState = newState;
+    selectedMenuOption = 0;
+    isTransitioning = true;
+    transitionTimer = 0.5f;
+}
+
+UIState UI::getState() const {
+    return currentState;
+}
+
+void UI::drawCenteredText(WINDOW* win, int y, const std::string& text, bool highlight) {
+    int maxX, maxY;
+    getmaxyx(win, maxY, maxX);
+    int x = (maxX - text.length()) / 2;
+    
+    if (highlight) wattron(win, A_REVERSE);
+    mvwprintw(win, y, x, "%s", text.c_str());
+    if (highlight) wattroff(win, A_REVERSE);
+}
+
+void UI::drawMainMenu() {
+    werase(mainWindow);
+    
+    int maxY, maxX;
+    getmaxyx(mainWindow, maxY, maxX);
+    
+    // Title with color
+    wattron(mainWindow, COLOR_PAIR(COLOR_PAIR_2048) | A_BOLD);
+    drawCenteredText(mainWindow, maxY / 4, "2048 GAME", false);
+    wattroff(mainWindow, COLOR_PAIR(COLOR_PAIR_2048) | A_BOLD);
+    
+    // Menu options
+    for (size_t i = 0; i < mainMenuOptions.size(); i++) {
+        drawCenteredText(mainWindow, maxY / 3 + i * 2, mainMenuOptions[i], i == selectedMenuOption);
+    }
+    
+    // Footer
+    wattron(mainWindow, A_DIM);
+    drawCenteredText(mainWindow, maxY - 2, "Use UP/DOWN to navigate, ENTER to select", false);
+    wattroff(mainWindow, A_DIM);
+    
+    wrefresh(mainWindow);
+}
+
+void UI::drawModeSelection() {
+    werase(mainWindow);
+    
+    int maxY, maxX;
+    getmaxyx(mainWindow, maxY, maxX);
+    
+    // Title
+    wattron(mainWindow, COLOR_PAIR(COLOR_PAIR_1024) | A_BOLD);
+    drawCenteredText(mainWindow, maxY / 4, "SELECT GAME MODE", false);
+    wattroff(mainWindow, COLOR_PAIR(COLOR_PAIR_1024) | A_BOLD);
+    
+    // Mode options
+    for (size_t i = 0; i < modeSelectionOptions.size(); i++) {
+        drawCenteredText(mainWindow, maxY / 3 + i * 2, modeSelectionOptions[i], i == selectedMenuOption);
+    }
+    
+    // Mode description (if one is selected)
+    if (selectedMenuOption < 4) {
+        std::string description;
+        switch (selectedMenuOption) {
+            case 0: description = "Classic 2048 - Combine tiles to reach 2048!"; break;
+            case 1: description = "Timed Mode - Race against the clock!"; break;
+            case 2: description = "Power-Up Mode - Use special abilities!"; break;
+            case 3: description = "Challenge Mode - Complete specific objectives!"; break;
+        }
+        
+        wattron(mainWindow, A_DIM);
+        drawCenteredText(mainWindow, maxY / 3 + modeSelectionOptions.size() * 2 + 2, description, false);
+        wattroff(mainWindow, A_DIM);
+    }
+    
+    // Navigation help
+    wattron(mainWindow, A_DIM);
+    drawCenteredText(mainWindow, maxY - 2, "Use UP/DOWN to navigate, ENTER to select", false);
+    wattroff(mainWindow, A_DIM);
+    
+    wrefresh(mainWindow);
+}
+
+void UI::drawPauseMenu() {
+    // Dim the background
+    wattron(mainWindow, A_DIM);
+    for (int y = 0; y < getmaxy(mainWindow); y++) {
+        for (int x = 0; x < getmaxx(mainWindow); x++) {
+            mvwaddch(mainWindow, y, x, ' ');
+        }
+    }
+    wattroff(mainWindow, A_DIM);
+    
+    // Draw pause menu box
+    int maxY, maxX;
+    getmaxyx(mainWindow, maxY, maxX);
+    
+    int boxHeight = pauseMenuOptions.size() * 2 + 4;
+    int boxWidth = 20;
+    int boxY = (maxY - boxHeight) / 2;
+    int boxX = (maxX - boxWidth) / 2;
+    
+    WINDOW* pauseWin = subwin(mainWindow, boxHeight, boxWidth, boxY, boxX);
+    box(pauseWin, 0, 0);
+    
+    // Title
+    wattron(pauseWin, A_BOLD);
+    drawCenteredText(pauseWin, 1, "PAUSED", false);
+    wattroff(pauseWin, A_BOLD);
+    
+    // Menu options
+    for (size_t i = 0; i < pauseMenuOptions.size(); i++) {
+        drawCenteredText(pauseWin, 3 + i * 2, pauseMenuOptions[i], i == selectedMenuOption);
+    }
+    
+    wrefresh(pauseWin);
+    delwin(pauseWin);
+}
 
 void UI::drawBoard(const Game2048& game) {
-    clear();
+    if (currentState != UIState::GAME_PLAYING) return;
     
-    // Display title
-    attron(A_BOLD);
-    mvprintw(0, 0, "2048 Game");
-    attroff(A_BOLD);
+    werase(gameWindow);
+    box(gameWindow, 0, 0);
     
     // Display the board
     for (int i = 0; i < SIZE; ++i) {
@@ -19,69 +185,372 @@ void UI::drawBoard(const Game2048& game) {
             int colorPair = getTileColorPair(value);
             
             // Calculate position for the tile
-            int yPos = i * 2 + 2;
-            int xPos = j * 6;
+            int yPos = i * 2 + 1;
+            int xPos = j * 6 + 1;
             
             // Draw the tile with color
-            attron(COLOR_PAIR(colorPair) | A_BOLD);
+            wattron(gameWindow, COLOR_PAIR(colorPair) | A_BOLD);
             if (value != 0) {
-                mvprintw(yPos, xPos, "%5d", value);
+                mvwprintw(gameWindow, yPos, xPos, "%5d", value);
             } else {
-                mvprintw(yPos, xPos, "     "); // Empty tile
+                mvwprintw(gameWindow, yPos, xPos, "     "); // Empty tile
             }
-            attroff(COLOR_PAIR(colorPair) | A_BOLD);
+            wattroff(gameWindow, COLOR_PAIR(colorPair) | A_BOLD);
         }
     }
     
-    // Display the score with highlight
-    displayScore(game);
+    wrefresh(gameWindow);
+    
+    // Update score window
+    werase(scoreWindow);
+    box(scoreWindow, 0, 0);
+    
+    wattron(scoreWindow, COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
+    mvwprintw(scoreWindow, 1, 2, "Score: %d", game.getScore());
+    wattroff(scoreWindow, COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
+    
+    wrefresh(scoreWindow);
+    
+    // Update info window
+    werase(infoWindow);
+    box(infoWindow, 0, 0);
+    
+    mvwprintw(infoWindow, 1, 2, "Controls: Arrow keys to move");
+    mvwprintw(infoWindow, 2, 2, "P: Pause, R: Restart, Q: Quit");
     
-    // Display instructions
-    displayInstructions();
+    if (currentGameMode == GameModeType::TIMED) {
+        mvwprintw(infoWindow, 3, 2, "Time left: %.1f", 180.0f); // Placeholder value
+    } else if (currentGameMode == GameModeType::POWERUP) {
+        mvwprintw(infoWindow, 3, 2, "Power-ups: 3  (1-3 to use)");
+    } else if (currentGameMode == GameModeType::CHALLENGE) {
+        mvwprintw(infoWindow, 3, 2, "Target: 512  Moves: 50/100");
+    }
     
-    refresh();
+    wrefresh(infoWindow);
 }
 
-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::drawTimerInterface(float timeRemaining) {
+    mvwprintw(infoWindow, 3, 2, "Time left: %.1f", timeRemaining);
+    wrefresh(infoWindow);
 }
 
-void UI::displayInstructions() {
-    mvprintw(SIZE * 2 + 4, 0, "Controls: Arrow keys to move, 'r' to restart, 'q' to quit");
+void UI::drawPowerUpInterface(const PowerUpMode& powerUpMode) {
+    mvwprintw(infoWindow, 3, 2, "Power-ups available: %d", 3); // Placeholder
+    mvwprintw(infoWindow, 4, 2, "1: Double Score, 2: Clear Row, 3: Undo");
+    wrefresh(infoWindow);
+}
+
+void UI::drawChallengeInterface(int targetScore, int targetTile, int movesRemaining) {
+    mvwprintw(infoWindow, 3, 2, "Target: %d tile  Score: %d", targetTile, targetScore);
+    mvwprintw(infoWindow, 4, 2, "Moves remaining: %d", movesRemaining);
+    wrefresh(infoWindow);
+}
+
+void UI::drawTutorial(int step) {
+    werase(mainWindow);
+    
+    int maxY, maxX;
+    getmaxyx(mainWindow, maxY, maxX);
+    
+    // Title
+    wattron(mainWindow, COLOR_PAIR(COLOR_PAIR_16) | A_BOLD);
+    drawCenteredText(mainWindow, 2, "TUTORIAL", false);
+    wattroff(mainWindow, COLOR_PAIR(COLOR_PAIR_16) | A_BOLD);
+    
+    // Tutorial content
+    std::string content;
+    switch (step) {
+        case 0:
+            content = "Welcome to 2048!";
+            mvwprintw(mainWindow, 5, 5, "In this game, you combine tiles with the same number");
+            mvwprintw(mainWindow, 6, 5, "to create a tile with the sum of those numbers.");
+            mvwprintw(mainWindow, 8, 5, "The goal is to create a tile with the value 2048.");
+            break;
+        case 1:
+            content = "Controls";
+            mvwprintw(mainWindow, 5, 5, "Use the arrow keys to move all tiles in that direction.");
+            mvwprintw(mainWindow, 6, 5, "When two tiles with the same number touch, they merge!");
+            mvwprintw(mainWindow, 8, 5, "Press 'r' to restart and 'q' to quit.");
+            break;
+        case 2:
+            content = "Game Modes";
+            mvwprintw(mainWindow, 5, 5, "Classic: Traditional 2048 gameplay");
+            mvwprintw(mainWindow, 6, 5, "Timed: Race against the clock");
+            mvwprintw(mainWindow, 7, 5, "Power-Up: Use special abilities");
+            mvwprintw(mainWindow, 8, 5, "Challenge: Meet specific objectives");
+            break;
+        case 3:
+            content = "Strategy";
+            mvwprintw(mainWindow, 5, 5, "Try to keep your highest tile in a corner.");
+            mvwprintw(mainWindow, 6, 5, "Plan your moves ahead. Don't make hasty decisions.");
+            mvwprintw(mainWindow, 7, 5, "Sometimes it's better to not merge tiles immediately.");
+            mvwprintw(mainWindow, 8, 5, "Focus on building up one corner of the board.");
+            break;
+        case 4:
+            content = "Ready to Play!";
+            mvwprintw(mainWindow, 5, 5, "You've completed the tutorial!");
+            mvwprintw(mainWindow, 6, 5, "Now it's time to play the game and reach 2048!");
+            mvwprintw(mainWindow, 8, 5, "Good luck!");
+            break;
+        default:
+            content = "End of Tutorial";
+            mvwprintw(mainWindow, 5, 5, "You're ready to play 2048!");
+            break;
+    }
+    
+    wattron(mainWindow, A_BOLD);
+    drawCenteredText(mainWindow, 3, content, false);
+    wattroff(mainWindow, A_BOLD);
+    
+    // Navigation
+    wattron(mainWindow, A_DIM);
+    if (step < 4) {
+        drawCenteredText(mainWindow, maxY - 2, "Press SPACE to continue or ESC to exit", false);
+    } else {
+        drawCenteredText(mainWindow, maxY - 2, "Press ESC to return to main menu", false);
+    }
+    wattroff(mainWindow, A_DIM);
+    
+    wrefresh(mainWindow);
 }
 
 void UI::handleInput(Game2048& game) {
-    int ch = getch();
-    switch (ch) {
-        case KEY_LEFT: game.moveLeft(); break;
-        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
+    switch (currentState) {
+        case UIState::MAIN_MENU:
+            handleMenuInput();
+            break;
+            
+        case UIState::MODE_SELECTION:
+            handleMenuInput();
+            break;
+            
+        case UIState::GAME_PLAYING: {
+            int ch = wgetch(mainWindow);
+            switch (ch) {
+                case KEY_LEFT: game.moveLeft(); break;
+                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;
+                case 'p': case 'P': setState(UIState::PAUSE_MENU); break;
+                case 'q': case 'Q': setState(UIState::MAIN_MENU); break;
+                    
+                // PowerUp mode specific keys
+                case '1':
+                    if (currentGameMode == GameModeType::POWERUP) {
+                        // Activate power-up 1 (would need PowerUpMode instance)
+                    }
+                    break;
+                case '2':
+                    if (currentGameMode == GameModeType::POWERUP) {
+                        // Activate power-up 2
+                    }
+                    break;
+                case '3':
+                    if (currentGameMode == GameModeType::POWERUP) {
+                        // Activate power-up 3
+                    }
+                    break;
+            }
+            break;
+        }
+            
+        case UIState::PAUSE_MENU:
+            handleMenuInput();
+            break;
+            
+        case UIState::GAME_OVER: {
+            int ch = wgetch(mainWindow);
+            if (ch == 'r' || ch == 'R') {
+                game.resetBoard();
+                setState(UIState::GAME_PLAYING);
+            } else if (ch == 'q' || ch == 'Q' || ch == 27) { // 27 is ESC
+                setState(UIState::MAIN_MENU);
+            }
+            break;
+        }
+            
+        case UIState::TUTORIAL: {
+            int ch = wgetch(mainWindow);
+            static int tutorialStep = 0;
+            
+            if (ch == ' ') {
+                tutorialStep++;
+                if (tutorialStep > 4) {
+                    setState(UIState::MAIN_MENU);
+                    tutorialStep = 0;
+                } else {
+                    drawTutorial(tutorialStep);
+                }
+            } else if (ch == 27) { // ESC
+                setState(UIState::MAIN_MENU);
+                tutorialStep = 0;
+            }
+            break;
+        }
+    }
+}
+
+void UI::handleMenuInput() {
+    int ch = wgetch(mainWindow);
+    
+    switch (currentState) {
+        case UIState::MAIN_MENU:
+            if (ch == KEY_UP) {
+                selectedMenuOption = (selectedMenuOption - 1 + mainMenuOptions.size()) % mainMenuOptions.size();
+                drawMainMenu();
+            } else if (ch == KEY_DOWN) {
+                selectedMenuOption = (selectedMenuOption + 1) % mainMenuOptions.size();
+                drawMainMenu();
+            } else if (ch == 10 || ch == KEY_ENTER) { // Enter key
+                switch (selectedMenuOption) {
+                    case 0: // Play Game
+                        setState(UIState::GAME_PLAYING);
+                        break;
+                    case 1: // Select Mode
+                        setState(UIState::MODE_SELECTION);
+                        break;
+                    case 2: // Tutorial
+                        setState(UIState::TUTORIAL);
+                        drawTutorial(0);
+                        break;
+                    case 3: // Quit
+                        endwin();
+                        exit(0);
+                        break;
+                }
+            }
+            break;
+            
+        case UIState::MODE_SELECTION:
+            if (ch == KEY_UP) {
+                selectedMenuOption = (selectedMenuOption - 1 + modeSelectionOptions.size()) % modeSelectionOptions.size();
+                drawModeSelection();
+            } else if (ch == KEY_DOWN) {
+                selectedMenuOption = (selectedMenuOption + 1) % modeSelectionOptions.size();
+                drawModeSelection();
+            } else if (ch == 10 || ch == KEY_ENTER) { // Enter key
+                switch (selectedMenuOption) {
+                    case 0: // Classic
+                        setGameMode(GameModeType::CLASSIC);
+                        setState(UIState::GAME_PLAYING);
+                        break;
+                    case 1: // Timed
+                        setGameMode(GameModeType::TIMED);
+                        setState(UIState::GAME_PLAYING);
+                        break;
+                    case 2: // Power-Up
+                        setGameMode(GameModeType::POWERUP);
+                        setState(UIState::GAME_PLAYING);
+                        break;
+                    case 3: // Challenge
+                        setGameMode(GameModeType::CHALLENGE);
+                        setState(UIState::GAME_PLAYING);
+                        break;
+                    case 4: // Back
+                        setState(UIState::MAIN_MENU);
+                        break;
+                }
+            } else if (ch == 27) { // ESC
+                setState(UIState::MAIN_MENU);
+            }
+            break;
+            
+        case UIState::PAUSE_MENU:
+            if (ch == KEY_UP) {
+                selectedMenuOption = (selectedMenuOption - 1 + pauseMenuOptions.size()) % pauseMenuOptions.size();
+                drawPauseMenu();
+            } else if (ch == KEY_DOWN) {
+                selectedMenuOption = (selectedMenuOption + 1) % pauseMenuOptions.size();
+                drawPauseMenu();
+            } else if (ch == 10 || ch == KEY_ENTER) { // Enter key
+                switch (selectedMenuOption) {
+                    case 0: // Resume
+                        setState(UIState::GAME_PLAYING);
+                        break;
+                    case 1: // Restart
+                        // Need to reset the game
+                        setState(UIState::GAME_PLAYING);
+                        break;
+                    case 2: // Main Menu
+                        setState(UIState::MAIN_MENU);
+                        break;
+                    case 3: // Quit
+                        endwin();
+                        exit(0);
+                        break;
+                }
+            } else if (ch == 27 || ch == 'p' || ch == 'P') { // ESC or P to resume
+                setState(UIState::GAME_PLAYING);
+            }
+            break;
     }
 }
 
 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);
+    // Dim the background
+    wattron(mainWindow, A_DIM);
+    for (int y = 0; y < getmaxy(mainWindow); y++) {
+        for (int x = 0; x < getmaxx(mainWindow); x++) {
+            mvwaddch(mainWindow, y, x, ' ');
+        }
+    }
+    wattroff(mainWindow, A_DIM);
+    
+    // Create a popup window
+    int maxY, maxX;
+    getmaxyx(mainWindow, maxY, maxX);
+    
+    int boxHeight = 7;
+    int boxWidth = 30;
+    int boxY = (maxY - boxHeight) / 2;
+    int boxX = (maxX - boxWidth) / 2;
+    
+    WINDOW* gameOverWin = subwin(mainWindow, boxHeight, boxWidth, boxY, boxX);
+    box(gameOverWin, 0, 0);
     
-    mvprintw(SIZE * 2 + 7, 0, "Press 'r' to restart or 'q' to quit");
-    refresh();
+    // Title
+    wattron(gameOverWin, COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
+    drawCenteredText(gameOverWin, 1, "GAME OVER!", false);
+    wattroff(gameOverWin, COLOR_PAIR(COLOR_PAIR_HIGHER) | A_BOLD);
     
+    // Score
+    std::string scoreText = "Final Score: " + std::to_string(game.getScore());
+    drawCenteredText(gameOverWin, 3, scoreText, false);
+    
+    // Options
+    drawCenteredText(gameOverWin, 5, "R: Restart  Q: Quit", false);
+    
+    wrefresh(gameOverWin);
+    
+    // Wait for input
     while (true) {
-        int ch = getch();
+        int ch = wgetch(gameOverWin);
         if (ch == 'r' || ch == 'R') {
             game.resetBoard();
+            setState(UIState::GAME_PLAYING);
+            break;
+        } else if (ch == 'q' || ch == 'Q' || ch == 27) { // Q or ESC
+            setState(UIState::MAIN_MENU);
             break;
-        } else if (ch == 'q' || ch == 'Q') {
-            endwin();
-            exit(0);
         }
     }
-}
\ No newline at end of file
+    
+    delwin(gameOverWin);
+}
+
+void UI::setGameMode(GameModeType mode) {
+    currentGameMode = mode;
+}
+
+GameModeType UI::getGameMode() const {
+    return currentGameMode;
+}
+
+void UI::displayScore(const Game2048& game) {
+    // This is now handled in drawBoard
+}
+
+void UI::displayInstructions() {
+    // This is now handled in drawBoard with the info window
+}
diff --git a/src/UI.o b/src/UI.o
deleted file mode 100644
index 30433495b505e870cdf9860ba7f717ff9de76884..0000000000000000000000000000000000000000
Binary files a/src/UI.o and /dev/null differ
diff --git a/src/main.cpp b/src/main.cpp
index 8708fb433038bf557f1965c71437a41a2a6c18e5..934ac4ed69c018f3dcb34f24f595f52e2b151c73 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,19 @@
 #include "2048.hpp"
 #include "UI.hpp"
 #include "Extra.hpp"
+#include "GameMode.hpp"
 #include <ncurses.h>
+#include <chrono>
+#include <thread>
+
+// Helper function for tracking time
+float getDeltaTime() {
+    static auto lastTime = std::chrono::high_resolution_clock::now();
+    auto currentTime = std::chrono::high_resolution_clock::now();
+    std::chrono::duration<float> duration = currentTime - lastTime;
+    lastTime = currentTime;
+    return duration.count();
+}
 
 int main() {
     // Initialize the game and colors
@@ -9,18 +21,71 @@ int main() {
 
     Game2048 game;
     UI ui;
-
-    ui.drawBoard(game);
-
+    ui.initialize();
+    
+    // Create game mode instances
+    ClassicMode classicMode;
+    TimedMode timedMode;
+    PowerUpMode powerUpMode;
+    ChallengeMode challengeMode;
+    TutorialMode tutorialMode;
+    
+    // Show the main menu initially
+    ui.drawMainMenu();
+    
+    float timeRemaining = 180.0f; // For timed mode
+    
     while (true) {
+        float deltaTime = getDeltaTime();
+        
+        // Handle timing for timed mode
+        if (ui.getState() == UIState::GAME_PLAYING && ui.getGameMode() == GameModeType::TIMED) {
+            timeRemaining -= deltaTime;
+            ui.drawTimerInterface(timeRemaining);
+            
+            if (timeRemaining <= 0) {
+                ui.showGameOver(game);
+            }
+        }
+        
+        // Handle user input based on current state
         ui.handleInput(game);
-        ui.drawBoard(game);
-
-        if (!game.canMove()) {
-            ui.showGameOver(game);
-            // After restart, redraw the board
-            ui.drawBoard(game);
+        
+        // Update display based on current state
+        switch (ui.getState()) {
+            case UIState::MAIN_MENU:
+                ui.drawMainMenu();
+                break;
+                
+            case UIState::MODE_SELECTION:
+                ui.drawModeSelection();
+                break;
+                
+            case UIState::GAME_PLAYING:
+                ui.drawBoard(game);
+                
+                // Check for game over
+                if (!game.canMove()) {
+                    ui.showGameOver(game);
+                    ui.drawBoard(game);
+                }
+                break;
+                
+            case UIState::PAUSE_MENU:
+                ui.drawPauseMenu();
+                break;
+                
+            case UIState::GAME_OVER:
+                // Handled in showGameOver
+                break;
+                
+            case UIState::TUTORIAL:
+                // Handled in handleInput and drawTutorial
+                break;
         }
+        
+        // Sleep a bit to limit CPU usage
+        std::this_thread::sleep_for(std::chrono::milliseconds(50));
     }
 
     cleanupGame();
diff --git a/src/main.o b/src/main.o
deleted file mode 100644
index 618be4a5c4dc1eefa3ddc87ac01405fe3e818fbd..0000000000000000000000000000000000000000
Binary files a/src/main.o and /dev/null differ