عکس تار


در این سوال از شما می‌خواهیم تا لوگوی کوئرا را به طرز خاصی نمایش دهید. در صفحه‌ای که شما می‌سازید باید یک لوگوی کوئرا وجود داشته باشد و وقتی که موس وارد عکس می‌شود عکس باید تار شود و زمانی که خارج می‌شود عکس باید دوباره حالت عادی خود بگیرد.

از شما می‌خواهیم تا این سرویس را روی عکسی که به شما داده می‌شود اجرا کنید.

پروژه اولیه🔗

پروژه اولیه را از اینجا دانلود کنید. ساختار فایل‌های این پروژه به صورت زیر است.

blur-image
├── Result.svg
├── index.html
└── quera.svg
Plain text

جزئیات🔗

در صورتی که موس داخل عکس باشد باید دو ویژگی زیر به CSS مربوط به عکس که دارای id برابر با image است اضافه شوند.

filter: blur(8px);
-webkit-filter: blur(8px);
CSS

در غیر این صورت هم نباید چیزی اضافه شود.

نکات🔗

  • توجه کنید که داوری خودکار بر مبنای شناسه (id) عناصر انجام می‌شود. پس دقت کنید که عناصر شناسه‌ی صحیح داشته باشند.

  • فرض کنید سیستم به اینترنت متصل نیست، بنابراین از ارجاع به فایل‌های موجود در وب (CDN ها) خودداری کنید.

  • پروژه را با ساختار زیر ارسال کنید. یعنی باید در Zip ارسالی شما تنها فایل ‍‍index.html وجود داشته باشد.

    [your-zip-file-name].zip
    └── index.html
    Plain text

پیداکردن گنج


در این سوال قصد داریم یک بازی ساده چند مرحله‌ای را پیاده‌سازی کنیم. نحوه اجرای بازی به‌ این گونه است که در هر مرحله یک نقطه از صفحه به عنوان گنج انتخاب می‌شود و هر چه قدر که موس را به آن نقطه نزدیک‌تر کنید رنگ صفحه روشن‌تر می‌شود.

هم‌چنین این بازی باید شامل تعدادی مرحله باشد که در هر مرحله نقطه‌ای که به عنوان گنج انتخاب می‌شود متفاوت است و باید اطلاعات مربوط به مکان گنج را از یک فایل JSON بخوانید.

برای درک جزئیات بیشتر می‌توانید این نمونه را ببینید.

توضیح تصویر

پروژه اولیه🔗

پروژه اولیه را از اینجا دانلود کنید.ساختار فایل‌های این پروژه به صورت زیر است.

findtreasure
├── index.html
├── levels.json
└── style.css
Plain text

جزئیات🔗

فایل levels.json:

  • این فایل مراحل بازی را مشخص می‌کند و یک ویژگی به نام levels دارد که حاوی یک آرایه است که مختصات گنج را در آن مرحله مشخص می‌کند.

  • اندازه لیست موجود در این فایل هم تعداد مراحل را مشخص می‌کند.

ویژگی background-color برای square:

  • در صورتی که موس خارج از این شی باشد باید رنگ #000 باشد.
  • در غیر این صورت ابتدا مقدار فاصله منهتنی موس و مکان گنج را به دست آورید و نام این مقدار را ‍‍distdist بگذارید. در آن صورت هر سه مولفه رنگ باید 255dist2255 - \lfloor \dfrac {dist}{2} \rfloor باشد.

منظور از فاصله منهتنی دو نقطه در این سوال مجموع اختلاف مولفه xx و yy آن‌هاست، یعنی اگر دو نقطه (x1,y1)(x_1, y_1) و (x2,y2)(x_2, y_2) داشته باشیم فاصله آن‌ها برابر با x1x2+y1y2 |x_1 - x_2| + |y_1 - y_2|\ است.

مقدار متنی ویژگی level:

  • در هر زمان که فاصله منهتنی موس و گنج کم‌تر از 1010 شد این مرحله تمام می‌شود و باید مرحله بعدی نمایش داده شود و ویژگی level هم باید مقدارش یکی بیشتر شود. در ابتدای بازی در مرحله ۰ هستیم و مقدار ویژگی level هم باید به صورت ‍‍Level #id باشد که #id شماره مرحله کنونی است.
  • هم‌چنین در صورتی که آخرین مرحله هم تمام شد باید مقدار این ويژگی به You won! تغییر کند و رنگ ‍‍square هم برای همیشه سفید بماند. (حتی در زمانی که موس از صفحه خارج شد.)

تغییرات لازم را در فایل index.html و در صورت نیاز فایل‌‌های .js خود را اضافه کنید.

توجه کنید که در هنگام تست‌کردن ممکن است فایل ‍‍levels.json تغییر کند.

نکات🔗

  • توجه کنید که داوری خودکار بر مبنای شناسه (id) عناصر انجام می‌شود. پس دقت کنید که عناصر شناسه‌ی صحیح داشته باشند.
  • در صورتی که هنگام ارسال درخواست برای دریافت فایل levels.json با خطای Cross Origin از طرف مرورگر مواجه شدید، به جای باز کردن مستقیم فایل HTML با مرورگر، پوشه پروژه را با یک وب‌سرور (مثلاً python -m http.server و یا npx http-server‍) serve کنید، و یا مرورگر FireFox را امتحان کنید.
  • فرض کنید سیستم به اینترنت متصل نیست، بنابراین از ارجاع به فایل‌های موجود در وب (CDN ها) خودداری کنید.
  • پروژه را با ساختار زیر ارسال کنید. تغییر تنها در مواردی که با * مشخص شده مجاز است و ارسال سایر فایل‌ها الزامی نیست.
    [your-zip-file-name].zip
    ├── index.html
    └── your .js files (Optional)
    Plain text

دفترچه تومن‌پی


مهارت‌های لازم:

  • آشنایی با ReactJS
  • آشنایی با Redux
  • کدخوانی

محمد و جواد و مهدی همیشه برای اینکه می‌توانند از پرداخت تومن استفاده کنند خیلی خوشحال هستند آنها می‌خواهند دفترچه یادداشتی با react و redux درست کنند که خاطرات استفاده از پرداخت تومن را در آن یادداشت کنند. ظاهر برنامه

پروژه اولیه🔗

پروژه اولیه را از اینجا دانلود کنید. ساختار فایل‌های این پروژه به صورت زیر است.

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
Plain text

راه‌اندازی پروژه🔗

برای اجرای پروژه، باید NodeJS و npm را از قبل نصب کرده باشید.

  • ابتدا پروژه‌ی اولیه را دانلود و از حالت فشرده خارج کنید.
  • در پوشه‌ی toman-booklet ، دستور npm install را برای نصب نیازمندی‌ها اجرا کنید.
  • در همین پوشه، دستور npm start را برای راه‌اندازی پروژه اجرا کنید.
  • پس از انجام موفق این مراحل، با مراجعه به آدرس http://localhost:3000/ می‌توانید نتیجه را ببینید.

جزئیات🔗

طراحی state برنامه بدین صورت است:

{
    editNode: null or nodeId,
    nodes: {
        nodeId: {
            id: Int or String,
            name: String,
            content: String,
            childIds: Array(nodes),
            isDir: true or false
        }, ...
    }
}
JavaScript
  • 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 در فایل ارسالی نباشد.

مین‌روب دو نفره


مین‌روب

می‌خواهیم بازی مین‌روب را به شکل سه‌بعدی و دونفره با استفاده از ReactJS پیاده‌سازی کنیم.

این بازی به صورت دونفره بین دو نفر به شکل نوبتی بازی می‌شود که یک مکعب n×n×n n \times n \times n داریم که هر خانه از این مکعب یا امن است یا حاوی یک مین است. با کلیک روی هر خانه، آن خانه باز می‌شود؛ بازشدن یک‌خانه به این معنی است که در صورتی که در آن خانه بمب باشد، بازیکنی که آن را باز کرده یک امتیاز گرفته و در غیر این‌صورت تعداد مین‌های اطراف این خانه شمرده می‌شوند، اگر صفر نبود تعداد این مین‌ها روی آن خانه نمایش داده می‌شوند و در صورتی که صفر بود، مشخص‌است که کل خانه‌های مجاور با این خانه نیز بدون مین هستند، آن خانه‌ها هم باز می‌شوند و این بازشدن تا جایی ادامه پیدا می‌کند تا به خانه‌های بدون بمبی که اطرافشان حداقل یک مین است برسیم.

برای پایان بازی باید همه‌ی خانه‌هایی که در آن مین قرار گرفته توسط یکی از دو نفر باز شود، سپس اگر امتیاز دونفر نابرابر بود کسی که امتیاز بیشتری کسب کرده برنده‌ی بازی و در غیراین‌صورت تساوی رخ می‌دهد.

چون بازی ۳ بعدی است و تنها می‌توانیم دو بعد را در کامپیوتر ببینیم، صفحه‌ی نمایش بازی را به دو بخش تقسیم می‌کنیم، بخش اول شامل یک صفحه‌ی دوبعدی از بازی است که نشان‌دهنده‌ی همه‌ی خانه‌های یک عمق خاص از مکعب است و بخش دوم شامل نمای کوچکی از همه‌ی عمق‌هاست که با کلیک بر روی هر عمق کدام، آن عمق روی بخش اول به نمایش در می‌آید.

دو خانه در مکعب مجاورند اگر رأس مشترک داشته باشند. یعنی یک خانه می‌تواند حداکثر ۲۶ خانه‌ی مجاور داشته باشد.

پروژه اولیه🔗

پروژه اولیه را از اینجا دانلود کنید.

ساختار فایل‌های پروژه‌ی اولیه
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
Plain text

راه‌اندازی پروژه🔗

برای اجرای پروژه، باید NodeJS و npm (یا pnpm) را از قبل نصب کرده باشید.

  • در پوشه‌ی minroob ، دستور npm install را برای نصب نیازمندی‌ها اجرا کنید.
    • نکته: برای نصب سریع‌تر از pnpm install استفاده کنید.
  • در همین پوشه، دستور npm start را برای راه‌اندازی پروژه اجرا کنید.
  • با مراجعه به http://localhost:3000/ می‌توانید نتیجه را ببینید.
  • برای اجرای تست‌های نمونه npm test را اجرا کنید.

جزئیات🔗

پروژه تعدادی مؤلفه تعریف شده که در جدول زیر مشاهده می‌کنید. همچنین حالت بازی در بالاترین مؤلفه یعنی App قرار دارد:

مؤلفه توضیحات
App مؤلفه‌ی اصلی بازی است و حالت بازی در آن قرار دارد.
State مؤلفه‌ی بدون حالت برای اینکه نوبت کدام یک از دو نفر است و اینکه اگر بازی تمام شده، برنده‌ی بازی کیست
Layers مؤلفه‌ی بدون حالت برای لیست عمق‌های مکعب بازی
Board مؤلفه‌ی بدون حالت برای نمایش یک عمق از مکعب بازی
Cell مؤلفه‌ی بدون حالت برای نمایش یک خانه از بازی

حالت بازی (حالت مؤلفه‌ی App) به صورت زیر است.

{
  n: 5,
  currentLayer: 0,
  turn: 1, // turn is 1 or 2
  board: [
    [
      {
        hasBomb: true,
        visible: false,
        owner: null
      },
      {
        hasBomb: false,
        visible: false,
        owner: null
      },
      ...
    ],
    ...
  ]
}
JavaScript

همان‌طور که مشخص است، اندازه‌ی مکعب، لایه‌ای از مکعب که در حال مشاهده‌ی آن هستیم، کسی که نوبت اوست و اطلاعات مکعب در حالت قرار دارد.

  • شماره‌ی لایه‌ای که آن‌را می‌بینیم currentLayer از صفر شروع می‌شود.
  • مقدار turn یک یا دو است و اینکه نوبت نفر اول است یا دوم را نشان می‌دهد.
  • board شامل اطلاعات مکعب بازی است که یک آرایه است که هر عضو آن مربوط به یک عمق است که آن یک آرایه‌ی با n×nn \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 در فایل ارسالی نباشد.