مسیرها
/
Go
Go
/
تمرین‌ها
/
صفحه‌ی شطرنج
صفحه‌ی شطرنج

صفحه‌ی شطرنج

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

مقدمه

در Go می‌توانید با استفاده از for و یک اندیس، روی یک slice پیمایش کنید، یا می‌توانید از range استفاده کنید. range همچنین به شما اجازه می‌دهد روی یک map هم پیمایش کنید.

هر تکرار دو مقدار برمی‌گرداند: اندیس/کلید و یک کپی از عنصر موجود در آن اندیس/کلید.

پیمایش روی یک slice

خیلی ساده است: حلقه زدن روی یک slice، به همان ترتیبی که انتظار دارید.

xi := []int{10, 20, 30}
for i, x := range xi {
  fmt.Println(i, x)
}
// outputs:
// 0, 10
// 1, 20
// 2, 30

پیمایش روی یک map

پیمایش روی یک map مسئله‌ی تازه‌ای به وجود می‌آورد. حالا ترتیب تصادفی است.

hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
  fmt.Println(k, v)
}
// outputs, for example:
// 99 20
// 999 30
// 9 10
Note

ممکن است به نظر برسد که خروجی بالا نادرست است، چون انتظار می‌رود اولین جفت کلید/مقدار در اعلان map، یعنی 9 10، اولین مورد چاپ‌شده باشد و نه آخری. با این حال، mapها ذاتاً بی‌ترتیب هستند؛ جفت کلید/مقدار اول و آخری وجود ندارد. به همین دلیل، وقتی روی ورودی‌های یک map پیمایش می‌کنید، ترتیبی که این ورودی‌ها بازدید می‌شوند تصادفی است و از هیچ الگوی مشخصی پیروی نمی‌کند. یعنی خروجی بالا ممکن است، اما شاید با آنچه خودتان در صورت اجرای این کد می‌بینید متفاوت باشد. برای آشنایی بیشتر با این موضوع، مشخصات زبان Go: بند range را ببینید.

تکرار با حذف کلید یا مقدار

در Go، یک متغیر استفاده‌نشده هنگام ساخت خطا ایجاد می‌کند. گاهی فقط به مقدار نیاز دارید، مثل مثال اول:

xi := []int{10, 20, 30}
for i, x := range xi {
  fmt.Println(x)
}
// Go build failed: i declared but not used

می‌توانید i را با _ جایگزین کنید تا به کامپایلر بگویید که ما از آن مقدار استفاده نمی‌کنیم:

xi := []int{10, 20, 30}
for _, x := range xi {
  fmt.Println(x)
}
// outputs:
// 10
// 20
// 30

اگر می‌خواهید فقط اندیس را چاپ کنید، می‌توانید x را با _ جایگزین کنید، یا به‌سادگی اعلان را حذف کنید:

xi := []int{10, 20, 30}
// for i, _ := range xi {
for i := range xi {
  fmt.Println(i)
}
// outputs:
// 0
// 1
// 2

تعریف انواع

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

type File []bool

File در اینجا به یک ستون عمودی روی صفحه‌ی شطرنج اشاره دارد که معمولاً با حروف A تا H برچسب‌گذاری می‌شود. هر خانه در این ستون با یک مقدار «منطقی» نمایش داده می‌شود که مشخص می‌کند آن خانه اشغال شده است یا نه. حالا که File تعریف شده است، می‌توانیم آن را داخل تعریف‌های دیگر به کار ببریم:

type Chessboard map[string]File

board := Chessboard{
    "A": File{true, false, true},
    "B": File{false, true, false},
}

Chessboard شناسه‌های ستون را به مقادیر File نگاشت می‌کند. هر File یک slice از مقادیر منطقی است که خانه‌های یک ستون شطرنج را نمایش می‌دهد. بدون این تعریف‌های نوع، board یک map[string][]bool می‌بود که فهم اینکه چه چیزی را نمایش می‌دهیم سخت‌تر می‌کرد.

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

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

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

  • ردیف‌های افقی خانه‌ها که «رتبه» نامیده می‌شوند، از ۱ تا ۸ شماره‌گذاری شده‌اند.
  • ستون‌های عمودی خانه‌ها که «فایل» نامیده می‌شوند، با A تا H برچسب‌گذاری شده‌اند.
   A B C D E F G H
 8 # _ _ _ # _ _ # 8
 7 _ _ _ _ _ _ _ _ 7
 6 _ _ _ _ # _ _ # 6
 5 _ # _ _ _ _ _ # 5
 4 _ _ _ _ _ _ # # 4
 3 # _ # _ _ _ _ # 3
 2 _ _ _ _ _ _ _ # 2
 1 # _ _ _ _ _ _ # 1
   A B C D E F G H

1. با یک صفحه‌ی شطرنج و یک فایل، بشمارید چند خانه اشغال شده است

تابع CountInFile(board Chessboard, file string) int را پیاده‌سازی کنید. باید با پیمایش روی یک نگاشت، تعداد کل خانه‌های اشغال‌شده را بشمارد. یک عدد صحیح برگردانید. اگر فایل داده‌شده در نگاشت پیدا نشد، شمارش صفر (0) را برگردانید.

CountInFile(board, "A")
// => 3

2. با یک صفحه‌ی شطرنج و یک رتبه، بشمارید چند خانه اشغال شده است

تابع CountInRank(board Chessboard, rank int) int را پیاده‌سازی کنید. باید با پیمایش روی رتبه‌ی داده‌شده، تعداد کل خانه‌های اشغال‌شده را بشمارد. یک عدد صحیح برگردانید. اگر رتبه‌ی داده‌شده معتبر نباشد (یعنی بین 1 و 8 با احتساب خودشان نباشد)، شمارش صفر (0) را برگردانید.

CountInRank(board, 2)
// => 1

3. بشمارید چند خانه در صفحه‌ی شطرنج داده‌شده وجود دارد

تابع CountAll(board Chessboard) int را پیاده‌سازی کنید. باید بشمارد چند خانه در صفحه‌ی شطرنج وجود دارد و یک عدد صحیح برگرداند. از آنجا که نیازی نیست محتوای خانه‌ها را بررسی کنید، استفاده از range را با حذف هم index و هم value در نظر بگیرید.

CountAll(board)
// => 64

4. بشمارید چند خانه در صفحه‌ی شطرنج داده‌شده اشغال شده است

تابع CountOccupied(board Chessboard) int را پیاده‌سازی کنید. باید بشمارد چند خانه در صفحه‌ی شطرنج اشغال شده است. یک عدد صحیح برگردانید.

CountOccupied(board)
// => 15
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Go Exercism

آماده‌اید صفحه‌ی شطرنج را شروع کنید؟

در Exercism ثبت‌نام کنید تا Go را همراه با 34 مفهوم166 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.