#include "game.hpp" #include #include #include #include #include #include #include #include #include using namespace std; // Structures struct paddle { int x; int width; string paddleChar; }; struct ball { int x; int y; int vx; int vy; }; struct brick { int x; int y; int width; bool isBroken; int color; int CTB; // Collision TO Break }; // Globals const int width = 81; const int height = 30; int FPS = 60; int frameDelay = 1000 / FPS; int goldenCount = 0; int TNTCount = 0; int HardCount = 0; int normalCount = 0; const int panelx = 130; const int panely = 5; int score = 0; int Broken = 0; int life = 3; int brickCol = 10; int brickRow = 5; const int brickWidth = 4; const int brickGap = 1; int brickColors[] = {9, 10, 11, 12, 13, 14}; brick bricks[14][8]; player Player = {}; paddle Paddle; ball Ball; // SetUp void HideCursor(bool visible) { HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO info; info.dwSize = 100; info.bVisible = visible; SetConsoleCursorInfo(consoleHandle, &info); } void initializeBricks(); void initializePaddle(paddle &paddle, int width); void initializeBall(ball &Ball); // Game void input(); void logic(ball &); // void render(); // void renderPanel(); bool game(); int gameDelay = 150; bool gameOver = false; bool bricksCount(); // Pause void render(string pause); void pauseMenu(); int pauseOption = 1; // Other Prototypes void explodeBricks(int col, int row); void nextStage(); // Game History player history[100] = {}; int historyCount = 0; // Load Game player loadedPlayer[100] = {}; int playerCount = 0; int loadOption = 1; // for delete record index // int main() // { // fstream file("loadGame.dat", ios::binary | ios::in | ios::out); // file.seekp(0); // player temp; // file.read(reinterpret_cast(&temp), sizeof(player)); // file.read(reinterpret_cast(&Ball), sizeof(ball)); // file.read(reinterpret_cast(&Paddle.width), sizeof(int)); // file.read(reinterpret_cast(&Paddle.x), sizeof(int)); // size_t len; // file.read(reinterpret_cast(&len), sizeof(len)); // cout << sizeof(len) << endl; // cout << len; // } bool game(int) { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); system("cls"); HideCursor(false); life = Player.life; score = Player.score; pauseOption = 1; renderPanel(); auto lastTime2 = std::chrono::steady_clock::now(); renderPanel(); while (!gameOver) { auto currentTime = std::chrono::steady_clock::now(); auto elapsedTime = std::chrono::duration_cast(currentTime - lastTime2).count(); // broken == 50? if (bricksCount()) { nextStage(); Sleep(1000); if (FPS < 120) { FPS += 20; } if (brickRow < 8) { brickRow++; } if (brickRow % 2 == 0 && brickCol < 14) { brickCol += 2; } initializeBricks(); initializePaddle(Paddle, width); initializeBall(Ball); } auto frameStart = std::chrono::steady_clock::now(); input(); if (pauseOption == 2) { return false; } else if (pauseOption >= 2) { return true; } logic(Ball); SetConsoleCursorPosition(h, {0, 5}); render(); auto frameTime = std::chrono::duration_cast(std::chrono::steady_clock::now() - frameStart).count(); if (frameDelay > frameTime) { Sleep(frameDelay - frameTime); // تنظیم فاصله زمانی برای رسیدن به FPS ثابت } } if (gameOver == true) { life--; } while (life > 0) { HideCursor(false); initializePaddle(Paddle, width); initializeBall(Ball); COORD cursor = {0, 5}; gameOver = false; auto lastTime = std::chrono::steady_clock::now(); SetConsoleCursorPosition(h, cursor); render(); renderPanel(); char start = _getch(); if (start == 27) { pauseMenu(); } while (!gameOver) { auto currentTime = std::chrono::steady_clock::now(); auto elapsedTime = std::chrono::duration_cast(currentTime - lastTime).count(); // broken == 50? if (bricksCount()) { nextStage(); Sleep(1000); if (FPS < 120) { FPS += 20; } if (brickRow < 8) { brickRow++; } if (brickRow % 2 == 0 && brickCol < 14) { brickCol += 2; } initializeBricks(); initializePaddle(Paddle, width); initializeBall(Ball); } input(); if (pauseOption == 2) { return false; } else if (pauseOption >= 2) { return true; } if (elapsedTime > 75) { logic(Ball); SetConsoleCursorPosition(h, cursor); render(); lastTime = currentTime; } } if (gameOver == true) { life--; } } return true; } bool game() { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); system("cls"); HideCursor(false); initializeBricks(); initializePaddle(Paddle, width); initializeBall(Ball); life = 3; score = 0; pauseOption = 1; Broken = 0; goldenCount = 0; TNTCount = 0; HardCount = 0; normalCount = 0; while (life > 0) { HideCursor(false); initializePaddle(Paddle, width); initializeBall(Ball); COORD cursor = {0, 5}; gameOver = false; auto lastTime = std::chrono::steady_clock::now(); SetConsoleCursorPosition(h, cursor); render(); renderPanel(); char start = _getch(); if (start == 27) { pauseMenu(); } while (!gameOver) { // broken == 50? if (bricksCount()) { nextStage(); Sleep(1000); if (brickRow < 8) { brickRow++; } if (brickRow % 2 == 0 && brickCol < 14) { brickCol += 2; } initializeBricks(); initializePaddle(Paddle, width); initializeBall(Ball); SetConsoleCursorPosition(h, cursor); HideCursor(false); Broken = 0; render(); renderPanel(); _getch(); } auto frameStart = std::chrono::steady_clock::now(); input(); if (pauseOption == 2) { return false; } else if (pauseOption >= 2) { return true; } logic(Ball); SetConsoleCursorPosition(h, cursor); render(); auto frameTime = std::chrono::duration_cast(std::chrono::steady_clock::now() - frameStart).count(); if (frameDelay > frameTime) { Sleep(frameDelay - frameTime); // تنظیم فاصله زمانی برای رسیدن به FPS ثابت } } if (gameOver == true) { life--; } } return true; } void initializeBricks() { int totalBrickWidth = brickCol * brickWidth + (brickCol - 1) * brickGap; int start = (width - totalBrickWidth) / 2; srand(time(0)); for (int col = 0; col < brickCol; col++) { for (int row = 0; row < brickRow; row++) { bricks[col][row].x = start + col * (brickWidth + brickGap); bricks[col][row].y = row * 2 + 3; bricks[col][row].width = brickWidth; bricks[col][row].isBroken = false; int r = rand() % 100; if (r < 20) { bricks[col][row].color = 9; } else if (r < 40) { bricks[col][row].color = 10; } // else if (r < 60) // { // bricks[col][row].color = 11; // } else if (r < 80) { bricks[col][row].color = 13; } else if (r < 90) { bricks[col][row].color = 12; } else { bricks[col][row].color = 14; } if (bricks[col][row].color == 9) { bricks[col][row].CTB = 2; } else { bricks[col][row].CTB = 1; } } } } void initializePaddle(paddle &Paddle, int width) { Paddle.width = 7; Paddle.paddleChar = "━"; Paddle.x = (width - Paddle.width) / 2; } void initializeBall(ball &Ball) { srand(time(0)); Ball.x = Paddle.x + 3; Ball.y = height - 3; int sign = rand() % 2; int value = rand() % 2 + 1; Ball.vx = sign == 0 ? 1 : -1; Ball.vy = value; } void render() { for (int y = 0; y < 30; y++) { cout << setw(45) << ""; for (int x = 0; x < 81; x++) { string c = " "; if (y == 0 && x == 0) { c = "┌"; } else if (y == 29 && x == 0) { c = "└"; } else if (y == 29 && x == 80) { c = "┘"; } else if (y == 0 && x == 80) { c = "┐"; } else if (y == 0 && (x > 0 && x < 80)) { c = "─"; } else if (y == 29 && (x > 0 && x < 80)) { c = "─"; } else if (x == 0 && (y > 0 && y < 29)) { c = "│"; } else if (x == 80 && (y > 0 && y < 29)) { c = "│"; } for (int col = 0; col < brickCol; col++) { for (int row = 0; row < brickRow; row++) { if (y == bricks[col][row].y && x >= bricks[col][row].x && x < bricks[col][row].x + bricks[col][row].width && bricks[col][row].isBroken == false) { setColor(bricks[col][row].color); c = "█"; } } } if (y == height - 2 && x >= Paddle.x && x < Paddle.x + Paddle.width) { c = Paddle.paddleChar; } if (x > 0 && x < width - 1 && y > 0 && y < height - 1) { if (x == Ball.x && y == Ball.y) c = "●"; } cout << c; setColor(7); } cout << endl; } } void render(string pause) { for (int y = 0; y < 30; y++) { cout << setw(45) << ""; for (int x = 0; x < 81; x++) { string c = " "; if (y == 0 && x == 0) { c = "┌"; } else if (y == 29 && x == 0) { c = "└"; } else if (y == 29 && x == 80) { c = "┘"; } else if (y == 0 && x == 80) { c = "┐"; } else if (y == 0 && (x > 0 && x < 80)) { c = "─"; } else if (y == 29 && (x > 0 && x < 80)) { c = "─"; } else if (x == 0 && (y > 0 && y < 29)) { c = "│"; } else if (x == 80 && (y > 0 && y < 29)) { c = "│"; } for (int col = 0; col < 10; col++) { for (int row = 0; row < 5; row++) { if (y == bricks[col][row].y && x >= bricks[col][row].x && x < bricks[col][row].x + bricks[col][row].width && bricks[col][row].isBroken == false) { c = "█"; } } } if (y == height - 2 && x >= Paddle.x && x < Paddle.x + Paddle.width) { c = Paddle.paddleChar; } if (x > 0 && x < width - 1 && y > 0 && y < height - 1) { if (x == Ball.x && y == Ball.y) c = "●"; } cout << c; } cout << endl; } } void input() { if (_kbhit()) { char input = _getch(); switch (input) { case 'D': case 'd': { if (Paddle.x + Paddle.width < 78 && (Ball.vx > 1 || Ball.vx < -1)) { Paddle.x += 3; } else if (Paddle.x + Paddle.width < 79) { Paddle.x += 2; } break; } case 'A': case 'a': { if (Paddle.x > 3 && (Ball.vx > 1 || Ball.vx < -1)) { Paddle.x -= 3; } else if (Paddle.x > 2) { Paddle.x -= 2; } break; } case 27: { pauseMenu(); switch (pauseOption) { case 2: { } } break; } } } } void playBeep(int F, int T) { thread t(Beep, F, T); t.detach(); } void bricksLogic(brick &B, int i, int j) { B.CTB--; if (B.color == 9 && B.CTB == 1) { playBeep(600 + 9 * 50, 60); B.color = 11; } if (B.CTB <= 0) { B.isBroken = true; if (B.color == 12) { TNTCount++; playBeep(600 + 12 * 50, 60); explodeBricks(i, j); } if (B.color == 14) { goldenCount++; playBeep(600 + 14 * 50, 60); score += 20; } else { if (B.color == 14) { HardCount++; } else { normalCount++; } playBeep(600, 60); score += 10; } Broken++; renderPanel(); } } void logic(ball &) { // endGame -> you will lose a life if (Ball.y >= height - 1) { // playBeep(200, 200); // playBeep(300, 100); // playBeep(400, 100); // playBeep(500, 100); playBeep(500, 300); playBeep(350, 400); playBeep(200, 600); gameOver = true; } // Wall Collision if (Ball.x >= width - 1 || Ball.x <= 1) { playBeep(520, 80); Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; Ball.vx *= -1; } if (Ball.y <= 1) { playBeep(520, 80); Ball.vy *= -1; } // Brick Collision bool collision = false; for (int i = 0; i < brickCol && !collision; i++) { for (int j = 0; j < brickRow; j++) { // from below if (Ball.x >= bricks[i][j].x - 1 && Ball.x < bricks[i][j].x + bricks[i][j].width + 1 && (Ball.y == bricks[i][j].y + 1) && bricks[i][j].isBroken == false && Ball.vy < 0) { collision = true; Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; Ball.vy *= -1; if (j < brickRow - 1) { if (((Ball.y + Ball.vy) == bricks[i][j + 1].y) && bricks[i][j + 1].isBroken == false && (Ball.x + Ball.vx >= bricks[i][j + 1].x) && (Ball.x + Ball.vx < bricks[i][j + 1].x + bricks[i][j + 1].width)) { Ball.y = bricks[i][j + 1].y - 2; } } bricksLogic(bricks[i][j], i, j); break; } // from left else if (Ball.x == bricks[i][j].x - 1 && (Ball.y >= bricks[i][j].y - 1 && Ball.y <= bricks[i][j].y + 1) && bricks[i][j].isBroken == false && Ball.vx > 0) { collision = true; Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; Ball.vx *= -1; if (i > 0) { // (Ball.x + Ball.vx) >= bricks[i - 1][j].x && if ((Ball.x + Ball.vx) >= bricks[i - 1][j].x && (Ball.x + Ball.vx) < bricks[i - 1][j].x + brickWidth && bricks[i - 1][j].isBroken == false && (Ball.y + Ball.vy == bricks[i - 1][j].y)) { Ball.x += bricks[i - 1][j].x + brickWidth - 1 - (Ball.x + Ball.vx) + 1; } } bricksLogic(bricks[i][j], i, j); break; } // from right else if (Ball.x == bricks[i][j].x + bricks[i][j].width + 1 && (Ball.y >= bricks[i][j].y - 1 && Ball.y <= bricks[i][j].y + 1) && bricks[i][j].isBroken == false && Ball.vx < 0) { collision = true; Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; Ball.vx *= -1; if (i < brickCol - 1) { // (Ball.x + Ball.vx) >= bricks[i - 1][j].x && if ((Ball.x + Ball.vx) >= bricks[i + 1][j].x && (Ball.x + Ball.vx) < bricks[i + 1][j].x + brickWidth && bricks[i + 1][j].isBroken == false && (Ball.y + Ball.vy == bricks[i + 1][j].y)) { Ball.x -= Ball.x + Ball.vx - bricks[i + 1][j].x + 1; } } bricksLogic(bricks[i][j], i, j); renderPanel(); break; } // from above else if (Ball.x >= bricks[i][j].x - 1 && Ball.x < bricks[i][j].x + bricks[i][j].width + 1 && (Ball.y == bricks[i][j].y - 1) && bricks[i][j].isBroken == false && Ball.vy > 0) { collision = true; Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; Ball.vy *= -1; if (j > 0) { if (((Ball.y + Ball.vy) == bricks[i][j - 1].y) && bricks[i][j - 1].isBroken == false && (Ball.x + Ball.vx >= bricks[i][j - 1].x) && (Ball.x + Ball.vx < bricks[i][j - 1].x + bricks[i][j + 1].width)) { Ball.y += 2; } } bricksLogic(bricks[i][j], i, j); break; } } } int nextY = Ball.y + Ball.vx; // Paddle Collision int delta = 0; if (Ball.x >= Paddle.x && Ball.x < Paddle.x + Paddle.width && Ball.y == height - 3) { playBeep(520, 80); Ball.vx > 0 ? Ball.vx = 1 : Ball.vx = -1; Ball.vy > 0 ? Ball.vy = 1 : Ball.vy = -1; int pos = Paddle.x + Paddle.width - Ball.x; switch (pos) { // case 0: case 2: case 1: { Ball.vy *= -1; if (Ball.x < 20 && Ball.vx < 0 && Ball.vx < 0) { Ball.vx *= -1; } Ball.vx > 0 ? delta = 2 : delta = 0; break; } // case 8:/ case 6: case 7: { Ball.vy *= -1; if (Ball.x > width - 20 && Ball.vx > 0) { Ball.vx *= -1; } Ball.vx > 0 ? delta = 0 : delta = -2; break; } case 4: { // srand(time(0)); // Ball.vx = (rand() % 2 == 0) ? 1 : -1; } case 5: case 3: { // Ball.vx = 0; Ball.vy *= -1; break; } } } Ball.vx += delta; if (Ball.x + Ball.vx > width - 1) { Ball.x = width - 1; } else if (Ball.x + Ball.vx < 1) { Ball.x = 1; } else { Ball.x += Ball.vx; } Ball.y += Ball.vy; } bool bricksCount() { for (int i = 0; i < brickCol; i++) { for (int j = 0; j < brickRow; j++) { if (bricks[i][j].isBroken == false) { return false; } } } return true; } void renderPanel() { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(h, {panelx, panely}); cout << "┌───────────────────┐"; SetConsoleCursorPosition(h, {panelx, panely + 1}); cout << "│ Game Info │"; SetConsoleCursorPosition(h, {panelx, panely + 2}); cout << "├───────────────────┤"; SetConsoleCursorPosition(h, {panelx, panely + 3}); cout << "│ Score: " << setw(5) << score << " │"; SetConsoleCursorPosition(h, {panelx, panely + 4}); cout << "│ Life: " << setw(5) << life << " │"; SetConsoleCursorPosition(h, {panelx, panely + 5}); cout << "│ Bricks: " << setw(5) << (brickCol * brickRow) - Broken << " │"; SetConsoleCursorPosition(h, {panelx, panely + 6}); cout << "└───────────────────┘"; } void selectPO(int option, int crrOption) // PO: pause option { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (option == crrOption) { SetConsoleTextAttribute(h, 1); } else { SetConsoleTextAttribute(h, 15); } } void pauseMenu() { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(h, 8); SetConsoleCursorPosition(h, {0, 5}); render("pause"); renderPanel(); SetConsoleTextAttribute(h, 15); SetConsoleCursorPosition(h, {65, 13}); cout << "╔══════════════════PAUSE══════════════════╗"; for (int i = 0; i < 13; i++) { SetConsoleCursorPosition(h, {65, SHORT(14 + i)}); cout << "║ ║"; } SetConsoleCursorPosition(h, {65, 26}); SetConsoleTextAttribute(h, 15); cout << "╚═════════════════════════════════════════╝"; while (true) { selectPO(1, pauseOption); SetConsoleCursorPosition(h, {80, 14}); cout << "╔═══════════╗"; SetConsoleCursorPosition(h, {80, 15}); cout << "║ Resume ║"; SetConsoleCursorPosition(h, {80, 16}); cout << "╚═══════════╝"; selectPO(2, pauseOption); SetConsoleCursorPosition(h, {80, 17}); cout << "╔═══════════╗"; SetConsoleCursorPosition(h, {80, 18}); cout << "║ Restart ║"; SetConsoleCursorPosition(h, {80, 19}); cout << "╚═══════════╝"; selectPO(3, pauseOption); SetConsoleCursorPosition(h, {80, 20}); cout << "╔═══════════╗"; SetConsoleCursorPosition(h, {80, 21}); cout << "║ Save Game ║"; SetConsoleCursorPosition(h, {80, 22}); cout << "╚═══════════╝"; selectPO(4, pauseOption); SetConsoleCursorPosition(h, {80, 23}); cout << "╔═══════════╗"; SetConsoleCursorPosition(h, {80, 24}); cout << "║ Quit ║"; SetConsoleCursorPosition(h, {80, 25}); cout << "╚═══════════╝"; while (true) { if (_kbhit()) { char userInput = _getch(); if ((userInput == 'w' || userInput == 'W') && pauseOption > 1) { pauseOption -= 1; break; } else if ((userInput == 's' || userInput == 'S') && pauseOption < 4) { pauseOption += 1; break; } if (userInput == 13) { if (pauseOption <= 2) { SetConsoleTextAttribute(h, 7); renderPanel(); } return; } } } Sleep(10); } } void setColor(int color) { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(h, color); } void explodeBricks(int col, int row) { for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { if (dx == 0 && dy == 0) continue; int c = col + dx; int r = row + dy; if (c >= 0 && c < brickCol && r >= 0 && r < brickRow) { if (!bricks[c][r].isBroken && !(c == col && r == row)) { bricks[c][r].isBroken = true; if (bricks[c][r].color == 14) { goldenCount++; score += 20; } else { if (bricks[c][r].color == 9 || bricks[c][r].color == 11) { HardCount++; } else { normalCount++; } score += 10; } Broken++; } } } } } void saveHistory() { time_t now = time(nullptr); tm *local = localtime(&now); strftime(Player.date, 80, "%Y-%m(%b)-%d(%a)", local); strftime(Player.time, 80, "%H:%M", local); char *pointer = strstr(Player.name, "(auto save)"); // پیدا کردن کلمه if (pointer != NULL) { int length = strlen("(auto save)"); // کپی کردن ادامه رشته روی بخش پیدا شده strcpy(pointer, pointer + length); } ofstream file("history.txt", ios::app); if (file.fail()) return; file << Player.name << " " << Player.date << " " << Player.time << " " << score << endl; // PLayer.score = scores file.close(); ofstream scores("scores.txt", ios::out | ios::app); if (scores.fail()) return; scores << Player.name << " " << goldenCount << " " << TNTCount << " " << HardCount << " " << normalCount << endl; scores.close(); } void loadScoresAndPrint(char name[]) { // T: Tmep string Tname; int TgoldenCount = 0; int TeTNTCount = 0; int THardCount = 0; int TnormalCount = 0; ifstream scores("scores.txt", ios::in); if (scores.fail()) return; while (scores >> Tname >> TgoldenCount >> TNTCount >> THardCount >> TnormalCount) { if (Tname == name) { break; } } HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); system("cls"); setColor(7); SetConsoleCursorPosition(h, {68, 15}); cout << "╔══════════════════════════════╗"; SetConsoleCursorPosition(h, {68, 16}); cout << "║ ║"; SetConsoleCursorPosition(h, {68, 17}); cout << "║ "; setColor(5); cout << "YOU HEAT "; setColor(7); cout <<" ║"; SetConsoleCursorPosition(h, {68, 18}); cout << "║ " << "\033[38;5;196mTNT: " << TNTCount; SetConsoleCursorPosition(h, {99, 18}); cout << "\033[0m║"; SetConsoleCursorPosition(h, {68, 19}); cout << "║ ║"; SetConsoleCursorPosition(h, {68, 20}); cout << "║ " << "\033[38;5;226mGolden: " << TgoldenCount; SetConsoleCursorPosition(h, {99, 20}); cout << "\033[0m║"; SetConsoleCursorPosition(h, {68, 21}); cout << "║ ║"; SetConsoleCursorPosition(h, {68, 22}); cout << "║ " << "\033[38;5;33mHard: " << THardCount; SetConsoleCursorPosition(h, {99, 22}); cout << "\033[0m║"; SetConsoleCursorPosition(h, {68, 23}); cout << "║ ║"; SetConsoleCursorPosition(h, {68, 24}); cout << "║ " << "\033[38;5;181mNormal: " << TnormalCount; SetConsoleCursorPosition(h, {99, 24}); cout << "\033[0m║"; SetConsoleCursorPosition(h, {68, 25}); cout << "\033[0m╚══════════════════════════════╝"; } int sort() { if (historyCount == 1) { return history[0].score; } int high; for (int i = 0; i < historyCount - 1; i++) { for (int j = 0; j < historyCount - i - 1; j++) { if (history[j].score < history[j + 1].score) { swap(history[j], history[j + 1]); } } } return history[0].score; } void loadHistory() { historyCount = 0; ifstream file("history.txt"); file.seekg(0); if (file.is_open()) { while (file >> history[historyCount].name >> history[historyCount].date >> history[historyCount].time >> history[historyCount].score) { historyCount++; } } file.close(); } int Hoption = 1; // History option void setHoptioncolor(int crrOption, int option) { if (crrOption == option) { setColor(13); } else { setColor(7); } } bool printHistory(int historyCount) { setColor(5); system("cls"); HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(h, {54, 3}); cout << "==============================================================\n"; cout << setw(54) << "" << " GAME HISTORY\n"; cout << setw(54) << "" << "==============================================================\n\n"; cout << setw(54) << ""; cout << left << setw(6) << "Rank" << setw(15) << "Name" << setw(25) << "Date" << setw(10) << "Time" << setw(10) << "Score" // << setw(8) << "Lives" // << setw(8) << "Result" << endl; cout << setw(54) << "" << "--------------------------------------------------------------\n"; setColor(7); while (true) { SetConsoleCursorPosition(h, {0, 9}); for (int i = 0; i < historyCount; i++) { setHoptioncolor(Hoption, i + 1); cout << setw(54) << ""; cout << left << setw(6) << i + 1 << setw(15) << history[i].name << setw(25) << history[i].date << setw(10) << history[i].time << setw(10) << history[i].score // << setw(8) << history[i].life // << setw(8) << (history[i].win ? "WIN" : "LOSE") << endl; } setColor(5); cout << setw(54) << "" << "==============================================================\n"; while (true) { if (_kbhit()) { char userInput = _getch(); if ((userInput == 'w' || userInput == 'W') && Hoption > 1) { Hoption -= 1; break; } else if ((userInput == 's' || userInput == 'S') && Hoption < historyCount) { Hoption += 1; break; } else if (userInput == 13) { return true; } else if (userInput == 8) { return false; } } } } setColor(7); _getch(); } void saveGame(player &p) { p.score = score; p.life = life; p.isActive = false; time_t now = time(nullptr); tm *local = localtime(&now); strftime(Player.date, 80, "%Y-%m(%b)-%d(%a)", local); strftime(Player.time, 80, "%H:%M", local); // maybe ios::app ofstream fOut("loadGame.dat", ios::app | ios::binary); if (fOut.is_open()) { fOut.write(reinterpret_cast(&p), sizeof(player)); fOut.write(reinterpret_cast(&Ball), sizeof(ball)); fOut.write(reinterpret_cast(&Paddle.width), sizeof(int)); fOut.write(reinterpret_cast(&Paddle.x), sizeof(int)); size_t len = Paddle.paddleChar.size(); fOut.write(reinterpret_cast(&len), sizeof(len)); fOut.write(Paddle.paddleChar.c_str(), len); fOut.write(reinterpret_cast(&brickCol), sizeof(int)); fOut.write(reinterpret_cast(&brickRow), sizeof(int)); fOut.write(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); fOut.write(reinterpret_cast(&Broken), sizeof(int)); fOut.write(reinterpret_cast(&goldenCount), sizeof(int)); fOut.write(reinterpret_cast(&TNTCount), sizeof(int)); fOut.write(reinterpret_cast(&HardCount), sizeof(int)); fOut.write(reinterpret_cast(&normalCount), sizeof(int)); } fOut.seekp(0, ios::end); fOut.close(); } // Half AI void setAndMarkAsActive(int index) { // باز کردن فایل در حالت خواندن و نوشتن همزمان (ios::in | ios::out) fstream file("loadGame.dat", ios::binary | ios::in | ios::out); int count = 1; player temp; if (file.is_open()) { if (index == 1) { while (file.read(reinterpret_cast(&temp), sizeof(player))) { if (temp.isActive == false) { int pointer = file.tellp(); int pos = pointer - sizeof(player); temp.isActive = true; char *find = strstr(temp.name, "(auto save)"); // پیدا کردن کلمه if (find != NULL) { int length = strlen("(auto save)"); // کپی کردن ادامه رشته روی بخش پیدا شده strcpy(find, find + length); } Player = temp; file.read(reinterpret_cast(&Ball), sizeof(ball)); file.read(reinterpret_cast(&Paddle.width), sizeof(int)); file.read(reinterpret_cast(&Paddle.x), sizeof(int)); size_t len; file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ file.read(&Paddle.paddleChar[0], len); // خواندن متن file.read(reinterpret_cast(&brickCol), sizeof(int)); file.read(reinterpret_cast(&brickRow), sizeof(int)); file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); file.read(reinterpret_cast(&Broken), sizeof(int)); file.read(reinterpret_cast(&goldenCount), sizeof(int)); file.read(reinterpret_cast(&TNTCount), sizeof(int)); file.read(reinterpret_cast(&HardCount), sizeof(int)); file.read(reinterpret_cast(&normalCount), sizeof(int)); file.seekp(pos); file.write(reinterpret_cast(&Player), sizeof(player)); break; } file.read(reinterpret_cast(&Ball), sizeof(ball)); file.read(reinterpret_cast(&Paddle.width), sizeof(int)); file.read(reinterpret_cast(&Paddle.x), sizeof(int)); size_t len; file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ file.read(&Paddle.paddleChar[0], len); // خواندن متن file.read(reinterpret_cast(&brickCol), sizeof(int)); file.read(reinterpret_cast(&brickRow), sizeof(int)); file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); file.read(reinterpret_cast(&Broken), sizeof(int)); file.read(reinterpret_cast(&goldenCount), sizeof(int)); file.read(reinterpret_cast(&TNTCount), sizeof(int)); file.read(reinterpret_cast(&HardCount), sizeof(int)); file.read(reinterpret_cast(&normalCount), sizeof(int)); } } else { while (count < index) { file.read(reinterpret_cast(&temp), sizeof(player)); if (temp.isActive == false) { count++; } file.read(reinterpret_cast(&Ball), sizeof(ball)); file.read(reinterpret_cast(&Paddle.width), sizeof(int)); file.read(reinterpret_cast(&Paddle.x), sizeof(int)); size_t len; file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ file.read(&Paddle.paddleChar[0], len); // خواندن متن file.read(reinterpret_cast(&brickCol), sizeof(int)); file.read(reinterpret_cast(&brickRow), sizeof(int)); file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); file.read(reinterpret_cast(&Broken), sizeof(int)); file.read(reinterpret_cast(&goldenCount), sizeof(int)); file.read(reinterpret_cast(&TNTCount), sizeof(int)); file.read(reinterpret_cast(&HardCount), sizeof(int)); file.read(reinterpret_cast(&normalCount), sizeof(int)); } while (file.read(reinterpret_cast(&temp), sizeof(player))) { if (temp.isActive == false) { int pointer = file.tellp(); int pos = pointer - sizeof(player); temp.isActive = true; char *find = strstr(temp.name, "(auto save)"); // پیدا کردن کلمه if (find != NULL) { int length = strlen("(auto save)"); // کپی کردن ادامه رشته روی بخش پیدا شده strcpy(find, find + length); } Player = temp; file.read(reinterpret_cast(&Ball), sizeof(ball)); file.read(reinterpret_cast(&Paddle.width), sizeof(int)); file.read(reinterpret_cast(&Paddle.x), sizeof(int)); size_t len; file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ file.read(&Paddle.paddleChar[0], len); // خواندن متن file.read(reinterpret_cast(&brickCol), sizeof(int)); file.read(reinterpret_cast(&brickRow), sizeof(int)); file.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); file.read(reinterpret_cast(&Broken), sizeof(int)); file.read(reinterpret_cast(&goldenCount), sizeof(int)); file.read(reinterpret_cast(&TNTCount), sizeof(int)); file.read(reinterpret_cast(&HardCount), sizeof(int)); file.read(reinterpret_cast(&normalCount), sizeof(int)); file.seekp(pos); file.write(reinterpret_cast(&Player), sizeof(player)); break; } file.read(reinterpret_cast(&Ball), sizeof(ball)); file.read(reinterpret_cast(&Paddle.width), sizeof(int)); file.read(reinterpret_cast(&Paddle.x), sizeof(int)); size_t len; file.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ file.read(&Paddle.paddleChar[0], len); // خواندن متن file.read(reinterpret_cast(&brickCol), sizeof(int)); file.read(reinterpret_cast(&brickRow), sizeof(int)); file.read(reinterpret_cast(&bricks), (sizeof(brick) * brickCol * brickRow)); file.read(reinterpret_cast(&Broken), sizeof(int)); file.read(reinterpret_cast(&goldenCount), sizeof(int)); file.read(reinterpret_cast(&TNTCount), sizeof(int)); file.read(reinterpret_cast(&HardCount), sizeof(int)); file.read(reinterpret_cast(&normalCount), sizeof(int)); } } file.close(); } } void setLGOColor(int crrOption, int option) // LGO : Load Game Option { if (crrOption == option) { setColor(14); } else { setColor(15); } } void loadPlayer() { playerCount = 0; // int count = 0; ifstream fIn("loadGame.dat", ios::in | ios::binary); player temp; // int index = sizeof(ball) + sizeof(paddle) + sizeof(bricks) + sizeof(int); fIn.seekg(0); if (fIn.is_open()) { while (fIn.read(reinterpret_cast(&temp), sizeof(player))) { if (temp.isActive == false) { loadedPlayer[playerCount] = temp; playerCount++; } fIn.read(reinterpret_cast(&Ball), sizeof(ball)); fIn.read(reinterpret_cast(&Paddle.width), sizeof(int)); fIn.read(reinterpret_cast(&Paddle.x), sizeof(int)); size_t len; fIn.read(reinterpret_cast(&len), sizeof(len)); // خواندن طول Paddle.paddleChar.resize(len); // آماده‌سازی فضا برای استرینگ fIn.read(&Paddle.paddleChar[0], len); // خواندن متن fIn.read(reinterpret_cast(&brickCol), sizeof(int)); fIn.read(reinterpret_cast(&brickRow), sizeof(int)); fIn.read(reinterpret_cast(&bricks), sizeof(brick) * brickCol * brickRow); fIn.read(reinterpret_cast(&Broken), sizeof(int)); fIn.read(reinterpret_cast(&goldenCount), sizeof(int)); fIn.read(reinterpret_cast(&TNTCount), sizeof(int)); fIn.read(reinterpret_cast(&HardCount), sizeof(int)); fIn.read(reinterpret_cast(&normalCount), sizeof(int)); } } fIn.close(); } bool printLoadGame() { setColor(6); loadOption = 1; system("cls"); HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(h, {51, 3}); cout << "=================================================================\n"; cout << setw(51) << "" << " LOAD GAME\n"; cout << setw(51) << "" << "=================================================================\n\n"; cout << setw(51) << ""; cout << left << setw(4) << "#" << setw(15) << "Name" << setw(10) << "Score" << setw(8) << "Lives" << setw(22) << "Date" << setw(10) << "Time" << endl; cout << setw(51) << "" << "-----------------------------------------------------------------\n"; while (true) { SetConsoleCursorPosition(h, {0, 9}); for (int i = 0; i < playerCount; i++) { setLGOColor(loadOption, i + 1); cout << setw(51) << ""; cout << "|" << left << setw(3) << i + 1 << setw(15) << loadedPlayer[i].name << setw(10) << loadedPlayer[i].score << setw(8) << loadedPlayer[i].life << setw(22) << loadedPlayer[i].date << setw(10) << loadedPlayer[i].time << endl; if (i < playerCount - 1) { setColor(15); cout << setw(51) << "" << "-----------------------------------------------------------------\n"; } } setColor(6); cout << setw(51) << "" << "=================================================================\n"; while (true) { if (_kbhit()) { char userInput = _getch(); if ((userInput == 'w' || userInput == 'W') && loadOption > 1) { loadOption -= 1; break; } else if ((userInput == 's' || userInput == 'S') && loadOption < playerCount) { loadOption += 1; break; } else if (userInput == 13) { if (playerCount > 0) { return true; } } else if (userInput == 8) { return false; } } } } setColor(7); } void nextStage() { HideCursor(true); system("cls"); string newGame[35][80]; for (int H = 0; H < 35; H++) { for (int S = 0; S < 80; S++) { newGame[H][S] = " "; } } newGame[0][0] = "╔"; newGame[0][54] = "╗"; newGame[34][0] = "╚"; newGame[34][54] = "╝"; for (int i = 1; i < 34; i++) { newGame[i][0] = "║"; newGame[i][54] = "║"; } for (int i = 1; i < 54; i++) { newGame[0][i] = "═"; newGame[34][i] = "═"; } HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(h, {0, 14}); for (int i = 0; i < 10; i++) { cout << setw(60) << ""; for (int j = 0; j < 79; j++) { cout << newGame[i][j]; } cout << endl; } SetConsoleCursorPosition(h, {60, 23}); cout << "╚═════════════════════════════════════════════════════╝"; SetConsoleTextAttribute(h, 12); SetConsoleCursorPosition(h, {85, 18}); cout << "Great"; SetConsoleCursorPosition(h, {77, 19}); cout << "Loading next stage..."; SetConsoleTextAttribute(h, 7); }