مسیرها
/
C#
C#
/
تمرین‌ها
/
جادوگران و جنگجویان
جادوگران و جنگجویان

جادوگران و جنگجویان

تمرین یادگیری

مقدمه

ارث‌بری

در C#، می‌توان یک سلسله‌مراتب «کلاس» را با «ارث‌بری» تعریف کرد؛ ارث‌بری به کلاس مشتق (Car) اجازه می‌دهد رفتار و داده‌ی کلاس والدش (Vehicle) را به ارث ببرد. اگر کلاس والدی مشخص نشود، کلاس از کلاس object ارث می‌برد.

کلاس‌های والد به سه روش می‌توانند قابلیت‌هایی در اختیار کلاس‌های مشتق بگذارند:

  • تعریف یک متد معمولی.
  • تعریف یک متد virtual که مانند یک متد معمولی است، با این تفاوت که کلاس‌های مشتق می‌توانند آن را تغییر دهند.
  • تعریف یک متد abstract که متدی بدون پیاده‌سازی است و کلاس‌های مشتق باید آن را پیاده‌سازی کنند. کلاسی که متدهای abstract دارد باید خودش هم با abstract علامت‌گذاری شود. از کلاس‌های انتزاعی نمی‌توان نمونه ساخت.

اصلاح‌کننده‌ی دسترسی protected اجازه می‌دهد به عضوی از کلاس والد در یک کلاس مشتق دسترسی داشته باشیم، اما دسترسی از کلاس‌های دیگر را مسدود می‌کند.

کلاس‌های مشتق می‌توانند از طریق کلیدواژه‌ی base به اعضای کلاس والد دسترسی داشته باشند.

// Inherits from the 'object' class
abstract class Vehicle
{
    // Can be overridden
    public virtual void Drive()
    {
    }

    // Must be overridden
    protected abstract int Speed();
}

class Car : Vehicle
{
    public override void Drive()
    {
        // Override virtual method

        // Call parent implementation
        base.Drive();
    }

    protected override int Speed()
    {
        // Implement abstract method
    }
}

سازنده‌ی یک کلاس مشتق به‌طور خودکار، پیش از اجرای منطق سازنده‌ی خودش، سازنده‌ی کلاس والد را فراخوانی می‌کند. می‌توان با کلیدواژه‌ی base آرگومان‌هایی به سازنده‌ی کلاس والد فرستاد:

abstract class Vehicle
{
    protected Vehicle(int wheels)
    {
        Console.WriteLine("Called first");
    }
}

class Car : Vehicle
{
    public Car() : base(4)
    {
        Console.WriteLine("Called second");
    }
}

وقتی بیش از یک کلاس از یک کلاس والد مشتق شود، آن دو (یا چند) کلاس اغلب نسخه‌های متفاوتی از یک متد کلاس والد را پیاده‌سازی می‌کنند. این یک اصل بسیار مهم است که به آن «چندریختی» می‌گویند. برای نمونه، در گونه‌ای متفاوت از مثال بالا نشان می‌دهیم که کد استفاده‌کننده از Vehicle چگونه بسته به این‌که چه نوع وسیله‌ی نقلیه‌ای نمونه‌سازی شده است، رفتار خود را تغییر می‌دهد.

abstract class Vehicle
{
   public abstract string GetDescription();
}

class Car : Vehicle
{
   public Car()
   {
   }

   public override string GetDescription()
   {
      return "Runabout";
   }
}

class Rig : Vehicle
{
   public Rig()
   {
   }

   public override string GetDescription()
   {
      return "Big Rig";
   }
}

Vehicle v1 = new Car();
Vehicle v2 = new Rig();

v1.GetDescription();
// => Runabout
v2.GetDescription();
// => Big Rig

دستورالعمل‌ها

در این تمرین شما یک بازی نقش‌آفرینی به اسم «Wizard and Warriors» بازی می‌کنید که به شما اجازه می‌دهد در نقش یک جادوگر یا یک جنگجو بازی کنید.

برای جنگجوها و جادوگرها قواعد متفاوتی وجود دارد که تعیین می‌کند چه مقدار امتیاز آسیب وارد می‌کنند.

برای یک جنگجو، قواعد به این صورت است:

  • اگر شخصیتی که به آن حمله می‌کند آسیب‌پذیر نباشد، ۶ امتیاز آسیب وارد می‌کند
  • اگر شخصیتی که به آن حمله می‌کند آسیب‌پذیر باشد، ۱۰ امتیاز آسیب وارد می‌کند

برای یک جادوگر، قواعد به این صورت است:

  • اگر جادوگر از قبل طلسمی آماده کرده باشد، ۱۲ امتیاز آسیب وارد می‌کند
  • اگر جادوگر از قبل طلسمی آماده نکرده باشد، ۳ امتیاز آسیب وارد می‌کند

به طور کلی، شخصیت‌ها هرگز آسیب‌پذیر نیستند. اما جادوگرها اگر طلسمی آماده نکرده باشند، آسیب‌پذیر هستند.

شما شش وظیفه دارید که با شخصیت‌های جنگجو و جادوگر کار می‌کنند.

1. توصیف یک شخصیت

متد ToString() را در کلاس Character بازنویسی کنید تا توصیفی از شخصیت را برگرداند، با این قالب: "Character is a <CHARACTER_TYPE>".

var warrior = new Warrior();
warrior.ToString();
// => "Character is a Warrior"

2. شخصیت‌ها را به طور پیش‌فرض آسیب‌پذیر نکنید

مطمئن شوید که متد Character.Vulnerable() همیشه false برمی‌گرداند.

var warrior = new Warrior();
warrior.Vulnerable();
// => false

3. به جادوگرها اجازه دهید طلسمی آماده کنند

متد Wizard.PrepareSpell() را پیاده‌سازی کنید تا به جادوگر اجازه دهید از قبل طلسمی آماده کند.

var wizard = new Wizard();
wizard.PrepareSpell();

4. جادوگرها را وقتی طلسمی آماده نکرده‌اند آسیب‌پذیر کنید

مطمئن شوید که متد Vulnerable() اگر جادوگر طلسمی آماده نکرده باشد true برمی‌گرداند؛ در غیر این صورت false برگرداند.

var wizard = new Wizard();
wizard.Vulnerable();
// => true

5. محاسبه‌ی امتیاز آسیب برای یک جادوگر

متد Wizard.DamagePoints() را پیاده‌سازی کنید تا امتیاز آسیب واردشده را برگرداند: ۱۲ امتیاز آسیب وقتی طلسمی آماده شده باشد و ۳ امتیاز آسیب وقتی آماده نشده باشد.

var wizard = new Wizard();
var warrior = new Warrior();

wizard.PrepareSpell();
wizard.DamagePoints(warrior);
// => 12

6. محاسبه‌ی امتیاز آسیب برای یک جنگجو

متد Warrior.DamagePoints() را پیاده‌سازی کنید تا امتیاز آسیب واردشده را برگرداند: ۱۰ امتیاز آسیب وقتی هدف آسیب‌پذیر است و ۶ امتیاز آسیب وقتی نیست.

var warrior = new Warrior();
var wizard = new Wizard();

warrior.DamagePoints(wizard);
// => 10
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
C# Exercism

آماده‌اید جادوگران و جنگجویان را شروع کنید؟

در Exercism ثبت‌نام کنید تا C# را همراه با 62 مفهوم178 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.