لینک‌های مفید برای شرکت در مسابقه:

در زمان مسابقه می‌توانید سوال‌های خود را از قسمت "سوال بپرسید" مطرح کنید.

بعد از مسابقه در ساعت ۱۹:۰۰ امروز وبیناری برای حل بخشی از سوالات مسابقه و پاسخگویی به سوالات شما تدارک دیده‌ایم که می‌توانید از طریق این لینک شرکت نمایید. دقت کنید که در هنگام ورود باید گزینه مهمان را انتخاب نمایید.

Laravel - ایکس او


نیما در این روزهای کرونایی حوصله‌اش به شدت سر رفته. از این رو، تصمیم گرفته است تا با کمک دوست صمیمی‌اش، محمدرضا، یک وبسایت ساده بسازد که در آن بتوان XO بازی کرد. قرار است نیما API این بازی را طراحی کند و محمدرضا فرانت کار را پیش ببرد. اخیراً نیما درگیر امتحانات پایان‌ترمش شده و می‌خواهد این وبسایت تا چند روز دیگر آماده شود. بنابراین، او از شما خواسته است تا API این بازی را پیاده‌سازی کنید.

جزئیات پروژه🔗

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

ساختار فایل‌ها
xo
├── app
│   ├── Console
│   │   └── Kernel.php
│   ├── Exceptions
│   │   └── Handler.php
│   ├── Http
│   │   ├── Controllers
│   │   │   ├── API
│   │   │   │   ├── AuthController.php
│   │   │   │   └── GameController.php
│   │   │   └── Controller.php
│   │   ├── Middleware
│   │   │   ├── Authenticate.php
│   │   │   ├── EncryptCookies.php
│   │   │   ├── PreventRequestsDuringMaintenance.php
│   │   │   ├── RedirectIfAuthenticated.php
│   │   │   ├── TrimStrings.php
│   │   │   ├── TrustHosts.php
│   │   │   ├── TrustProxies.php
│   │   │   └── VerifyCsrfToken.php
│   │   └── Kernel.php
│   ├── Models
│   │   ├── Game.php
│   │   ├── Move.php
│   │   └── User.php
│   └── Providers
│       ├── AppServiceProvider.php
│       ├── AuthServiceProvider.php
│       ├── BroadcastServiceProvider.php
│       ├── EventServiceProvider.php
│       └── RouteServiceProvider.php
├── bootstrap
│   ├── cache
│   │   ├── packages.php
│   │   ├── routes-v7.php
│   │   └── services.php
│   └── app.php
├── config
│   ├── app.php
│   ├── auth.php
│   ├── broadcasting.php
│   ├── cache.php
│   ├── cors.php
│   ├── database.php
│   ├── filesystems.php
│   ├── hashing.php
│   ├── logging.php
│   ├── mail.php
│   ├── queue.php
│   ├── services.php
│   ├── session.php
│   └── view.php
├── database
│   ├── factories
│   │   └── UserFactory.php
│   ├── migrations
│   │   ├── 2014_10_12_000000_create_users_table.php
│   │   ├── 2014_10_12_100000_create_password_resets_table.php
│   │   ├── 2019_08_19_000000_create_failed_jobs_table.php
│   │   ├── 2021_01_05_094004_create_games_table.php
│   │   └── 2021_01_05_095752_create_moves_table.php
│   ├── seeders
│   │   └── DatabaseSeeder.php
│   └── database.sqlite
├── public
│   ├── favicon.ico
│   ├── index.php
│   ├── robots.txt
│   └── web.config
├── resources
│   ├── css
│   │   └── app.css
│   ├── js
│   │   ├── app.js
│   │   └── bootstrap.js
│   ├── lang
│   │   └── en
│   │       ├── auth.php
│   │       ├── pagination.php
│   │       ├── passwords.php
│   │       └── validation.php
│   └── views
│       └── welcome.blade.php
├── routes
│   ├── api.php
│   ├── channels.php
│   ├── console.php
│   └── web.php
├── storage
│   ├── app
│   │   └── public
│   ├── framework
│   │   ├── cache
│   │   ├── sessions
│   │   ├── testing
│   │   └── views
│   ├── logs
│   │   └── laravel.log
│   ├── oauth-private.key
│   └── oauth-public.key
├── tests
│   ├── Feature
│   │   └── ExampleTest.php
│   ├── Unit
│   │   └── ExampleTest.php
│   ├── CreatesApplication.php
│   └── TestCase.php
├── README.md
├── artisan
├── composer.json
├── package.json
├── phpunit.xml
├── server.php
└── webpack.mix.js
Plain text
راه‌اندازی پروژه

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

  • ابتدا پروژه‌ی اولیه را دانلود و از حالت فشرده خارج کنید.
  • دستور composer install را در پوشه‌ی اصلی پروژه برای نصب نیازمندی‌ها اجرا کنید.
  • دستور php artisan migrate را برای پیکربندی کامل پایگاه داده اجرا کنید.
  • دستور php artisan passport:install را برای پیکربندی Laravel Passport اجرا کنید.

برای احراز هویت در این پروژه از Laravel Passport استفاده شده است. هم‌چنین، برای پایگاه داده از SQLite استفاده شده است.

مدل‌ها🔗

این پروژه شامل ۳ مدل به شرح زیر است:

  1. مدل User:
نام فیلد تعریف
id شناسه‌ی کاربر
username نام کاربری
email آدرس ایمیل
password رمز عبور
  1. مدل Game:
نام فیلد تعریف
id شناسه‌ی بازی
host_id شناسه‌ی کاربر میزبان
opponent_id شناسه‌ی حریف
is_host_turn یک boolean که بیانگر این است که الآن نوبت میزبان است یا خیر (مقدار پیش‌فرض آن false است)؛ مقدار آن در صورتی که بازی تمام شده باشد اهمیتی ندارد.
status یک enum با مقدار پیش‌فرض pending به این معنا که بازی در انتظار تأیید است. اگر مقدار آن rejected باشد، یعنی حریف درخواست بازی را رد کرده است. اگر ongoing باشد، یعنی بازی در حال انجام است. اگر win باشد، یعنی میزبان برنده شده است. اگر lose باشد، یعنی حریف برنده شده است. اگر tie باشد، یعنی بازی مساوی شده است.
  1. مدل Move:
نام فیلد تعریف
id شناسه‌ی حرکت
game_id شناسه‌ی بازی
position یک عدد در بازه‌ی 1 تا 9 که بیانگر موقعیت حرکت است
is_by_host یک boolean که بیانگر این است که این حرکت توسط میزبان صورت گرفته است یا خیر

دو مورد زیر باید در مدل‌ها پیاده‌سازی شوند:

  1. متد games در مدل User را طوری پیاده‌سازی کنید که با اجرای متد get روی نتیجه‌ی آن، بتوان آرایه‌ای از بازی‌هایی که کاربر در آن‌ها نقش میزبان یا حریف دارد را در اختیار داشت.
  2. متد getBoardAttribute در مدل Game را طوری پیاده‌سازی کنید که صفحه‌ی بازی را در قالب یک آرایه‌ی ۳×۳ برگرداند. خانه‌های پرشده توسط شروع‌کننده‌ی بازی باید با X و خانه‌های پرشده توسط میزبان بازی باید با O نمایش داده شوند. خانه‌های خالی نیز باید با حرف _ نمایش داده شوند. مثلاً اگر در یک بازی ابتدا حریف خانه‌ی 9 را پر کند، سپس میزبان خانه‌ی 5 را پر کند و در ادامه حریف خانه‌ی 1 را پر کند، این متد باید چنین چیزی را برگرداند:
    [
     ['X', '_', '_'],
     ['_', 'O', '_'],
     ['_', '_', 'X']
    ]
    PHP

مسیرها🔗

دو route زیر به کنترلر API\AuthController متصل هستند و باید پیاده‌سازی شوند:

  1. ثبت‌نام (POST /register): سه فیلد username، email و password باید در بدنه‌ی درخواست موجود باشند. هم‌چنین، دو فیلد username و email باید در جدول users یکتا باشند. در صورتی که ورودی شرایط لازم را نداشتند، خطاهای پیش‌فرض Validator لاراول را در قالب JSON برگردانید. در غیر این‌صورت، یک آرایه شامل کلید token با مقدار توکن تولیدشده توسط Laravel Passport را در پاسخ برگردانید.
  2. ورود (POST /login): دو فیلد username و password باید در بدنه‌ی درخواست موجود باشند. در صورتی که ورودی شرایط لازم را نداشتند، خطاهای پیش‌فرض Validator لاراول را در قالب JSON برگردانید. اگر نام کاربری یا رمز عبور نادرست بود، یک آرایه شامل کلید error با مقدار invalid credentials را در قالب JSON برگردانید. در غیر این‌صورت، یک آرایه شامل کلید token با مقدار توکن تولیدشده توسط Laravel Passport را در پاسخ برگردانید.

پنج route زیر از middleware auth:api استفاده می‌کنند و نیازمند هدرهای Accept: application/json و Authorization: Bearer token هستند. این route ها به کنترلر API\GameController متصل هستند و باید پیاده‌سازی شوند:

  1. لیست بازی‌های کاربر (GET /games): بازی‌هایی که کاربر در آن‌ها میزبان یا حریف دارد را در قالب JSON برگردانید.
  2. ساخت بازی جدید (POST /games/create): فیلد opponent باید در بدنه‌ی درخواست موجود باشد. در صورتی که ورودی شرایط لازم را نداشتند، خطاهای پیش‌فرض Validator لاراول را در قالب JSON برگردانید. در صورتی که کاربری با نام کاربری واردشده وجود نداشت، آرایه‌ای شامل کلید error با مقدار opponent does not exist را با کد پاسخ 404 برگردانید. اگر نام کاربری واردشده با نام کاربری کاربر فعلی یکسان بود، آرایه‌ای شامل کلید error با مقدار you cannot play with yourself را برگردانید. در غیر این‌صورت، بازی را ایجاد کرده و آن را در پاسخ به‌صورت JSON برگردانید.
  3. مشاهده‌ی اطلاعات بازی (GET /games/{id}): در صورتی که بازی‌ای با شناسه‌ی واردشده وجود نداشت یا کاربر در آن میزبان یا حریف نبود، آرایه‌ای شامل کلید error با مقدار game does not exist را با کد پاسخ 404 برگردانید. در غیر این‌صورت، آبجکت بازی را در پاسخ برگردانید.
  4. تأیید درخواست بازی (GET /games/accept/{id}): در صورتی که بازی‌ای با شناسه‌ی واردشده وجود نداشت یا کاربر در آن میزبان یا حریف نبود، آرایه‌ای شامل کلید error با مقدار game does not exist را با کد پاسخ 404 برگردانید. اگر بازی در حال انجام بود، آرایه‌ای شامل کلید error با مقدار game is already ongoing را برگردانید. اگر درخواست بازی قبلاً رد شده بود، آرایه‌ای شامل کلید error با مقدار game is already rejected را برگردانید. اگر بازی خاتمه یافته بود، آرایه‌ای شامل کلید error با مقدار game is already finished را برگردانید. در غیر این‌صورت، وضعیت بازی را به ongoing تغییر داده و آرایه‌ای شامل مقدار success را در قالب JSON برگردانید. اگر کاربر میزبان بازی بود، آرایه‌ای شامل کلید error با مقدار you cannot accept your games را برگردانید.
  5. رد درخواست بازی (GET /games/reject/{id}): در صورتی که بازی‌ای با شناسه‌ی واردشده وجود نداشت یا کاربر در آن میزبان یا حریف نبود، آرایه‌ای شامل کلید error با مقدار game does not exist را با کد پاسخ 404 برگردانید. اگر بازی در حال انجام بود، آرایه‌ای شامل کلید error با مقدار game is already ongoing را برگردانید. اگر درخواست بازی قبلاً رد شده بود، آرایه‌ای شامل کلید error با مقدار game is already rejected را برگردانید. اگر بازی خاتمه یافته بود، آرایه‌ای شامل کلید error با مقدار game is already finished را برگردانید. در غیر این‌صورت، وضعیت بازی را به rejected تغییر داده و آرایه‌ای شامل مقدار success را در قالب JSON برگردانید. اگر کاربر میزبان بازی بود، آرایه‌ای شامل کلید error با مقدار you cannot reject your games را برگردانید.
  6. انجام حرکت در بازی (POST /games/move/{id}): فیلد position باید با مقداری عددی و در بازه‌ی 1 تا 9 در بدنه‌ی درخواست موجود باشد. در صورتی که ورودی شرایط لازم را نداشتند، خطاهای پیش‌فرض Validator لاراول را در قالب JSON برگردانید. در صورتی که بازی‌ای با شناسه‌ی واردشده وجود نداشت یا کاربر در آن میزبان یا حریف نبود، آرایه‌ای شامل کلید error با مقدار game does not exist را با کد پاسخ 404 برگردانید. اگر درخواست بازی در انتظار تأیید حریف بود، آرایه‌ای شامل کلید error با مقدار game is already pending را برگردانید. اگر درخواست بازی قبلاً رد شده بود، آرایه‌ای شامل کلید error با مقدار game is already rejected را برگردانید. اگر بازی خاتمه یافته بود، آرایه‌ای شامل کلید error با مقدار game is already finished را برگردانید. اگر نوبت کاربر نبود، آرایه‌ای شامل کلید error با مقدار it is not your turn را برگردانید (توجه کنید که همیشه حریف شروع‌کننده‌ی بازی است). اگر موقعیت حرکت در حال حاضر ثبت شده بود، آرایه‌ای شامل کلید error با مقدار cell is already full را برگردانید. در غیر این‌صورت، حرکت را ثبت کرده و آرایه‌ای شامل مقدار success را در قالب JSON برگردانید. توجه کنید که پس از ثبت حرکت، باید بررسی کنید که آیا برنده‌ی بازی (یا مساوی شدن بازی) می‌تواند تعیین شود یا خیر. در صورتی که این مورد قابل تشخیص بود، وضعیت بازی باید تغییر کند.

توجه: شما تنها مجاز به تغییر فایل‌های موجود در پوشه‌ی /app هستید.

آن‌چه باید آپلود کنید🔗

پس از اعمال تغییرات، کل پروژه به غیر از پوشه‌ی vendor را Zip کرده و آپلود کنید. نام فایل Zip اهمیتی ندارد.

ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.