در شهری به نام گاسترونومیکا، رستورانی محبوب وجود دارد که همیشه پر از مشتریان است. این رستوران برای مدیریت بهتر رزروها و تخصیص میزها به مشتریان، تصمیم گرفته است از یک سیستم رزرواسیون دیجیتال استفاده کند. این سیستم باید قادر به پردازش درخواستهای رزرو به صورت غیرهمزمان باشد و در عین حال، تخصیص میزها را به شکل عادلانه انجام دهد.
شما باید کد جاوااسکریپت برای این سیستم رزرواسیون را بنویسید. سیستم شما باید قابلیت مدیریت وضعیت میزهای موجود در رستوران را در زمان واقعی داشته باشد و بتواند درخواستهای رزرو را پردازش کند تا شبیهسازی واقعیتری از فرایند رزرو در شرایط شلوغ رستورانها داشته باشد.
ظاهر کلی برنامه به شکل زیر است:
![خروجی](https://quera.org/qbox/view/JEMc3Ady53/D.gif)
# پروژه اولیه
پروژه اولیه را از
[این لینک](/problemset/assignments/4367/download_problem_initial_project/254940/)
دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
```
initial-project.zip
├── assets
│ ├── Vazir.ttf
│ └── logo.png
├── index.html
├── styles.css
└── script.js
```
# جزئیات
شما باید سازنده و توابع مورد نیاز را در کلاس `Restaurant` به شکلی تکمیل کنید که مدیریت میزها و لیست انتظار رزروها به درستی انجام شود. در ادامه ویژگیهای برنامه توضیح داده میشوند.
### وضعیت میزها (تابع `updateTableStatus()`)
در این قسمت، وضعیت میزها و موجودی آنها نمایش داده میشود. این قسمت پس از هر تغییر، باید بهروزرسانی شود تا بتواند در هر لحظه، گزارش درستی از تعداد میزهای موجود نمایش دهد. دقت کنید که اطلاعات میزها باید در یک تگ `ul` با کلاس `tableStatus` نمایش داده شود.
+ مثال: میز ۲ نفره: ۲ از ۲ عدد باقی مانده.
### رزرو میز (تابع `reserveTable()`)
کاربر با وارد کردن تعداد نفرات و اولویت رزرو، درخواست خود را در مودال مربوطه ثبت میکند. سیستم ابتدا بررسی میکند که آیا میزی برای تعداد نفرات درخواست شده موجود هست یا خیر. اگر میز مناسب موجود باشد:
+ رزرو انجام میشود.
+ پیامی شامل تعداد میزهای رزرو شده و شناسه رزرو، در قسمت گزارشات نمایش داده میشود. دقت کنید که شناسه رزرو، یک عدد یکتا است که از یک شروع شده و توسط تابع `generateReservationId()` یکی یکی افزایش مییابد. (مثال: "۱ عدد میز ۲ نفره برای ۲ نفر رزرو شد. شناسه رزرو: ۱")
در صورتی که هیچ میزی برای تعداد افراد درخواست شده موجود نباشد:
+ سیستم به دنبال ترکیبی از میزها میگردد که مجموع ظرفیت آنها دقیقا برابر با تعداد افراد درخواست شده باشد. جستجوی این ترکیبها از بزرگترین میزها شروع میشوند.
+ اگر ترکیب دقیقی از میزها پیدا شود، رزرو انجام و پیام مربوطه چاپ میشود. (مثال: "۱ عدد میز ۲ نفره و ۱ عدد میز ۳ نفره برای ۵ نفر رزرو شد. شناسه رزرو: ۲")
+ اگر هیچ ترکیب دقیقی موجود نباشد، درخواست کاربر به لیست انتظار اضافه میشود و پیغام `هیچ ترکیب دقیقی از میزها موجود نیست، اضافه کردن به لیست انتظار.` در قسمت گزارشات چاپ میشود.
### آزادسازی میز (تابع `releaseTable()`)
آزادسازی میزها به دو روش انجام میشود:
+ **آزادسازی دستی:** کاربر با وارد کردن شناسه رزرو مربوطه، میز خود را آزاد میکند.
+ **آزادسازی خودکار:** اگر پس از گذشت ۱ دقیقه از رزرو (که به عنوان میانگین زمان لازم برای غذا خوردن در نظر گرفته شده است)، میز به صورت دستی آزاد نشده باشد، سیستم به طور خودکار آن را آزاد میکند.
پس از آزاد شدن میزها، سیستم بررسی میکند که آیا گروهی در لیست انتظار وجود دارد که بتواند از میزهای آزاد شده استفاده کند یا خیر. در صورت وجود چنین گروهی، سیستم رزرو آنها را انجام میدهد. ترتیب اولویت رزروها و زمان ثبت آنها برای انتخاب گروه مناسب در نظر گرفته میشود.
### گزارشها (تابع `log()`)
در این قسمت، پس از هر تغییر، گزارش مربوط به آن طبق الگوهای گفته در بخش زیر، چاپ میشود.
<details class="purple">
<summary>
**پیامهای log**
</summary>
همانطور که گفته شد، تابع `log()` پیامهای مربوط به فرآیند رزرو را در المان `log` در صفحه نمایش میدهد.
+ قبل از ثبت هر پیام یک لاگ با متن `درخواست رزرو برای {k} نفر در حال پردازش...` ثبت خواهد شد.
+ پس از رزرو میز، عبارت `{n} عدد میز {m} نفره برای {k} نفر رزرو شد. شناسه رزرو: {p}` در قسمت گزارشات چاپ میشود. برای مثال:
+ ۱ عدد میز ۲ نفره برای ۲ نفر رزرو شد. شناسه رزرو: ۱
+ ۱ عدد میز ۲ نفره و ۱ عدد میز ۳ نفره برای ۵ نفر رزرو شد. شناسه رزرو: ۲
+ در صورتی که کاربر، میزی را آزاد کند عبارت `{m} عدد میز {m} نفره برای رزرو با شناسه {p} آزاد شد.` در قسمت گزارشات چاپ میشود. برای مثال:
+ ۱ عدد میز ۲ نفره برای رزرو با شناسه ۱ آزاد شد.
+ ۱ عدد میز ۲ نفره و ۱ عدد میز ۳ نفره برای رزرو با شناسه ۲ آزاد شد.
+ در صورتی که میزی به صورت خودکار و پس از صرف زمان ۱ دقیقه آزاد شود، عبارت `{n} عدد میز {m} نفره برای رزرو با شناسه {p} به صورت خودکار آزاد شد.` در قسمت گزارشات چاپ میشود. برای مثال:
+ ۱ عدد میز ۲ نفره برای رزرو با شناسه ۱ به صورت خودکار آزاد شد.
+ در صورتی که هیچ ترکیبی از میزها برای رزرو موجود نباشد و رزرو به صف انتظار منتقل شود، عبارت `هیچ ترکیب دقیقی از میزها موجود نیست، اضافه کردن به لیست انتظار.` چاپ میشود.
</details>
**مواردی که باید در این تمرین رعایت کنید:**
+ برای پیدا کردن حالتهای ترکیب میزها، باید از بزرگترین میز شروع کنید. برای مثال برای رزرو میز ۶ نفره، حالتهای زیر به ترتیب بررسی میشوند:
+ ۴ + ۲
+ ۳ + ۳
+ ۲ + ۲ + ۲
+ پس از هر تغییر (**رزرو** یا **آزادسازی میز**) وضعیت میزها باید توسط تابع `updateTableStatus` بهروزرسانی شود.
# نکات
+ فایل *HTML* و *CSS* و کدهای اولیه `javascript` در اختیار شما قرار گرفته است.
+ شما فقط مجاز به ایجاد تغییرات در کلاس `Restaurant` در `script.js` هستید.
+ در صورت نیاز، میتوانید توابع کمکی به کلاس `Restaurant` اضافه کنید.
+ پس از اعمال تغییرات در `script.js`، فایلهای پروژه را به صورت یک فایل *ZIP* با ساختار زیر ارسال نمایید.
```
[your-zip-file-name].zip
├── assets
│ ├── Vazir.ttf
│ └── logo.png
├── index.html
├── styles.css
└── <mark class="violet">script.js</mark>
```