**مهارتهای لازم:**
+ آشنایی با `JS`
--------------------------------------------------
در این سوال قصد داریم یک بازی مشابه *puzzle-8* را با استفاده از `js` و بدون استفاده از کتابخانه جانبی پیاده سازی کنیم.ظاهر کلی برنامه بدین صورت است:
![توضیح تصویر](https://quera.ir/qbox/view/34bybyOtL8/yawz_gif.gif)
# پروژه اولیه
پروژه اولیه را از
[این لینک](/contest/assignments/20701/download_problem_initial_project/67900/)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
8-puzzle
├── __tests__
│ ├── requirements.txt
│ └── sample_test.py
├── .qsampletest
├── index.html
└── style.css
```
<details class="brown">
<summary>
راهاندازی پروژه
</summary>
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- سپس فایل `index.html` را در مرورگر خود باز کنید.
</details>
# جزئیات
این بازی مشابه با بازی *8-puzzle* می باشد.با این تفاوت که در این بازی فرض شده است که سطر اول و آخر و همچنین ستون اول و آخر با هم مجاور هستند.برای فهم دقیق گیف قرار داده شده در ابتدا سوال را با دقت مشاهده کنید.
برای پیاده سازی نکات زیر را در نظر بگیرید:
- حالت اولیه بازی را به شکل زیر در نظر بگیرید.
```js
init_state = [
[2, 3, 5],
[1, 4, ''],
[7, 8, 6]
]
```
- وضعیت بازی را در یک عنصر با شناسه `game_status` نمایش دهید.
- تعداد حرکات صورت گرفته را در یک عنصر با شناسه `moves` نمایش دهید.
- با کلیک بر روی دکمه `reset` بازی به حالت اول بر می گردد.
# نکات
- در صورت مرتب شدن پازل پیغام *You won !* را نمایش دهید در غیر اینصورت پیغام *Start moving Tile !* باید نمایش داده شود.(پیغام را کپی نکنید و خودتان تایپ کنید.)
- تغییرات را تنها در فایل `app.js` اعمال کنید. تغییرات در بقیه فایل ها نادیده گرفته می شوند.
- توجه کنید که داوری خودکار بر مبنای نام کلاس های انجام میشود.
- پروژه را با ساختار زیر ارسال کنید.
```
[your-zip-file-name].zip
└── app.js
```
# قسمت آموزشی
در این قسمت راهنماییهای سوال، به مرور اضافه میشود. مشکلاتتان در راستای حل سوال را میتوانید از بخش ["سوال بپرسید"](https://quera.ir/contest/clarification/20701/) مطرح کنید.
# قسمت آموزشی
در این قسمت راهنماییهای سوال، به مرور اضافه میشود. مشکلاتتان در راستای حل سوال را میتوانید از بخش ["سوال بپرسید"](https://quera.ir/contest/clarification/20701/) مطرح کنید.
<details class="blue">
<summary>
راهنمایی شماره ۱
</summary>
- برای حل این سوال می توانید یک آرایه دو بعدی داشته باشید. سپس یک تابع بنویسید که با فراخوانی آن آرایه دو بعدی ساخته شده رندر شود.
- همچنین می توانید یک تابع بنویسید که وظیفه آن جابجا کردن سلول ها باشد.
- برای اینکه بتوانید عملکرد کلیک کردن در بازی را پیاده سازی کنید از تابع *addEventListener* استفاده کنید. بعد می توانید توابعی که نوشتید را در *callback* این تابع اجرا کنید.
- همچنین می توانید یک عملکردی پیاده سازی کنید تا به عنوان مثال آرایه شما از `a[-1]` (ایندکس های منفی یا بزرگتر از اندازه لیست) را نیز پشتیبانی کند (همانند پایتون). این قابلیت با استفاده از *Proxy* ها در جاوا اسکریپت قابل پیاده سازی است.به عنوان مثال :
```js
const ProxyArray = (arr) => {
return new Proxy(arr, {
get(target, prop) {
if (!isNaN(prop)) {
prop = parseInt(prop, 10);
if (prop < 0) {
prop += target.length;
}
if (prop >= target.length) {
prop = prop % target.length;
}
}
return target[prop];
}
});
};
```
</details>
<details class="blue">
<summary>
راهنمایی شماره ۲
</summary>
برای رندر کردن ماتریس شما باید تمامی *cell* ها را داشته باشید. برای دریافت تمامی *cell* شما می توانید از کد زیر استفاده کنید.
```js
let cells = document.querySelectorAll('.cell');
```
در نهایت می توانید با استفاده از یک حلقه *for* روی این لیست یا با استفاده از *forEach*، محتوای هر کدام از *cell* ها را مقدار دهی کنید.به عنوان نمونه:
```js
cells.forEach(item => {
item.innerHTML = `<span>${matrix[y][x]}</span>`
});
```
</details>
<details class="blue">
<summary>
راهنمایی شماره ۳
</summary>
می توانید کد زیر را کامل کنید.
```js
let matrix = [
[2, 3, 5],
[1, 4, ''],
[7, 8, 6]
];
// Get all cells
cells.forEach(item => {
// set click listener for each cell
item.addEventListener('click', (e) => {
// get position of clicked cell
// (x, y) current position of clicked cell
moveCell(x, y); // move the cell to a position that is empty.
renderMatrix(); // render the matrix
})
});
function moveCell(x, y) {
// todo
}
function renderMatrix() {
// todo
}
```
</details>
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.