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