case (که در زبانهای دیگر اغلب با نام switch شناخته میشود) گونهای از عبارت کنترلی است، مانند if-else.
case امکان زنجیرهکردن چندین دستور if-else-if را میدهد، میتواند خوانایی بیشتری داشته باشد و ساختارهای قدرتمندی را ممکن میسازد.
یک case با کلیدواژهی case تعریف میشود که پس از آن یک عبارت اختیاری میآید.
سپس برای هر مورد، کلیدواژهی when به کار میرود که پس از آن عبارتی میآید که با عبارت case مقایسه میشود.
کلیدواژهی when نباید نسبت به کلیدواژهی case تورفتگی داشته باشد.
پس از کلیدواژهی when، کدی میآید که اگر عبارت case با عبارت when مطابقت داشته باشد باید اجرا شود.
case امکان یک دستور else اختیاری را میدهد که اگر هیچ مورد دیگری مطابقت نکند اجرا میشود.
عبارت case ارزیابی میشود و سپس با هر عبارت when مقایسه میشود.
مقایسهی عبارت با استفاده از عملگر شمول case (===) انجام میشود.
case 1
when 1
puts "One"
when 2
puts "Two"
else
puts "Other"
end
# => One
# This is the same as:
tmp = 1
if 1 === tmp
puts "One"
elsif 2 === tmp
puts "Two"
else
puts "Other"
end
case (===)عملگر شمول case (===) کمی با عملگر برابری (==) تفاوت دارد.
این عملگر بررسی میکند که آیا سمت راست عضوی از مجموعهای است که سمت چپ توصیف میکند یا نه.
این یعنی جای قرار گرفتن هر عملوند اهمیت دارد.
نحوهی کارکرد آن به نوع سمت چپ بستگی دارد؛ برای نمونه، یک Range بررسی میکند که آیا سمت راست در آن بازه قرار دارد، یا یک Object بررسی میکند که آیا سمت راست نمونهای از Object است.
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
case با چند عبارتcase امکان مطابقت با چندین عبارت را در یک case واحد میدهد، بهطوری که هر مقدار ممکن با یک کاما از دیگری جدا میشود.
اگر هر یک از عبارتها مطابقت داشته باشد، کد اجرا میشود.
این میتواند برای یک case واحد با چند مقدار ممکن مفید باشد.
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
case با بازههاcase همچنین میتواند بررسی کند که آیا یک مقدار در یک بازه قرار دارد یا نه.
این کار با قرار دادن یک بازه بهعنوان عبارت when انجام میشود.
case var
when 1..3
puts "One to three"
else
puts "Other"
end
case بدون عبارت case
وقتی نیازی به عبارت case نباشد، میتوان آن را حذف کرد.
با این کار، هر عبارت when از نظر درست بودن ارزیابی میشود.
و باعث میشود مانند دستورهای if-else-if رفتار کنند.
case
when 1 == 1
puts "One is equal to one"
when 1 > 2
puts "One is greater than two"
else
puts "Other"
end
when تکخطیCrystal امکان دستورهای case تکخطی را فراهم میکند.
این زمانی به کار میآید که یک دستور ساده و تکخطی دارید.
دستور تکخطی when بهصورت when <expression> then <statement>. نوشته میشود.
و وقتی در دستور else به کار میرود، بهصورت else <statement> نوشته میشود.
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
case با نوعهاcase امکان مطابقت با نوعها را فراهم میکند.
مقایسه از عملگر is_a? برای بررسی نوع متغیر استفاده میکند.
برای نمونه، این امکان میدهد که در یک نوع union برای هر نوع یک شاخه داشته باشیم.
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
case امکان استفاده از یک شیء ضمنی را فراهم میکند.
برای نمونه، این میتواند باعث شود یک عبارت when یک فراخوانی متد روی عبارت case باشد.
بسته به اینکه متد مقداری «درست» یا «غلط» برگرداند، case مطابقت داده میشود یا نه.
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
در این تمرین، اولین نوبت یک بازی بلکجک را شبیهسازی میکنیم.
شما دو کارت دریافت میکنید و میتوانید کارت روشدهی پخشکننده را ببینید.
همهی کارتها با یک رشته نمایش داده میشوند؛ مثل ace، king، three، two و غیره.
ارزش هر کارت به این صورت است:
| کارت | ارزش | کارت | ارزش |
|---|---|---|---|
| ace | ۱۱ | eight | ۸ |
| two | ۲ | nine | ۹ |
| three | ۳ | ten | ۱۰ |
| four | ۴ | jack | ۱۰ |
| five | ۵ | queen | ۱۰ |
| six | ۶ | king | ۱۰ |
| seven | ۷ | other | ۰ |
معمولاً کارتهای ace میتوانند ارزش ۱ یا ۱۱ داشته باشند، اما برای سادگی فرض میکنیم که فقط میتوانند ارزش ۱۱ داشته باشند.
متد Blackjack.parse_card را پیادهسازی کنید که یک کارت را به شکل رشته به عنوان ورودی میگیرد.
این متد باید ارزش کارت را بهصورت یک عدد صحیح برگرداند.
Blackjack.parse_card("ace")
# => 11
امتیاز بازیکن باید در بازههایی از مقادیر دستهبندی شود. امتیاز بازیکن از جمع ارزش دو کارت بازیکن به دست میآید. بازههایی که استفاده میشوند عبارتاند از:
| بازه | ارزش |
|---|---|
| low | [۴، ۱۱] |
| mid | [۱۲، ۱۶] |
| high | [۱۷، ۲۰] |
| blackjack | [۲۱] |
متد Blackjack.card_range را پیادهسازی کنید که دو کارت را به شکل رشته به عنوان ورودی میگیرد.
این متد باید اسم بازهای را برگرداند که این دو کارت در آن قرار میگیرند.
Blackjack.card_range("ten", "king")
# => "high"
بسته به دو کارت شما و کارت پخشکننده، برای نوبت اول بازی یک استراتژی وجود دارد که در آن گزینههای زیر را دارید:
هرچند هنوز بهینه نیست، اما از استراتژیای پیروی میکنید که دوستتان الکس در حال توسعهی آن بوده است. این استراتژی به این صورت است:
ace داشته باشید، باید همیشه آنها را تقسیم کنید.ace، کارت تصویری یا ten نداشته باشد، بهطور خودکار برنده میشوید.
اما اگر پخشکننده هر یک از این کارتها را داشته باشد، باید بایستید و منتظر رو شدن کارت دیگر بمانید.متد Blackjack.first_turn را پیادهسازی کنید که سه کارت را به شکل رشته به عنوان ورودی میگیرد.
این متد باید تصمیمی را که باید بگیرید بهصورت یک رشته برگرداند.
Blackjack.first_turn("ace", "ace", "two")
# => "P"