commit 8f7da7d2fcf2f42219caa9f9a687cc595f7876a3 Author: faraz_ardeh Date: Tue Apr 14 20:09:11 2026 +0000 Upload files to "/" diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..f5f33a2 --- /dev/null +++ b/main.cpp @@ -0,0 +1,636 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +// تعریف متغیرهای اصلی +const int SCREEN_WIDTH = 40; +const int SCREEN_HEIGHT = 20; +const char PLAYER_SHIP = 'A'; +const char ENEMY_TYPE1 = 'X'; +const char ENEMY_TYPE2 = 'Y'; +const char ENEMY_TYPE3 = 'Z'; +const char RED_UFO = 'U'; +const char LASER = '|'; +const char ENEMY_MISSILE = '*'; +int score = 0, lives = 3, level = 1, gameTime = 0, laserCount = 1; +int playerX = SCREEN_WIDTH / 2, playerY = SCREEN_HEIGHT - 2; +int enemyX = 5, enemyY = 1, baseEnemySpeed = 500, enemySpeed = baseEnemySpeed; +bool moveRight = true; +bool ufoVisible = false; +int ufoX = -1, ufoY = 0, baseFireProbability = 2, enemiesDestroyed = 0; +const int ENEMY_ROWS = 3, ENEMY_COLS = 10, NUM_BARRIERS = 3, BARRIER_WIDTH = 5, BARRIER_HEIGHT = 2, thresholdToUpgrade = 15; +chrono::steady_clock::time_point startTime = chrono::steady_clock::now(); +vector> enemies(ENEMY_ROWS, vector(ENEMY_COLS, true)); +vector> lasers, enemyMissiles; +vector> barriers(NUM_BARRIERS, vector(BARRIER_WIDTH * BARRIER_HEIGHT, 3)); +vector> barrierPositions = {{10, 15}, {20, 15}, {30, 15}}; + +void setColor(string colorCode) { + cout << "\033[" << colorCode << "m"; +} +void resetColor() { + cout << "\033[0m"; +} +char getInput() { + struct termios oldt, newt; + char ch; + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + ch = getchar(); + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + return ch; +} +void updateGameTime() { + chrono::steady_clock::time_point currentTime = chrono::steady_clock::now(); + gameTime = chrono::duration_cast(currentTime - startTime).count(); +} + +void renderStatus() { + // نمایش وضعیت در بالای صفحه + cout << "\033[1;1H"; // تنظیم موقعیت چاپ به خط اول + setColor("36"); // رنگ فیروزه‌ای + cout << "Score: " << score << " | Lives: " << lives << " | Time: " << gameTime << "s"; + resetColor(); + cout << "\033[2;1H"; // رفتن به خط دوم برای نمایش صفحه بازی +} + +void renderScreen() { + system("clear"); // پاک کردن صفحه + for (int y = 0; y < SCREEN_HEIGHT; y++) { + for (int x = 0; x < SCREEN_WIDTH; x++) { + if (y == playerY && x == playerX) { + cout << PLAYER_SHIP; // نمایش سفینه بازیکن + } else { + // نمایش لیزرها + bool isLaser = false; + for (pair &laser : lasers) { + if (laser.first == y && laser.second == x) { + cout << LASER; + isLaser = true; + break; + } + } + if (!isLaser) { + cout << " "; // فضای خالی + } + } + } + cout << endl; + } +} + +void renderEnemies() { + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + if (enemies[i][j]) { + int x = enemyX + j; + int y = enemyY + i; + if (x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT) { + cout << "\033[" << y + 1 << ";" << x + 1 << "H"; // تنظیم موقعیت چاپ در ترمینال + if (i == 0) + cout << ENEMY_TYPE3; // دشمن نوع سوم + else if (i == 1) + cout << ENEMY_TYPE2; // دشمن نوع دوم + else + cout << ENEMY_TYPE1; // دشمن نوع اول + } + } + } + } +} + +void renderBarriers() { + for (int b = 0; b < NUM_BARRIERS; b++) { + int startX = barrierPositions[b].first; + int startY = barrierPositions[b].second; + + for (int y = 0; y < BARRIER_HEIGHT; y++) { + for (int x = 0; x < BARRIER_WIDTH; x++) { + int idx = y * BARRIER_WIDTH + x; + if (barriers[b][idx] > 0) { + cout << "\033[" << (startY + y + 1) << ";" << (startX + x + 1) << "H"; // تنظیم موقعیت چاپ + if (barriers[b][idx] == 3) setColor("32"); // سبز (سالم) + else if (barriers[b][idx] == 2) setColor("33"); // زرد (آسیب‌دیده) + else setColor("31"); // قرمز (تقریباً نابود) + cout << "#"; + resetColor(); + } + } + } + } +} + + +void renderUFO() { + if (ufoVisible && ufoX >= 0 && ufoX < SCREEN_WIDTH) { + cout << "\033[" << ufoY + 1 << ";" << ufoX + 1 << "H"; // تنظیم موقعیت چاپ در ترمینال + setColor("31"); // رنگ قرمز + cout << RED_UFO; + resetColor(); + } +} + +void renderMissiles() { + for (pair &missile : enemyMissiles) { + int x = missile.second; + int y = missile.first; + if (y >= 0 && y < SCREEN_HEIGHT) { + cout << "\033[" << y + 1 << ";" << x + 1 << "H"; // تنظیم موقعیت چاپ در ترمینال + setColor("33"); // رنگ زرد + cout << ENEMY_MISSILE; + resetColor(); + } + } +} + +void updateEnemies() { + // تغییر جهت حرکت در صورت رسیدن به لبه صفحه + if (moveRight) { + if (enemyX + ENEMY_COLS >= SCREEN_WIDTH) { + moveRight = false; + enemyY++; // حرکت به سمت پایین + } else { + enemyX++; // حرکت به راست + } + } else { + if (enemyX <= 0) { + moveRight = true; + enemyY++; // حرکت به سمت پایین + } else { + enemyX--; // حرکت به چپ + } + } + + // افزایش سرعت با کاهش تعداد دشمنان + int remainingEnemies = 0; + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + if (enemies[i][j]) remainingEnemies++; + } + } + if (remainingEnemies > 0) { + enemySpeed = max(100, 500 - (remainingEnemies * 5)); // کاهش زمان برای افزایش سرعت + } +} + +void updateLasers() { + for (vector>::iterator it = lasers.begin(); it != lasers.end();) { + it->first--; // حرکت تیر به بالا + if (it->first < 0) { + it = lasers.erase(it); // حذف تیر اگر از بالای صفحه خارج شد + } else { + // برخورد آینه‌ای + if (it->second <= 0 || it->second >= SCREEN_WIDTH - 1) { + it->second = max(0, min(SCREEN_WIDTH - 1, it->second)); // محدود کردن به صفحه + it->second *= -1; // معکوس کردن جهت حرکت افقی + } + ++it; + } + } +} + +void updateMissiles() { + for (vector>::iterator it = enemyMissiles.begin(); it != enemyMissiles.end();) { + it->first++; // حرکت موشک به پایین + if (it->first >= SCREEN_HEIGHT) { + it = enemyMissiles.erase(it); // حذف موشک اگر از صفحه خارج شد + } else { + ++it; + } + } +} + + +void updateUFO() { + // اگر بشقاب پرنده در حال حرکت است + if (ufoVisible) { + ufoX++; // حرکت به سمت راست + if (ufoX >= SCREEN_WIDTH) { + ufoVisible = false; // اگر از صفحه خارج شد، ناپدید شود + ufoX = -1; + } + } else { + // ایجاد بشقاب پرنده به صورت تصادفی + if (rand() % 100 < 2) { // احتمال 2 درصد برای ظاهر شدن UFO + ufoVisible = true; + ufoX = 0; // شروع از لبه چپ صفحه + } + } +} + +void enemyFire() { + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + if (enemies[i][j] && rand() % 100 < 2) { // احتمال 2 درصد برای شلیک موشک + enemyMissiles.push_back({enemyY + i + 1, enemyX + j}); + } + } + } +} + +void checkLaserHits() { + for (vector>::iterator it = lasers.begin(); it != lasers.end();) { + int laserX = it->second; + int laserY = it->first; + bool hit = false; + + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + int enemyPosX = enemyX + j; + int enemyPosY = enemyY + i; + + if (enemies[i][j] && laserX == enemyPosX && laserY == enemyPosY) { + enemies[i][j] = false; // حذف دشمن + it = lasers.erase(it); // حذف لیزر + hit = true; + break; + } + } + if (hit) break; + } + + if (!hit) ++it; + } +} + +void checkLaserBarrierHits() { + for (vector>::iterator it = lasers.begin(); it != lasers.end();) { + int laserX = it->second; + int laserY = it->first; + bool hit = false; + + for (int b = 0; b < NUM_BARRIERS; b++) { + int startX = barrierPositions[b].first; + int startY = barrierPositions[b].second; + + if (laserY >= startY && laserY < startY + BARRIER_HEIGHT && + laserX >= startX && laserX < startX + BARRIER_WIDTH) { + int idx = (laserY - startY) * BARRIER_WIDTH + (laserX - startX); + if (barriers[b][idx] > 0) { + barriers[b][idx]--; // کاهش مقاومت مانع + it = lasers.erase(it); // حذف لیزر + hit = true; + break; + } + } + } + if (!hit) ++it; + } +} + +void checkMissileHits() { + for (vector>::iterator it = enemyMissiles.begin(); it != enemyMissiles.end();) { + int missileX = it->second; + int missileY = it->first; + + // برخورد با سفینه بازیکن + if (missileX == playerX && missileY == playerY) { + cout << "\nYour ship was hit! -1 life\n"; + this_thread::sleep_for(chrono::milliseconds(500)); + it = enemyMissiles.erase(it); // حذف موشک + // TODO: کاهش تعداد جان بازیکن + } else { + ++it; + } + } +} + +void checkMissileBarrierHits() { + for (vector>::iterator it = enemyMissiles.begin(); it != enemyMissiles.end();) { + int missileX = it->second; + int missileY = it->first; + bool hit = false; + + for (int b = 0; b < NUM_BARRIERS; b++) { + int startX = barrierPositions[b].first; + int startY = barrierPositions[b].second; + + if (missileY >= startY && missileY < startY + BARRIER_HEIGHT && + missileX >= startX && missileX < startX + BARRIER_WIDTH) { + int idx = (missileY - startY) * BARRIER_WIDTH + (missileX - startX); + if (barriers[b][idx] > 0) { + barriers[b][idx]--; // کاهش مقاومت مانع + it = enemyMissiles.erase(it); // حذف موشک + hit = true; + break; + } + } + } + if (!hit) ++it; + } +} + +void checkUFOHit() { + for (vector>::iterator it = lasers.begin(); it != lasers.end();) { + int laserX = it->second; + int laserY = it->first; + + if (ufoVisible && laserX == ufoX && laserY == ufoY) { + ufoVisible = false; // حذف UFO + ufoX = -1; + it = lasers.erase(it); // حذف لیزر + cout << "\nYou destroyed the Red UFO! +100 points\n"; + this_thread::sleep_for(chrono::milliseconds(500)); + break; + } else { + ++it; + } + } +} + +void resetEnemies() { + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + enemies[i][j] = true; // تمام دشمنان دوباره ظاهر می‌شوند + } + } + enemyX = 5; // موقعیت اولیه دشمنان + enemyY = 1; // ارتفاع اولیه دشمنان + moveRight = true; // تنظیم جهت حرکت اولیه +} + +void increaseDifficulty() { + level++; // افزایش سطح + enemySpeed = max(100, baseEnemySpeed - (level * 50)); // کاهش زمان حرکت دشمنان + baseFireProbability = min(10, baseFireProbability + level); // افزایش احتمال شلیک موشک + for (vector &barrier : barriers) { + for (int &cell : barrier) { + cell = max(1, cell - 1); // کاهش مقاومت موانع + } + } + cout << "Level Up! Welcome to Level " << level << "!\n"; + this_thread::sleep_for(chrono::seconds(2)); +} + +bool isLevelComplete() { + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + if (enemies[i][j]) { + return false; // اگر حداقل یک دشمن باقی مانده باشد، سطح کامل نشده است + } + } + } + return true; // تمام دشمنان نابود شده‌اند +} + +void saveGame() { + ofstream saveFile("save.txt"); + if (!saveFile) { + cout << "Error: Could not open save file.\n"; + return; + } + + // ذخیره وضعیت کلی بازی + saveFile << score << " " << lives << " " << gameTime << "\n"; + saveFile << playerX << " " << playerY << "\n"; + + // ذخیره دشمنان + saveFile << enemyX << " " << enemyY << " " << moveRight << "\n"; + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + saveFile << enemies[i][j] << " "; + } + saveFile << "\n"; + } + + // ذخیره موقعیت موانع + for (int b = 0; b < NUM_BARRIERS; b++) { + for (int idx = 0; idx < BARRIER_WIDTH * BARRIER_HEIGHT; idx++) { + saveFile << barriers[b][idx] << " "; + } + saveFile << "\n"; + } + + // ذخیره لیزرها + saveFile << lasers.size() << "\n"; + for (pair &laser : lasers) { + saveFile << laser.first << " " << laser.second << "\n"; + } + + // ذخیره موشک‌های دشمن + saveFile << enemyMissiles.size() << "\n"; + for (pair &missile : enemyMissiles) { + saveFile << missile.first << " " << missile.second << "\n"; + } + + // ذخیره وضعیت بشقاب پرنده قرمز + saveFile << ufoVisible << " " << ufoX << " " << ufoY << "\n"; + + saveFile.close(); + cout << "Game saved successfully!\n"; +} + +void loadGame() { + ifstream loadFile("save.txt"); + if (!loadFile) { + cout << "Error: Could not open save file.\n"; + return; + } + + // بارگذاری وضعیت کلی بازی + loadFile >> score >> lives >> gameTime; + loadFile >> playerX >> playerY; + + // بارگذاری دشمنان + loadFile >> enemyX >> enemyY >> moveRight; + for (int i = 0; i < ENEMY_ROWS; i++) { + for (int j = 0; j < ENEMY_COLS; j++) { + bool temp; + loadFile >> temp; + enemies[i][j] = temp; + } + } + + // بارگذاری موقعیت موانع + for (int b = 0; b < NUM_BARRIERS; b++) { + for (int idx = 0; idx < BARRIER_WIDTH * BARRIER_HEIGHT; idx++) { + loadFile >> barriers[b][idx]; + } + } + + // بارگذاری لیزرها + int laserCount; + loadFile >> laserCount; + lasers.clear(); + for (int i = 0; i < laserCount; i++) { + int y, x; + loadFile >> y >> x; + lasers.push_back({y, x}); + } + + // بارگذاری موشک‌های دشمن + int missileCount; + loadFile >> missileCount; + enemyMissiles.clear(); + for (int i = 0; i < missileCount; i++) { + int y, x; + loadFile >> y >> x; + enemyMissiles.push_back({y, x}); + } + + // بارگذاری وضعیت بشقاب پرنده قرمز + loadFile >> ufoVisible >> ufoX >> ufoY; + + loadFile.close(); + cout << "Game loaded successfully!\n"; +} + +struct PlayerScore { + string name; + int score; + int time; + bool operator<(const PlayerScore &other) const { + if (score != other.score) return score > other.score; + return time < other.time; + } +}; + +void saveScore(string playerName, int score, int time) { + ofstream leaderboardFile("leaderboard.txt", ios::app); + if (!leaderboardFile) { + cout << "Error: Could not open leaderboard file.\n"; + return; + } + leaderboardFile << playerName << " " << score << " " << time << "\n"; + leaderboardFile.close(); + cout << "Score saved to leaderboard!\n"; +} + +void showLeaderboard() { + ifstream leaderboardFile("leaderboard.txt"); + if (!leaderboardFile) { + cout << "Error: Could not open leaderboard file.\n"; + return; + } + + vector scores; + string name; + int score, time; + + // خواندن اطلاعات از فایل + while (leaderboardFile >> name >> score >> time) { + scores.push_back({name, score, time}); + } + leaderboardFile.close(); + + // مرتب‌سازی امتیازات + sort(scores.begin(), scores.end()); + + // نمایش جدول + system("clear"); + cout << "===== Leaderboard =====\n"; + cout << "Rank | Name | Score | Time (s)\n"; + cout << "------------------------------\n"; + for (size_t i = 0; i < scores.size(); i++) { + cout << i + 1 << " | " << scores[i].name << " | " << scores[i].score << " | " << scores[i].time << "\n"; + } + cout << "\nPress any key to return to the main menu.\n"; + getInput(); // انتظار برای ورودی +} + +void handleInput() { + char input = getInput(); + if (input == 'a' || input == 'A') { + if (playerX > 0) playerX--; // حرکت به چپ + } else if (input == 'd' || input == 'D') { + if (playerX < SCREEN_WIDTH - 1) playerX++; // حرکت به راست + } else if (input == ' ') { + // شلیک چند تیر به صورت هم‌زمان + if (lasers.size() < laserCount) { + for (int i = 0; i < laserCount; i++) { + lasers.push_back({playerY - 1, playerX + (i - laserCount / 2)}); // تیرها از نقاط مختلف شلیک می‌شوند + } + } + } +} + +void newGame() { + while (true) { + updateGameTime(); // به‌روزرسانی زمان بازی + renderStatus(); // نمایش وضعیت بازی + renderScreen(); // نمایش صفحه + renderEnemies(); // نمایش دشمنان + renderUFO(); // نمایش بشقاب پرنده قرمز + renderMissiles(); // نمایش موشک‌های دشمنان + renderBarriers(); // نمایش موانع + handleInput(); // دریافت ورودی بازیکن + updateLasers(); // به‌روزرسانی لیزرها + checkLaserHits(); // چک کردن برخورد لیزرها با دشمنان + checkLaserBarrierHits();// چک کردن برخورد لیزرها با موانع + updateEnemies(); // به‌روزرسانی حرکت دشمنان + updateUFO(); // به‌روزرسانی حرکت بشقاب پرنده + checkUFOHit(); // چک کردن برخورد لیزر با UFO + enemyFire(); // شلیک موشک توسط دشمنان + updateMissiles(); // به‌روزرسانی حرکت موشک‌ها + checkMissileHits(); // چک کردن برخورد موشک‌ها با بازیکن + checkMissileBarrierHits();// چک کردن برخورد موشک‌ها با موانع + + // بررسی پایان سطح + if (isLevelComplete()) { + increaseDifficulty(); // افزایش سختی + resetEnemies(); // بازنشانی دشمنان برای سطح جدید + } + + // تاخیر برای کنترل سرعت بازی + this_thread::sleep_for(chrono::milliseconds(enemySpeed)); + } +} + +void showMenu() { + while (true) { + system("clear"); + setColor("32"); + cout << "==========================\n"; + cout << " Welcome to Space Invaders \n"; + cout << "==========================\n"; + resetColor(); + + cout << "1. New Game\n"; + cout << "2. Load Game\n"; + cout << "3. Save Game\n"; + cout << "4. How to Play\n"; + cout << "5. Leaderboard\n"; + cout << "6. Exit\n"; + cout << "Select an option: "; + + char choice = getInput(); + switch (choice) { + case '1': + newGame(); + break; + case '2': + loadGame(); + break; + case '3': + saveGame(); + break; + case '4': + // نمایش دستورالعمل‌ها + break; + case '5': + showLeaderboard(); + break; + case '6': + return; + default: + cout << "Invalid option! Please try again.\n"; + this_thread::sleep_for(chrono::seconds(1)); + } + } +} + +int main() { + showMenu(); + return 0; +} \ No newline at end of file