در این سوال از شما میخواهیم تا لوگوی کوئرا را به طرز خاصی نمایش دهید.
در صفحهای که شما میسازید باید یک لوگوی کوئرا وجود داشته باشد و وقتی که موس وارد عکس میشود
عکس باید تار شود و زمانی که خارج میشود عکس باید دوباره حالت عادی خود بگیرد.
از شما میخواهیم تا این سرویس را روی عکسی که به شما داده میشود اجرا کنید.
# پروژه اولیه
پروژه اولیه را از
[اینجا](https://quera.ir/qbox/download/U4lT3fhTTe/blurimage.zip)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
blur-image
├── Result.svg
├── index.html
└── quera.svg
```
# جزئیات
در صورتی که موس داخل عکس باشد باید دو ویژگی زیر به *CSS* مربوط به عکس که دارای *id* برابر با `image` است اضافه شوند.
```css
filter: blur(8px);
-webkit-filter: blur(8px);
```
در غیر این صورت هم نباید چیزی اضافه شود.
# نکات
- توجه کنید که داوری خودکار بر مبنای شناسه (id) عناصر انجام میشود.
پس دقت کنید که عناصر شناسهی صحیح داشته باشند.
- فرض کنید سیستم به اینترنت متصل نیست، بنابراین از ارجاع به فایلهای موجود
در وب (*CDN* ها) خودداری کنید.
- پروژه را با ساختار زیر ارسال کنید.
یعنی باید در *Zip* ارسالی شما تنها فایل `index.html` وجود داشته باشد.
```
[your-zip-file-name].zip
└── index.html
```
در این سوال قصد داریم یک بازی ساده چند مرحلهای را پیادهسازی کنیم.
نحوه اجرای بازی به این گونه است که در هر مرحله یک نقطه از صفحه به عنوان گنج انتخاب میشود
و هر چه قدر که موس را به آن نقطه نزدیکتر کنید رنگ صفحه روشنتر میشود.
همچنین این بازی باید شامل تعدادی مرحله باشد که در هر مرحله نقطهای که
به عنوان گنج انتخاب میشود متفاوت است و باید اطلاعات مربوط به مکان گنج را از یک فایل *JSON* بخوانید.
برای درک جزئیات بیشتر میتوانید این نمونه را ببینید.
![توضیح تصویر](https://quera.ir/qbox/view/92EveWLe1U/Peek%202019-07-12%2014-16.gif)
# پروژه اولیه
پروژه اولیه را از [اینجا](https://quera.ir/qbox/download/jVjs1SCPaI/findtreasure.zip) دانلود کنید.ساختار فایلهای این پروژه به صورت زیر است.
```
findtreasure
├── index.html
├── levels.json
└── style.css
```
# جزئیات
فایل `levels.json`:
+ این فایل مراحل بازی را مشخص میکند و یک ویژگی به نام `levels`
دارد که حاوی یک آرایه است که مختصات گنج را در آن مرحله مشخص میکند.
+ اندازه لیست موجود در این فایل هم تعداد مراحل را مشخص میکند.
ویژگی `background-color` برای `square`:
+ در صورتی که موس خارج از این شی باشد باید رنگ `#000` باشد.
+ در غیر این صورت ابتدا مقدار فاصله منهتنی موس و مکان گنج را به دست آورید و نام این مقدار را
$dist$ بگذارید. در آن صورت هر سه مولفه رنگ باید $255 - \lfloor \dfrac {dist}{2} \rfloor $ باشد.
منظور از فاصله منهتنی دو نقطه در این سوال مجموع اختلاف مولفه $x$ و $y$ آنهاست، یعنی اگر دو نقطه $(x_1, y_1)$ و $(x_2, y_2)$ داشته باشیم فاصله آنها برابر با $|x_1 - x_2| + |y_1 - y_2|\ $ است.
مقدار متنی ویژگی `level`:
+ در هر زمان که فاصله منهتنی موس و گنج کمتر از $10$ شد این مرحله تمام میشود و باید مرحله بعدی
نمایش داده شود و ویژگی `level` هم باید مقدارش یکی بیشتر شود. در ابتدای بازی در مرحله ۰ هستیم و مقدار ویژگی `level` هم باید به صورت `Level #id` باشد که `#id` شماره مرحله کنونی است.
+ همچنین در صورتی که آخرین مرحله هم تمام شد باید مقدار این ويژگی به `You won!` تغییر کند و رنگ `square` هم برای همیشه سفید بماند. (حتی در زمانی که موس از صفحه خارج شد.)
تغییرات لازم را در فایل `index.html` و در صورت نیاز فایلهای `.js` خود را اضافه کنید.
توجه کنید که در هنگام تستکردن ممکن است فایل `levels.json` تغییر کند.
# نکات
- توجه کنید که داوری خودکار بر مبنای شناسه (id) عناصر انجام میشود.
پس دقت کنید که عناصر شناسهی صحیح داشته باشند.
- در صورتی که هنگام ارسال درخواست برای دریافت فایل `levels.json` با خطای `Cross Origin`
از طرف مرورگر مواجه شدید، به جای باز کردن مستقیم فایل *HTML* با مرورگر،
پوشه پروژه را با یک وبسرور (مثلاً
[`python -m http.server`](https://docs.python.org/3/library/http.server.html) و یا `npx http-server`)
serve
کنید، و یا مرورگر *FireFox* را امتحان کنید.
- فرض کنید سیستم به اینترنت متصل نیست، بنابراین از ارجاع به فایلهای موجود
در وب (*CDN* ها) خودداری کنید.
- پروژه را با ساختار زیر ارسال کنید.
تغییر تنها در مواردی که با `*` مشخص شده مجاز است
و ارسال سایر فایلها الزامی نیست.
```
[your-zip-file-name].zip
├── index.html
└── your .js files (Optional)
```
**مهارتهای لازم:**
+ آشنایی با `ReactJS`
+ آشنایی با `Redux`
+ کدخوانی
--------------------------------------------------
محمد و جواد و مهدی همیشه برای اینکه میتوانند از پرداخت تومن استفاده کنند خیلی خوشحال هستند آنها میخواهند دفترچه یادداشتی با `react` و `redux` درست کنند که خاطرات استفاده از پرداخت تومن را در آن یادداشت کنند.
![ظاهر برنامه](https://quera.ir/qbox/download/cE7exu5DPo/overview.png)
# پروژه اولیه
پروژه اولیه را از
[اینجا](https://quera.ir/qbox/download/bgxgOsADJL/toman-booklet.zip)
دانلود کنید.
ساختار فایلهای این پروژه به صورت زیر است.
```
toman-booklet
├── public
│ ├── static
│ │ ├── image
│ │ │ ├── document.png
│ │ │ ├── folder-horizontal.png
│ │ │ ├── toggle-small-expand.png
│ │ │ └── toggle-small.png
│ │ └── style.css
│ └── index.html
├── src
│ ├── actions
│ │ └── index.js
│ ├── containers
│ │ ├── Editor.js
│ │ └── Node.js
│ ├── reducers
│ │ └── index.js
│ ├── generateTree.js
│ └── index.js
├── package.json
└── pnpm-lock.yaml
```
# راهاندازی پروژه
**برای اجرای پروژه، باید `NodeJS` و `npm` را از قبل نصب کرده باشید.**
- ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
- در پوشهی `toman-booklet` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- پس از انجام موفق این مراحل، با مراجعه به آدرس `http://localhost:3000/` میتوانید نتیجه را ببینید.
# جزئیات
طراحی state برنامه بدین صورت است:
``` js
{
editNode: null or nodeId,
nodes: {
nodeId: {
id: Int or String,
name: String,
content: String,
childIds: Array(nodes),
isDir: true or false
}, ...
}
}
```
- `editNode`: مشخص کننده `id` فایل در حال تغییر است. و یا `null` میباشد.
- `nodes[nodeID].id`: رشته یا عددی که `id` فایل یا پوشه را مشخص میکند.
- `nodes[nodeID].name`: نام فایل یا پوشه
- `nodes[nodeID].content`: محتوای فایل را نگه میدارد در حالت پوشه یک رشته خالی است.
- `nodes[nodeID].childIds`: آرایهای از `id` فایلها و پوشهها که زیرمجموعه پوشه فعلی هستند این مورد برای فایل یک آرایه خالی است.
- `nodes[nodeID].isDir`: اگر پوشه باشد `true` و در صورت فایل بودن مقدار `false` میگیرد.
در این پروژه دو قسمت کلی وجود دارد وجود دارد:
- `Node`: درخت فایلها و پوشهها را مشخص میکند و برای هر پوشه امکان ایجاد یک `پوشه جدید زیرمجموعه` و یا `فایل زیرمجموعه` وجود دارد و میتوان پوشه را حذف کرد. برای هر فایل نیز امکان حذف فایل وجود دارد.
- `Editor`: اگر روی نام یک فایل کلیک شود در این مولفه امکان تغییر نام و محتوای فایل وجود دارد و با زدن دکمه ذخیره تغییرات ذخیره میشود.
داخل فایل `actions/index.js` اطلاعات مربوط به action ها قرار دارد.
در این پروژه شش نوع action (عملیات) وجود دارد:
- `CREATE_NODE`: با اجرای این `action` فایل یا پوشه جدیدی ساخته شود. پدر و فرزندی در اینجا تعیین نمیشود.
- `ADD_CHILD`: رابطه پدر فرزندی برای دو `id` تعیین میشود.
- `REMOVE_CHILD`: مقدار `id` یک پوشه را میگیرد و از بین id فرزندانش `childId` را حذف میکند.
- `DELETE_NODE`: مقدار `id` یک فایل یا پوشه را میگیرد و آنرا و تمام زیر مجموعههای آنرا حذف میکند. اثرات `id` در پدر نباید از بین برود و حذف این اثرات با `DELETE_CHILD` انجام میشود.
- `EDIT_NODE`: امکان تغییر نام و محتوای درون فایل را فراهم میکند.
- `SET_EDIT_NODE`: فایل را به عنوان فایل فعلی برای تغییر انتخاب میکند.
طبق تعریف انجام شده بایستی `action`ها عمل کنند (reducer به درستی پیاده سازی شود) و همچنین موارد زیر پیاده سازی شود.
- با کلیک بر روی `📄` فایل جدیدی به پوشه اضافه شود.
- با کلیک بر روی `📂` پوشه جدیدی به پوشه جاری اضافه شود.
- با کلیک بر روی `×` فایل یا پوشه و تمامی فرزندان حذف شود.
- با کلیک بر روی نام فایل، به عنوان فایل فعلی مورد تغییر انتخاب شود.
- با تغییر نام و محتوای فایل و ذخیره آن تغییرات اعمال شود.
این تغییرات با استفاده از `action` ها انجام میگیرد.
# نکات
- شما تنها مجاز به اعمال تغییر در فایلهای `Editor.js`، `Node.js`، `reducers/index.js` هستید.
- پس از اعمال تغییرات، پروژه را _zip_ کرده و ارسال کنید.
دقت کنید که پوشهی `node_modules` در فایل ارسالی نباشد.
![مینروب](https://quera.ir/qbox/view/ZYevn8BMGB/photo_2019-07-12_13-40-11.jpg)
میخواهیم بازی مینروب را به شکل سهبعدی و دونفره با استفاده از ReactJS پیادهسازی کنیم.
این بازی به صورت دونفره بین دو نفر به شکل نوبتی بازی میشود که یک مکعب $ n \times n \times n$ داریم که هر خانه از این مکعب یا امن است یا حاوی یک مین است. با کلیک روی هر خانه، آن خانه باز میشود؛ بازشدن یکخانه به این معنی است که در صورتی که در آن خانه بمب باشد، بازیکنی که آن را باز کرده یک امتیاز گرفته و در غیر اینصورت تعداد مینهای اطراف این خانه شمرده میشوند، اگر صفر نبود تعداد این مینها روی آن خانه نمایش داده میشوند و در صورتی که صفر بود، مشخصاست که کل خانههای مجاور با این خانه نیز بدون مین هستند، آن خانهها هم باز میشوند و این بازشدن تا جایی ادامه پیدا میکند تا به خانههای بدون بمبی که اطرافشان حداقل یک مین است برسیم.
برای پایان بازی باید همهی خانههایی که در آن مین قرار گرفته توسط یکی از دو نفر باز شود، سپس اگر امتیاز دونفر نابرابر بود کسی که امتیاز بیشتری کسب کرده برندهی بازی و در غیراینصورت تساوی رخ میدهد.
چون بازی ۳ بعدی است و تنها میتوانیم دو بعد را در کامپیوتر ببینیم، صفحهی نمایش بازی را به دو بخش تقسیم میکنیم، بخش اول شامل یک صفحهی دوبعدی از بازی است که نشاندهندهی همهی خانههای یک عمق خاص از مکعب است و بخش دوم شامل نمای کوچکی از همهی عمقهاست که با کلیک بر روی هر عمق کدام، آن عمق روی بخش اول به نمایش در میآید.
دو خانه در مکعب مجاورند اگر رأس مشترک داشته باشند. یعنی یک خانه میتواند حداکثر ۲۶ خانهی مجاور داشته باشد.
# پروژه اولیه
پروژه اولیه را از [اینجا](https://quera.ir/qbox/download/phBnP2Qfit/minroob.zip) دانلود کنید.
<details>
<summary>
ساختار فایلهای پروژهی اولیه
</summary>
```
minroob
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── components
│ │ ├── board
│ │ │ ├── Board.css
│ │ │ ├── Board.js
│ │ │ ├── Cell.css
│ │ │ ├── Cell.js
│ │ │ └── bomb.svg
│ │ ├── menu
│ │ │ ├── Layers.css
│ │ │ ├── Layers.js
│ │ │ ├── State.css
│ │ │ └── State.js
│ │ ├── App.css
│ │ └── App.js
│ ├── constants.js
│ ├── index.css
│ └── index.js
├── README.md
├── package.json
├── pnpm-debug.log
└── pnpm-lock.yaml
```
</details>
# راهاندازی پروژه
**برای اجرای پروژه، باید `NodeJS` و `npm` (یا `pnpm`) را از قبل نصب کرده باشید.**
- در پوشهی `minroob` ، دستور `npm install` را برای نصب نیازمندیها اجرا کنید.
- **نکته:** برای نصب سریعتر از `pnpm install` استفاده کنید.
- در همین پوشه، دستور `npm start` را برای راهاندازی پروژه اجرا کنید.
- با مراجعه به `http://localhost:3000/` میتوانید نتیجه را ببینید.
- برای اجرای تستهای نمونه `npm test` را اجرا کنید.
# جزئیات
پروژه تعدادی مؤلفه تعریف شده که در جدول زیر مشاهده میکنید.
همچنین حالت بازی در بالاترین مؤلفه یعنی `App` قرار دارد:
| مؤلفه | توضیحات |
|:-----------:|---------------------------------------------------------------------------|
| **`App`** | مؤلفهی اصلی بازی است و حالت بازی در آن قرار دارد. |
| **`State`** | مؤلفهی بدون حالت برای اینکه نوبت کدام یک از دو نفر است و اینکه اگر بازی تمام شده، برندهی بازی کیست |
| **`Layers`** | مؤلفهی بدون حالت برای لیست عمقهای مکعب بازی |
| **`Board`** | مؤلفهی بدون حالت برای نمایش یک عمق از مکعب بازی |
| **`Cell`** | مؤلفهی بدون حالت برای نمایش یک خانه از بازی |
حالت بازی (حالت مؤلفهی `App`) به صورت زیر است.
```js
{
n: 5,
currentLayer: 0,
turn: 1, // turn is 1 or 2
board: [
[
{
hasBomb: true,
visible: false,
owner: null
},
{
hasBomb: false,
visible: false,
owner: null
},
...
],
...
]
}
```
همانطور که مشخص است، اندازهی مکعب، لایهای از مکعب که در حال مشاهدهی آن هستیم، کسی که نوبت اوست و اطلاعات مکعب در حالت قرار دارد.
- شمارهی لایهای که آنرا میبینیم `currentLayer` از صفر شروع میشود.
- مقدار `turn` یک یا دو است و اینکه نوبت نفر اول است یا دوم را نشان میدهد.
- `board` شامل اطلاعات مکعب بازی است که یک آرایه است که هر عضو آن مربوط به یک عمق است که آن یک آرایهی با $n \times n$ درایه است که وضعیت خانهها را صورت سطر به سطر از چپ به راست نشان میدهد.
هر خانه از مکعب شامل ۳ داده است:
- مقدار `hasBomb` که نشان میدهد آیا در این خانه مین قرار دارد یا امن است.
- مقدار `visible` که نشان میدهد آیا این خانه باز شدهاست یا خیر.
- مقدار `owner` که نشان میدهد اگر در خانه مین است، این مین را کدام یک از دو نفر تصاحب کردهاند، مقدار `owner` برای خانههای امن یا بازنشده `null` و برای بقیهی خانهها ۱ یا ۲ است.
مواردی که باید پیادهسازی کنید:
## ۱. نمایش اولیه
در نمایش اولیهی بازی، باید حالت کنونی بازی در مؤلفهی `Board` نمایش دادهشود دقت کنید مؤلفهی `Board` هم نمایش بورد اصلی بازی را بر عهده دارد و هم نمایش بوردهای کوچک در مؤلفهی `Layers` را، خصوصهی `type` به همین منظور استفاده شدهاست.
همچنین بورد عمقی که در حال نمایش است از `Layers` باید کلاس `current` را داشتهباشد.
همچنین `Cell` ها براساس کلاسهای تعریفشده در `Cell.css` کلاس داشتهباشند، مثلا اگر خانه باز نشدهاست، `.cell.unknown` باشد، اگر مین دارد و متعلق به نفر اول است `.cell.bomb.user1` باشد و اگر باز شده و روی آن عدد ۳ است `.cell.number.number-3` را داشتهباشد.
## ۲. عملکرد صحیح انتخاب بوردها
با کلیک بر روی `.layerMask` هر بورد در `Layers`، باید آن بورد برای نمایش داده شدن در بورد اصلی انتخاب شود.
## ۳. عملکرد صحیح کلیک روی خانهها
با کلیک بر روی یک `Cell` در بورد اصلی، در صورتی که بازی تمام نشدهباشد و خانه قبلا باز نشدهباشد، باید خانه باز شده و نوبت به نفر دیگر دادهشود.
## ۴. عملکرد صحیح `State`
در صورتی که بازی تمام نشده (تمام مینها باز نشدهاند.) و یکی از دو کلاس `.state.turn-1` یا `.state.turn-2` را بر حسب کسی که نوبتش است داشتهباشد و در صورت پایان بازی، یکی از ۳ کلاس `.state.win-1`, `.state.win-2` یا `.state.win-0` در صورت برد نفر اول یا دوم یا مساوی داشتهباشد.
# نکات
- میتوانید در صورت نیاز دادههای دیگری نیز در حالت مؤلفه ذخیره کنید.
اما مجاز به تغییر ساختار دادههای فعلی نیستید.
- شما تنها مجاز به اعمال تغییر در فایلهای `App.js`، `Layers.js`، `Board.js`، `State.js` و `Cell.js` هستید.
- پس از اعمال تغییرات، پروژه را _Zip_ کرده و ارسال کنید.
دقت کنید که پوشهی `node_modules` در فایل ارسالی نباشد.