Initial commit on develop branch

This commit is contained in:
2026-04-14 21:59:16 +03:30
commit 4a362f9c60
+436
View File
@@ -0,0 +1,436 @@
#include <iostream>
#include <vector>
#include <fstream> // برای کار با فایل
#include <conio.h> // برای دریافت ورودی کیبورد
#include <chrono> // برای مدیریت زمان
#include <cstdlib> // توابع استاندارد
#include <ctime> // برای دریافت تاریخ و زمان
#include <string> // برای مدیریت رشته‌ها
#include <windows.h>// برای کنترل مکان‌نما و حذف پرش تصویر
using namespace std;
// تنظیمات کلی بازی
const int WIDTH = 40; // عرض صفحه بازی
const int HEIGHT = 20; // ارتفاع صفحه بازی
// توابع کمکی برای گرافیک (جلوگیری از پرش تصویر)
// انتقال مکان‌نما به مختصات (x, y) بدون پاک کردن کل صفحه
void gotoxy(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
// مخفی کردن نشانگر چشمک‌زن موس برای زیبایی
void HideCursor()
{
HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO info;
info.dwSize = 100;
info.bVisible = FALSE;
SetConsoleCursorInfo(consoleHandle, &info);
}
// ایجاد وقفه زمانی دقیق
void waitFor(int milliseconds)
{
auto start = chrono::high_resolution_clock::now();
while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() < milliseconds)
{
// حلقه انتظار (Busy wait)
}
}
// کلاس توپ (Ball)
class Ball
{
public:
float x, y; // مختصات
float dx, dy; // جهت حرکت
bool moving; // وضعیت حرکت
Ball(float startX, float startY) : x(startX), y(startY), dx(0.5f), dy(-1.0f), moving(false) {}
// حرکت توپ بر اساس سرعت فعلی
void move()
{
if (moving)
{
x += dx;
y += dy;
}
}
// بازنشانی توپ به مکان اولیه (بعد از باختن جان)
void reset(float startX, float startY)
{
x = startX;
y = startY;
// جهت پرتاب تصادفی چپ یا راست
dx = (rand() % 2 == 0 ? 0.5f : -0.5f);
dy = -1.0f;
moving = false;
}
};
// کلاس راکت (Paddle)
class Paddle
{
public:
float x;
int y;
int width;
Paddle(int startX, int startY) : x(startX), y(startY), width(7) {}
// حرکت به چپ با بررسی مرزها
void moveLeft()
{
x -= 2;
if (x < 1) x = 1;
}
// حرکت به راست با بررسی مرزها
void moveRight()
{
x += 2;
if (x + width > WIDTH - 1) x = WIDTH - 1 - width;
}
};
// کلاس آجر (Brick)
class Brick
{
public:
int x, y;
bool active; // آیا آجر هنوز وجود دارد؟
int points; // امتیاز آجر
Brick(int bx, int by) : x(bx), y(by), active(true), points(10) {}
};
// کلاس اصلی بازی (Game Engine)
class Game
{
private:
bool gameOver;
bool victory;
int score;
int lives;
string playerName;
Ball* ball;
Paddle* paddle;
vector<Brick> bricks;
public:
Game(string name)
{
playerName = name;
gameOver = false;
victory = false;
score = 0;
lives = 3;
// ایجاد اشیاء بازی
paddle = new Paddle(WIDTH / 2 - 3, HEIGHT - 2);
ball = new Ball(WIDTH / 2, HEIGHT - 3);
// چیدمان آجرها
for (int i = 0; i < 4; i++)
{
for (int j = 2; j < WIDTH - 2; j += 4)
{
bricks.push_back(Brick(j, i + 2));
}
}
}
~Game()
{
delete ball;
delete paddle;
}
// رسم محیط بازی (بدون پرش تصویر)
void draw()
{
gotoxy(0, 0); // پرش به ابتدای صفحه به جای پاک کردن کل آن
string buffer = ""; // بافر برای ذخیره کل تصویر و چاپ یکجا
// هدر بازی
buffer += "PLAYER: " + playerName + " | SCORE: " + to_string(score) + " | LIVES: " + to_string(lives) + "\n";
for (int i = 0; i < WIDTH + 2; i++) buffer += "#";
buffer += "\n";
// رسم محتوا
for (int i = 0; i < HEIGHT; i++)
{
for (int j = 0; j < WIDTH; j++)
{
if (j == 0) buffer += "#"; // دیوار چپ
bool drawn = false;
// رسم توپ
if ((int)ball->x == j && (int)ball->y == i)
{
buffer += "O";
drawn = true;
}
// رسم راکت
else if (i == paddle->y && j >= (int)paddle->x && j < (int)paddle->x + paddle->width)
{
buffer += "=";
drawn = true;
}
else
{
// رسم آجرها
for (auto& b : bricks) {
if (b.active && b.x == j && b.y == i)
{
buffer += "[]";
drawn = true;
j++; // پرش از روی کاراکتر دوم آجر
break;
}
}
}
if (!drawn) buffer += " "; // فضای خالی
if (j == WIDTH - 1) buffer += "#"; // دیوار راست
}
buffer += "\n";
}
for (int i = 0; i < WIDTH + 2; i++) buffer += "#";
buffer += "\n";
// راهنما پایین صفحه
if(!ball->moving)
buffer += "\nPress 'SPACE' to start. 'a'/'d' to Move. 'q' Quit ";
else
buffer += "\n ";
cout << buffer; // چاپ نهایی بافر
}
// دریافت ورودی از کاربر
void input()
{
if (_kbhit())
{
char current = _getch();
if (current == 'a' || current == 'A') paddle->moveLeft();
if (current == 'd' || current == 'D') paddle->moveRight();
if (current == 'q' || current == 'Q') gameOver = true;
if (current == ' ') ball->moving = true;
}
}
// منطق بازی (فیزیک و برخوردها)
void logic()
{
if (!ball->moving)
{
// چسبیدن توپ به راکت قبل از پرتاب
ball->x = paddle->x + paddle->width / 2;
ball->y = paddle->y - 1;
return;
}
ball->move();
// برخورد با دیوارهای چپ و راست
if (ball->x <= 1 || ball->x >= WIDTH - 1) ball->dx = -ball->dx;
// برخورد با سقف
if (ball->y <= 0) ball->dy = -ball->dy;
// برخورد با راکت
if (ball->y >= paddle->y - 1 && ball->y <= paddle->y && ball->x >= paddle->x && ball->x <= paddle->x + paddle->width)
{
ball->dy = -ball->dy;
ball->y = paddle->y - 1;
}
// افتادن توپ (باختن جان)
if (ball->y >= HEIGHT)
{
lives--;
ball->reset(paddle->x + paddle->width / 2, paddle->y - 1);
if (lives <= 0) gameOver = true;
}
// برخورد با آجرها
bool allDestroyed = true;
for (auto& b : bricks)
{
if (b.active)
{
allDestroyed = false;
if ((int)ball->x >= b.x && (int)ball->x < b.x + 2 && (int)ball->y == b.y)
{
b.active = false;
ball->dy = -ball->dy;
score += b.points;
}
}
}
// شرط پیروزی
if (allDestroyed)
{
victory = true;
gameOver = true;
}
}
// ذخیره تاریخچه بازی در فایل
void saveHistory()
{
ofstream outFile("game_history.txt", ios::app); // برای اضافه کردن به ته فایل
if (outFile.is_open())
{
// دریافت زمان فعلی
time_t now = time(0);
char* dt = ctime(&now);
// حذف کاراکتر خط جدید از انتهای رشته زمان
string timeStr = dt;
if (!timeStr.empty() && timeStr.back() == '\n') timeStr.pop_back();
outFile << "Name: " << playerName << " | Score: " << score << " | Date: " << timeStr << endl;
outFile.close();
}
}
// حلقه اصلی اجرای بازی
void run()
{
system("cls"); // پاکسازی اولیه
HideCursor();
while (!gameOver)
{
draw();
input();
logic();
waitFor(60); // کنترل سرعت بازی
}
// ذخیره امتیاز در پایان بازی
saveHistory();
system("cls");
if (victory)
{
cout << "\n\n\t****************************\n";
cout << "\t* YOU WON! *\n";
cout << "\t* Score saved to history *\n";
cout << "\t****************************\n";
}
else
{
cout << "\n\n\t----------------------------\n";
cout << "\t! GAME OVER !\n";
cout << "\t! Score saved to history !\n";
cout << "\t----------------------------\n";
}
cout << "\nPress any key to exit...";
_getch();
}
};
// توابع منو
void showHelp()
{
system("cls");
cout << "========================================\n";
cout << " GAME HELP \n";
cout << "========================================\n";
cout << " Controls:\n";
cout << " 'a' / 'd' : Move Paddle Left/Right\n";
cout << " 'SPACE' : Launch Ball\n";
cout << " 'q' : Quit Game\n\n";
cout << " Rules:\n";
cout << " Break all bricks to win.\n";
cout << " Don't let the ball fall.\n";
cout << "\nPress any key to return...";
_getch();
}
void showHistory()
{
system("cls");
cout << "========================================\n";
cout << " GAME HISTORY \n";
cout << "========================================\n";
ifstream inFile("game_history.txt");
string line;
if (inFile.is_open())
{
while (getline(inFile, line))
{
cout << line << endl;
}
inFile.close();
}
else
{
cout << "No history found yet.\n";
}
cout << "\n========================================\n";
cout << "Press any key to return...";
_getch();
}
int main()
{
srand(static_cast<unsigned int>(time(0))); // تنظیم اولیه اعداد تصادفی
while (true)
{
system("cls");
cout << "========================================\n";
cout << " BREAKOUT - MAIN MENU \n";
cout << "========================================\n";
cout << " 1. New Game\n";
cout << " 2. Game History\n";
cout << " 3. Help\n";
cout << " 4. Exit\n";
cout << "========================================\n";
cout << " Select Option: ";
char choice = _getch();
if (choice == '1')
{
system("cls");
string pName;
cout << "\nEnter Player Name: ";
cin >> pName;
Game breakout(pName);
breakout.run();
}
else if (choice == '2')
{
showHistory();
}
else if (choice == '3')
{
showHelp();
}
else if (choice == '4')
{
cout << "\nGoodbye!\n";
break;
}
}
return 0;
}