#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; }