From 81e9f04d1b9670ab5b22b6c91443e614470cd748 Mon Sep 17 00:00:00 2001
From: h3-alsaddi <hamed2.alsaddi@live.uwe.ac.uk>
Date: Wed, 12 Mar 2025 05:28:53 +0000
Subject: [PATCH] New changed

---
 game.cpp | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 221 insertions(+), 10 deletions(-)

diff --git a/game.cpp b/game.cpp
index a278b61..a0b9280 100644
--- a/game.cpp
+++ b/game.cpp
@@ -1,21 +1,232 @@
 #include "game.hpp"
 #include <iostream>
+#include <cstdlib>   // for rand, srand
+#include <ctime>     // for time
 
-Game::Game() {
-    // Constructor: could initialize variables here
-}
-
-void Game::start() {
-    std::cout << "Starting the game..." << std::endl;
+Game::Game() : score(0) {
+    // Seed random generator
+    std::srand(static_cast<unsigned int>(std::time(nullptr)));
     initBoard();
-    printBoard();
 }
 
+// -------------------------
+// 1) Initialize the board
+// -------------------------
 void Game::initBoard() {
-    // Set up game data here
+    for (int i = 0; i < SIZE; i++) {
+        for (int j = 0; j < SIZE; j++) {
+            board[i][j] = 0;
+        }
+    }
+    // Add two random tiles to start
+    addRandomTile();
+    addRandomTile();
+}
+
+void Game::addRandomTile() {
+    // Collect empty cells
+    int emptyCells[SIZE * SIZE][2];
+    int count = 0;
+
+    for (int i = 0; i < SIZE; i++) {
+        for (int j = 0; j < SIZE; j++) {
+            if (board[i][j] == 0) {
+                emptyCells[count][0] = i;
+                emptyCells[count][1] = j;
+                count++;
+            }
+        }
+    }
+
+    // If there's at least one empty cell, place a new tile
+    if (count > 0) {
+        int idx = std::rand() % count;
+        int row = emptyCells[idx][0];
+        int col = emptyCells[idx][1];
+
+        // 10% chance of 4, 90% chance of 2
+        int value = (std::rand() % 10 == 0) ? 4 : 2;
+        board[row][col] = value;
+    }
 }
 
+// -------------------------
+// 2) Movement Logic
+// -------------------------
+void Game::moveLeft() {
+    // Move each row to the left
+    for (int i = 0; i < SIZE; i++) {
+        int row[SIZE];
+        // Copy board row into a temporary array
+        for (int j = 0; j < SIZE; j++) {
+            row[j] = board[i][j];
+        }
+
+        // Compress (remove gaps)
+        compressRow(row);
+        // Merge adjacent tiles
+        mergeRow(row);
+        // Compress again to remove new gaps
+        compressRow(row);
+
+        // Copy the row back into the board
+        for (int j = 0; j < SIZE; j++) {
+            board[i][j] = row[j];
+        }
+    }
+}
+
+void Game::moveRight() {
+    // Reverse each row, move left, then reverse again
+    for (int i = 0; i < SIZE; i++) {
+        reverseRow(i);
+    }
+    moveLeft();
+    for (int i = 0; i < SIZE; i++) {
+        reverseRow(i);
+    }
+}
+
+void Game::moveUp() {
+    // Transpose, move left, transpose again
+    transpose();
+    moveLeft();
+    transpose();
+}
+
+void Game::moveDown() {
+    // Transpose, move right, transpose again
+    transpose();
+    moveRight();
+    transpose();
+}
+
+// -------------------------
+// 3) Movement Helpers
+// -------------------------
+void Game::reverseRow(int rowIndex) {
+    for (int j = 0; j < SIZE / 2; j++) {
+        int temp = board[rowIndex][j];
+        board[rowIndex][j] = board[rowIndex][SIZE - j - 1];
+        board[rowIndex][SIZE - j - 1] = temp;
+    }
+}
+
+void Game::transpose() {
+    for (int i = 0; i < SIZE; i++) {
+        for (int j = i + 1; j < SIZE; j++) {
+            int temp = board[i][j];
+            board[i][j] = board[j][i];
+            board[j][i] = temp;
+        }
+    }
+}
+
+// Compress row by moving all non-zero values to the front
+void Game::compressRow(int row[SIZE]) {
+    int temp[SIZE] = {0};
+    int idx = 0;
+    for (int i = 0; i < SIZE; i++) {
+        if (row[i] != 0) {
+            temp[idx] = row[i];
+            idx++;
+        }
+    }
+    for (int i = 0; i < SIZE; i++) {
+        row[i] = temp[i];
+    }
+}
+
+// Merge adjacent tiles if they are the same
+void Game::mergeRow(int row[SIZE]) {
+    for (int i = 0; i < SIZE - 1; i++) {
+        if (row[i] != 0 && row[i] == row[i + 1]) {
+            row[i] *= 2;
+            score += row[i];
+            row[i + 1] = 0;
+        }
+    }
+}
+
+// -------------------------
+// 4) Check for Game Over
+// -------------------------
+bool Game::checkGameOver() {
+    // If there's an empty cell, not over
+    if (hasEmptyCell()) {
+        return false;
+    }
+    // If a merge is possible, not over
+    if (canMerge()) {
+        return false;
+    }
+    // Otherwise, game over
+    return true;
+}
+
+bool Game::hasEmptyCell() {
+    for (int i = 0; i < SIZE; i++) {
+        for (int j = 0; j < SIZE; j++) {
+            if (board[i][j] == 0) return true;
+        }
+    }
+    return false;
+}
+
+bool Game::canMerge() {
+    // Check horizontally
+    for (int i = 0; i < SIZE; i++) {
+        for (int j = 0; j < SIZE - 1; j++) {
+            if (board[i][j] == board[i][j+1]) return true;
+        }
+    }
+    // Check vertically
+    for (int j = 0; j < SIZE; j++) {
+        for (int i = 0; i < SIZE - 1; i++) {
+            if (board[i][j] == board[i+1][j]) return true;
+        }
+    }
+    return false;
+}
+
+// -------------------------
+// 5) Display and Game Loop
+// -------------------------
 void Game::printBoard() {
-    // Print the game board or any other info
-    std::cout << "Board printed." << std::endl;
+    std::cout << "\nScore: " << score << "\n\n";
+    for (int i = 0; i < SIZE; i++) {
+        for (int j = 0; j < SIZE; j++) {
+            std::cout << board[i][j] << "\t";
+        }
+        std::cout << "\n\n";
+    }
+}
+
+void Game::start() {
+    char input;
+    while (true) {
+        printBoard();
+        if (checkGameOver()) {
+            std::cout << "Game Over! Final Score: " << score << std::endl;
+            break;
+        }
+
+        std::cout << "Move [W=Up, A=Left, S=Down, D=Right, Q=Quit]: ";
+        std::cin >> input;
+
+        switch (input) {
+            case 'W': case 'w': moveUp();    break;
+            case 'S': case 's': moveDown();  break;
+            case 'A': case 'a': moveLeft();  break;
+            case 'D': case 'd': moveRight(); break;
+            case 'Q': case 'q': 
+                std::cout << "Quitting...\n";
+                return;
+            default:
+                std::cout << "Invalid input! Try again.\n";
+                continue;
+        }
+        // After a valid move, add a random tile
+        addRandomTile();
+    }
 }
-- 
GitLab