diff --git a/README.md b/README.md index 63bdae936eddfb85f868628c2b7ea0cdc72f9db6..885284e6c2898b15d2376ce04f000012b5209faf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Enhanced 2048 Game by Jamal Enoime +A terminal-based version of the popular 2048 puzzle game with multiple game modes and visual enhancements. + ## Project Structure ``` 2048-game/ @@ -29,7 +31,7 @@ ``` ## Features -- **Interactive 2048-terminal clone**: +- **Interactive 2048-terminal clone** - **Multiple Game Modes**: - **Classic**: Traditional 2048 gameplay - **Timed**: Race against the clock @@ -60,11 +62,77 @@ ## Dependencies - NCurses: For terminal-based UI - SDL2 and SDL2_mixer: For sound and music - -### Issues -- The gameplay seems to fragment possibly due to a logical error in my code (**will revisit**) -- (REVISIT) to get a fully function version of my game with no bugs replace the following -- ui.cpp + +### Installing Dependencies + +#### For Ubuntu/Debian: +```bash +# Install NCurses +sudo apt-get install libncurses5-dev libncursesw5-dev + +# Install SDL2 and SDL2_mixer +sudo apt-get install libsdl2-dev libsdl2-mixer-dev +``` + +#### For macOS (with Homebrew): +```bash +brew install ncurses sdl2 sdl2_mixer +``` + +#### For Windows: +Use WSL (Windows Subsystem for Linux) and follow the Ubuntu/Debian instructions. + +### Setting Up Sound Files +For the music and sound effects to work properly: +1. Create directories for sounds and music: +```bash +mkdir -p res/sounds res/music +``` +2. Place your sound effect files in the `res/sounds` directory +3. Place your background music files in the `res/music` directory +4. Supported audio formats include WAV, MP3, and OGG (depending on your SDL2_mixer build) + +## How to Build and Run +```bash +# Build the project +make + +# Run the game +./bin/2048 + +# Clean build files +make clean +``` + +## Controls +- Arrow keys: Move tiles / Navigate menus +- Enter: Select menu options +- P: Pause game +- R: Restart game +- Q/ESC: Quit/Return to menu + +## Special Mode Controls +- Power-Up Mode: + - 1: Activate double score + - 2: Clear a row + - 3: Undo move + - 4: Upgrade a tile + +- Zen Mode: + - C: Toggle color shift effect + +## Issues and Solutions + +### Known Issues +- **Gameplay Fragmentation**: The gameplay sometimes fragments due to a logical error in the code. +- **Sound Issues**: Sound files might not play correctly if not properly set up. + +### Solutions + +To get a fully functional version of the game with no bugs but fewer features, replace the following files with the code provided below: + +#### UI.cpp +```cpp #include "UI.hpp" #include <cmath> #include <algorithm> @@ -1055,7 +1123,10 @@ void UI::onGameOver() { void UI::onVictory() { setState(UIState::VICTORY); } --main.cpp +``` + +#### main.cpp +```cpp #include "UI.hpp" #include "Extra.hpp" #include <iostream> @@ -1087,7 +1158,10 @@ int main() { return 1; } } --extra.hpp +``` + +#### Extra.hpp +```cpp #ifndef EXTRA_HPP #define EXTRA_HPP @@ -1106,7 +1180,10 @@ void initColors(); int getTileColorPair(int value); #endif // EXTRA_HPP --extra.cpp +``` + +#### Extra.cpp +```cpp #include "Extra.hpp" #include <ncurses.h> @@ -1163,7 +1240,10 @@ int getTileColorPair(int value) { void cleanupGame() { endwin(); } --makefile +``` + +#### Makefile +```makefile CC = g++ CFLAGS = -std=c++11 -Wall -I include LDFLAGS = -lncurses @@ -1207,339 +1287,8 @@ run: all $(EXECUTABLE) .PHONY: all directories clean run --2048.hpp -// 2048.hpp -#ifndef GAME2048_HPP -#define GAME2048_HPP - -#include <vector> -#include <array> -#include <functional> -#include "Tile.hpp" - -#define SIZE 4 - -// Event types for observers -enum class GameEvent { - TILE_MOVED, - TILE_MERGED, - TILE_SPAWNED, - SCORE_CHANGED, - GAME_WON, - GAME_OVER -}; - -// Game state observer pattern -using GameEventCallback = std::function<void(GameEvent, int, int, int)>; - -class Game2048 { -private: - std::array<std::array<Tile, SIZE>, SIZE> board; - std::array<std::array<Tile, SIZE>, SIZE> previousBoard; - bool moved; - int score; - int previousScore; - int highScore; - std::vector<GameEventCallback> observers; - - void spawnTile(); - void addToScore(int value); - void notifyObservers(GameEvent event, int row = -1, int col = -1, int value = 0); - void notifyObservers(GameEvent event, int fromRow, int fromCol, int toRow, int toCol, int value); - void saveBoardState(); - -public: - Game2048(); - void resetBoard(); - - // Movement methods - void moveLeft(); - void moveRight(); - void moveUp(); - void moveDown(); - - // Game state methods - bool canMove() const; - bool hasWon() const; - int getScore() const; - int getHighScore() const; - void undoMove(); - - // Special actions for power-ups - void clearRow(int row); - void clearColumn(int col); - void doubleScoreTile(int row, int col); - void upgradeTile(int row, int col); - - // Board access - const std::array<std::array<Tile, SIZE>, SIZE>& getBoard() const; - - // Observer pattern methods - void addObserver(GameEventCallback callback); - void removeAllObservers(); -}; - -#endif // GAME2048_HPP - -// Tile.hpp -#ifndef TILE_HPP -#define TILE_HPP - -class Tile { -private: - int value; - bool mergedThisTurn; - bool isNew; - float animationProgress; - -public: - Tile(); - - // Basic operations - void setValue(int val); - int getValue() const; - void setMerged(bool merged); - bool getMerged() const; - void setNew(bool newTile); - bool getNew() const; - - // Animation management - void setAnimationProgress(float progress); - float getAnimationProgress() const; - void resetAnimation(); - - // Operators - bool operator==(const Tile& other) const; - Tile& operator*=(int multiplier); - Tile& operator=(const Tile& other); -}; - -#endif // TILE_HPP - -// GameMode.hpp -#ifndef GAMEMODE_HPP -#define GAMEMODE_HPP - -#include <string> -#include <ncurses.h> // For KEY_ constants -#include "2048.hpp" - -enum class GameModeType { - CLASSIC, - TIMED, - POWERUP, - CHALLENGE, - ZEN, - TUTORIAL -}; - -// Base abstract class for all game modes -class GameMode { -protected: - GameModeType type; - std::string name; - std::string description; - bool gameOver; - bool gameWon; - -public: - GameMode(GameModeType type, const std::string& name, const std::string& description); - virtual ~GameMode() = default; - - // Pure virtual methods that derived classes must implement - virtual void initialize(Game2048& game) = 0; - virtual bool update(Game2048& game, float deltaTime) = 0; - virtual void handleInput(Game2048& game, int key) = 0; - virtual void render() = 0; - - // Common methods for all modes - GameModeType getType() const; - const std::string& getName() const; - const std::string& getDescription() const; - bool isGameOver() const; - bool isGameWon() const; - virtual void setGameOver(bool over); - virtual void setGameWon(bool won); -}; - -// Classic mode - original 2048 gameplay -class ClassicMode : public GameMode { -public: - ClassicMode(); - void initialize(Game2048& game) override; - bool update(Game2048& game, float deltaTime) override; - void handleInput(Game2048& game, int key) override; - void render() override; -}; - -#endif // GAMEMODE_HPP - -// UI.hpp -#ifndef UI_HPP -#define UI_HPP - -#include <ncurses.h> -#include <vector> -#include <string> -#include <memory> -#include "2048.hpp" -#include "GameMode.hpp" - -// UI states -enum class UIState { - MAIN_MENU, - MODE_SELECTION, - GAME_PLAYING, - PAUSE_MENU, - GAME_OVER, - VICTORY, - TUTORIAL, - SETTINGS, - EXIT_CONFIRM -}; - -class UI { -private: - // State management - UIState currentState; - UIState previousState; - int selectedMenuOption; - - // Menu options - std::vector<std::string> mainMenuOptions; - std::vector<std::string> modeSelectionOptions; - std::vector<std::string> pauseMenuOptions; - std::vector<std::string> settingsOptions; - - // Window management - WINDOW* mainWindow; - WINDOW* gameWindow; - WINDOW* scoreWindow; - WINDOW* infoWindow; - - // Game state - Game2048 game; - GameModeType currentGameMode; - - // Mode instances - std::unique_ptr<GameMode> gameMode; - - // Background and color management - float backgroundEffectTimer; - bool animationsEnabled; - - // Theme management - struct Theme { - std::string name; - }; - std::vector<Theme> themes; - int currentTheme; - - // Helper methods - void createWindows(); - void destroyWindows(); - void initializeThemes(); - void applyTheme(int themeIndex); - - // Drawing helpers - void drawCenteredText(WINDOW* win, int y, const std::string& text, bool highlight = false); - void drawBorderedWindow(WINDOW* win, const std::string& title = ""); - void drawTile(WINDOW* win, int row, int col, int value); - - // Event handlers - void handleMainMenuInput(); - void handleModeSelectionInput(); - void handleGameInput(); - void handlePauseMenuInput(); - void handleSettingsInput(); - void handleTutorialInput(); - void handleExitConfirmInput(); - - // Menu drawing - void drawMainMenu(); - void drawModeSelection(); - void drawPauseMenu(); - void drawSettings(); - void drawTutorial(); - void drawExitConfirm(); - - // Game UI - void drawBoard(); - void drawScore(); - void drawInfo(); - void drawGameOver(); - void drawVictory(); - - // Game event callbacks - void onTileMerged(int row, int col, int value); - void onTileSpawned(int row, int col, int value); - void onScoreChanged(int newScore, int prevScore); - void onGameOver(); - void onVictory(); - -public: - UI(); - ~UI(); - - // Initialization - bool initialize(); - - // Main game loop - void run(); - - // State management - void setState(UIState newState); - UIState getState() const; - - // Game mode management - void setGameMode(GameModeType mode); - GameModeType getGameMode() const; - - // Theme management - void setTheme(int themeIndex); - int getThemeCount() const; - std::string getThemeName(int index) const; - - // Settings - void toggleAnimations(); -}; - -#endif // UI_HPP - -## How to build and Run -```bash -# Build the project -need to install the dependencies for ncurses with this code **sudo apt-get install libncurses5-dev libncursesw5-dev** then in terminal type -make - -# Run the game -./bin/2048-game - -# Clean build files -make clean - - - -## Controls -- Arrow keys: Move tiles / Navigate menus -- Enter: Select menu options -- P: Pause game -- R: Restart game -- Q/ESC: Quit/Return to menu - -## Special Mode Controls -- Power-Up Mode: - - 1: Activate double score - - 2: Clear a row - - 3: Undo move - - 4: Upgrade a tile - -- Zen Mode: - - C: Toggle color shift effect - +``` +**this version can be run with *make run* in terminal** ## Credits Created by Jamal Enoime -Sound effects from freesound.org -Music from bensound.com -