بازی شطرنج

بازی شطرنج

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

مقدمه

بازه فاصله‌ای بین دو مقدار را نشان می‌دهد. رایج‌ترین نوع‌هایی که از بازه پشتیبانی می‌کنند Int، Char و String هستند. از بازه‌ها می‌توان برای کارهای زیادی استفاده کرد؛ مثل ساختن سریع یک مجموعه، برش دادن رشته‌ها، بررسی اینکه یک مقدار درون یک بازه قرار دارد یا نه، و پیمایش. بازه‌ها با عملگر بازه .. یا ... ساخته می‌شوند (به‌ترتیب شامل و غیرشامل).

1..5  # A range containing 1, 2, 3, 4, 5
1...5 # A range containing 1, 2, 3, 4

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

بازه‌ها را می‌توان با سازنده‌ی Range هم ساخت.

Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Note

وقتی در Crystal با عملگرهای بازه‌ی .. یا ... یک بازه می‌سازید و می‌خواهید متدی را روی آن فراخوانی کنید، باید بازه را داخل پرانتز بگذارید. چون در غیر این صورت، متد روی آرگومان دومِ عملگر بازه فراخوانی می‌شود.

(1..5).size # => 5
1..5.size # => Error: undefined method 'size' for Int32

گرفتن زیررشته‌ها

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

"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"

همچنین می‌توانید از ایندکس‌های منفی استفاده کنید تا زیررشته را از انتهای رشته بگیرید.

"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"

متدهای بازه

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

متد توضیح مثال
sum مجموع همه‌ی مقادیر بازه را برمی‌گرداند (1..5).sum # => 15
size اندازه‌ی بازه را برمی‌گرداند (1..5).size # => 5
includes? اگر بازه مقدار داده‌شده را شامل شود true و در غیر این صورت false را برمی‌گرداند (1..5).includes?(3) # => true

بازه‌های بی‌پایان و بی‌آغاز

یک بازه می‌تواند بی‌پایان یا بی‌آغاز باشد. در بازه‌ی بی‌پایان یا بی‌آغاز، مقدار شروع یا پایانش nil است، اما هنگام تعریف بازه می‌توان nil را حذف کرد.

استفاده از بازه‌های بی‌آغاز و بی‌پایان وقتی مفید است که مثلاً بخواهید رشته‌ای را از ابتدا یا تا انتها برش دهید.

"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello"
Caution

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

بازه‌های Char

می‌توان از کاراکترها در بازه‌ها استفاده کرد و این امکان را دارد که فاصله‌ای از کاراکترها بین دو کاراکتر به دست آورید. برای مثال، وقتی بخواهید الفبا را به دست آورید، این کار به کار می‌آید.

'a'..'z' # A range containing ['a', 'b', 'c', ..., 'z']

بازه‌های String

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

("aa".."az") # A range containing ["aa", "ab", "ac", ..., "az"]

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

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

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

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

1. تعریف بازه‌ی رتبه و فایل

بازی باید رتبه‌های صفحه را نگه دارد. رتبه‌ها همان سطرهای صفحه هستند و از ۱ تا ۸ شماره‌گذاری می‌شوند.

بازی همچنین باید فایل‌های صفحه را نگه دارد. فایل‌ها همان ستون‌های صفحه هستند و با حروف A تا H مشخص می‌شوند.

ثابت‌های Chess::RANKS و Chess::FILES را تعریف کنید که به ترتیب بازه‌ی رتبه‌ها و فایل‌ها را نگه می‌دارند.

Chess::RANKS
# => 1..8

Chess::FILES
# => 'A'..'H'

2. بررسی معتبر بودن خانه

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

متد Chess.valid_square? را تعریف کنید که دو آرگومان می‌گیرد: rank که عددی صحیح از رتبه را نگه می‌دارد و file که کاراکتری از فایل را نگه می‌دارد. متد باید اگر رتبه و فایل در محدوده‌ی رتبه‌ها و فایل‌ها باشند true را برگرداند و در غیر این صورت false را.

Chess.valid_square?(1, 'A')
# => true

3. گرفتن اسم مستعار بازیکن

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

متد Chess.nickname را تعریف کنید که دو آرگومان می‌گیرد: first_name که رشته‌ای از اسم کوچک بازیکن را نگه می‌دارد و last_name که رشته‌ای از اسم خانوادگی بازیکن را نگه می‌دارد. متد باید اسم مستعار بازیکن را به صورت یک رشته با حروف بزرگ برگرداند.

Chess.nickname("John", "Doe")
# => "JOOE"

4. ساختن پیام حرکت

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

اگر حرکت معتبر باشد، پیام باید این باشد: "{nickname} moved to {square}" اگر حرکت معتبر نباشد، پیام باید این باشد: "{nickname} attempted to move to {square}, but that is not a valid square"

متد Chess.move_message را تعریف کنید که سه آرگومان می‌گیرد: first_name که رشته‌ای از اسم کوچک بازیکن را نگه می‌دارد، last_name که رشته‌ای از اسم خانوادگی بازیکن را نگه می‌دارد و square که رشته‌ای از خانه‌ای را نگه می‌دارد که بازیکن به آن حرکت کرده است. متد باید پیام حرکت را به صورت یک رشته برگرداند.

Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Crystal Exercism

آماده‌اید بازی شطرنج را شروع کنید؟

در Exercism ثبت‌نام کنید تا Crystal را همراه با 26 مفهوم142 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.