بازی حدس عدد: راه اندازی UI و متغیرهای DOM

21 آبان 1398
بازی حدس عدد: راه اندازی UI و متغیر های DOM

راه اندازی UI

به پروژه ی سوم از این سری آموزشی خوش آمدید. در این پروژه می خواهیم یک بازی حدس عدد را بسازیم که به شکل زیر کار می کند:

  • یک عدد بین 1 تا 10 توسط جاوا اسکریپت انتخاب می شود (شما میتوایند 1 تا 20 یا هر عدد دیگری را نیز انتخاب کنید).
  • کاربر تا 3 بار می تواند حدس بزند که عدد انتخاب شده چه عددی است.
  • اگر در این 3 شانس توانست مقدار را به درستی حدس بزند برنده می شود اما اگر نتواند، بازی را باخته و می تواند دوباره بازی کند.

ما در این پروژه ها سعی می کنیم از کتابخانه های مختلفی برای راه اندازی UI خود استفاده کنیم تا شما با انواع مختلف آن ها آشنا شویم. در این پروژه از کتابخانه ی Skeleton استفاده می کنیم که یک کتابخانه ی بسیار کم حجم و فشرده و البته بسیار ساده می باشد:

نمایی از وب سایت Skeleton
نمایی از وب سایت Skeleton

متاسفانه وب سایت رسمی این کتابخانه، ip های ایران را تحریم کرده اند بنابراین برای رجوع به سایت آن ها باید از ابزار های رفع تحریم استفاده کنید. من از CDN زیر برای بارگذاری در پروژه مان استفاده می کنم:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.css" integrity="sha256-ECB9bbROLGm8wOoEbHcHRxlHgzGqYpDtNTgDTyDz0wg=" crossorigin="anonymous" />

برای راه اندازی پروژه ابتدا یک پوشه به نام NumberGuesser ایجاد می کنیم و مثل همیشه درون آن دو فایل مختلف خواهیم داشت:

  • html
  • js

برای محتوای فایل html می توانید کدهای زیر را در آن کپی کنید:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.css" />
  <title>Number Guesser</title>
</head>

<body>
  <div class="container">
    <h1>Number Guesser</h1>
    <div id="game">
      <p>Guess a number between <span class="min-num"></span> and <span class="max-num"></span></p>
      <input type="number" id="guess-input" placeholder="Enter your guess...">
      <input type="submit" value="Submit" id="guess-btn">
      <p class="message"></p>
    </div>
  </div>

  <script src="app.js"></script>
</body>

</html>

اگر دوست داشتید می توانید فایل HTML را بیشتر بررسی کنید اما کدهای آن بسیار ساده است و من توضیحاتی در مورد آن نمی دهم. حالا وارد فایل app.js می شویم تا کدهای جاوا اسکریپت آن را بنویسیم.

نمایی از ظاهر برنامه ی ما
نمایی از ظاهر برنامه ی ما

اولین کار ما تعریف برخی از متغیرهای مربوط به بازی است:

// Game values
let min = 1,
    max = 10,
    winningNum = 2,
    guessesLeft = 3;

کد بالا خطا نیست بلکه روش بهتر تعریف متغیرهای مختلف است. شما می توانید کلیدواژه ی let را بنویسید و سپس متغیرها را با ویرگول از هم جدا کنید. عدد min قرار است حداقل و max حداکثر باشد. این دو عدد تعریف می کنند که برنامه بین چه بازه ای عدد را انتخاب کند. متغیر winningNum نیز عدد انتخاب شده توسط جاوا اسکریپت است که البته فعلا به صورت دستی آن را 2 قرار داده ایم تا بعدا کدهایش را تکمیل کنیم و به صورت تصادفی انتخاب شود. gussesLeft نیز به معنی حدس های باقی مانده برای کاربر است که در اولین اجرای برنامه باید 3 باشد (کاربر با 3 حدس بازی را شروع می کند). این متغیرها مربوط به خود بازی هستند و در طول بازی تغییر می کنند به همین دلیل از نوع let هستند اما باید متغیرهای مخصوص UI را نیز تعریف کنیم که از نوع const خواهند بود. بنابراین:

// UI Elements
const game = document.querySelector('#game'),
    minNum = document.querySelector('.min-num'),
    maxNum = document.querySelector('.max-num'),
    guessBtn = document.querySelector('#guess-btn'),
    guessInput = document.querySelector('#guess-input'),
    message = document.querySelector('.message');

توضیح متغیرها:

  • Game تمام قسمت بازی است به غیر از <h1>
  • minNum یک تگ span درون فایل html است. قرار است بازه ی اعداد را با جاوا اسکریپت تعیین کنیم و جاوا اسکریپت این بازه را در مرورگر نمایش دهد بنابراین این مقدار را در یک تگ span گذاشته ایم تا جاوا اسکریپت بتواند آن را هدف بگیرد.
  • maxNum نیز مانند minNum است با این تفاوت که عدد حداکثر را مشخص می کند.
  • guessBtn همان دکمه ی Submit است.
  • guessInput تنها فیلد فرم ما است که کاربر حدس خود را در آن می نویسد.
  • Message یک تگ <p> خالی است که در فایل html قرار داده ایم. این تگ قرار است نتیجه ی حدس کاربر را به او بگوید؛ آیا کاربر عدد درست را حدس زده است یا اینکه باید دوباره تلاش کند؟

حالا باید مقدار دو <span> ای را که عدد حداقل و حداکثر را مشخص می کنند با استفاده از جاوا اسکریپت تعیین کنیم بنابراین می گوییم:

// Assign UI min and max
minNum.textContent = min;
maxNum.textContent = max;

حالا به فایل html بروید و مقدار 1 و 10 را از درون آن دو تگ <span> حذف کنید چرا که جاوا اسکریپت این مقادیر را برایمان قرار خواهد داد. از این به بعد اگر مقدار متغیرهای min و max را تغییر دهید، مقدار این اعداد در span ها نیز تغییر می کند.

در قدم بعد باید event-listener خود را تعریف کنیم:

guessBtn.addEventListener('click', function () {

});

اولین کاری که باید درون این تابع انجام دهیم دریافت مقدار تایپ شده توسط کاربر است اما برای آنکه مطمئن شویم مقدار تایپ شده توسط کاربر یک عدد خواهد بود از تابع parseInt استفاده می کنیم:

guessBtn.addEventListener('click', function () {
    let guess = parseInt(guessInput.value);

});

برخی اوقات زمانی که کاربر مثلا عدد 2 را درون input وارد می کند، عدد 2 به صورت یک رشته (یعنی "2") ارسال می شود بنابراین با parseInt آن را به یک عدد تبدیل می کنیم. دلیل اینکه می خواهیم این مقدار حتما عدد باشد این است که بعدا می خواهیم آن را با عدد اصلی که جاوا اسکریپت انتخاب کرده است مقایسه کنیم و در این مقایسه هر دو باید از یک نوع باشند.

در مرحله ی بعد باید ورودی کاربر را ارزیابی کنیم که خارج از بازه ی تعیین شده (اعداد حداقل و حداکثر) نباشد بنابراین می گوییم:

guessBtn.addEventListener('click', function () {
    let guess = parseInt(guessInput.value);

    // Validate
    if (isNaN(guess) || guess < min || guess > max) {
        setMessage(`Please enter a number between ${min} and ${max}`, 'red');
    }

});

به نظر شما چرا داده ی کاربر را چک کرده ام تا NaN نباشد؟ در حالت عادی اگر کاربر فیلد را خالی بگذارد و فرم را ثبت کند، یک رشته ی خالی به ما ارسال می شود اما از آنجایی که داده های کاربر را با parseInt تبدیل به عدد کرده ایم، رشته ی خالی تبدیل به NaN می شود. به همین خاطر به جای چک کردن برای خالی بودن فیلد، NaN بودن ورودی را چک می کنیم. دو شرط بعدی هم می گویند که عدد وارد شده بیشتر از حداکثر و کمتر از حداقل نباشد. اگر شرط برقرار بود (یعنی داده ی کاربر نامعتبر بود) تابعی به نام setMessage اجرا می شود که به کاربر می گوید عددی بین بازه ی تعیین شده را وارد کند. پارامتر دوم این تابع یک رنگ است که رنگ متن را دریافت می کند. من برای این خطا رنگ قرمز را انتخاب کرده ام. حالا باید تابع setMessage را تعریف کنیم. ما خارج از event-listener خودمان آن را اینگونه تعریف می کنیم:

// Set message
function setMessage(msg, color){
  message.style.color = color;
  message.textContent = msg;
}

در مرحله ی بعد باید ببینیم که آیا حدس کاربر صحیح است یا خیر. برای این کار از یک شرط if درون event-listener استفاده می کنیم:

// Listen for guess
guessBtn.addEventListener('click', function () {
    let guess = parseInt(guessInput.value);

    // Validate
    if (isNaN(guess) || guess < min || guess > max) {
        setMessage(`Please enter a number between ${min} and ${max}`, 'red');
    }

    // Check if won
    if (guess === winningNum) {
        // Disable input
        guessInput.disabled = true;
        // Change border color
        guessInput.style.borderColor = 'green';
        // Set message
        setMessage(`${winningNum} is correct, YOU WIN!`, 'green');

    } else {

    }
});

در این شرط if می گوییم آیا حدس کاربر برابر با winingNum (عدد انتخاب شده توسط جاوا اسکریپت) است؟ اگر چنین بود ابتدا input را غیرفعال می کنیم تا کاربر چیز دیگری تایپ نکند (او برنده شده و باز تمام شده است). سپس رنگ حاشیه فیلد input را سبز می کنیم تا UI زیباتری داشته باشیم و در آخر با استفاده از همان تابع setMessage به کاربر می گوییم که برنده شده است. رنگ این پیام نیز باید سبز (green) باشد.

در قسمت بعدی باید کدهای باختن کاربر را بنویسیم (قسمت else در شرط if بالا)؛ مثلا چند حدس دیگر باقی مانده و مسائل از این قبیل...

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری پروژه‌های مدرن جاوا اسکریپت توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.