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 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?, який перевіряє тип змінної.
Наприклад, це дає змогу мати окрему гілку для кожного типу в обʼєднаному типі.
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
case дає змогу використовувати неявний обʼєкт.
Завдяки цьому вираз when може бути, наприклад, викликом методу на виразі case.
Залежно від того, чи повертає метод істинне значення, гілка збігається або ні.
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
У цій вправі ми змоделюємо перший хід гри в блекджек.
Ми отримаємо дві карти й побачимо відкриту карту дилера. Усі карти подано як рядок тексту (англ. string), наприклад "ace", "king", "three", "two" тощо. Значення кожної карти такі:
| card | value | card | value |
|---|---|---|---|
| ace | 11 | eight | 8 |
| two | 2 | nine | 9 |
| three | 3 | ten | 10 |
| four | 4 | jack | 10 |
| five | 5 | queen | 10 |
| six | 6 | king | 10 |
| seven | 7 | інші | 0 |
Зазвичай тузи можуть мати значення 1 або 11, але для простоти припустімо, що вони можуть мати лише значення 11.
Реалізуйте метод Blackjack.parse_card, який приймає карту як рядок тексту в аргументі.
Метод має повернути значення карти як ціле число.
Blackjack.parse_card("ace")
# => 11
Рахунок гравця треба розподілити за діапазонами значень. Рахунок гравця обчислюється додаванням значень двох карт гравця. Використовуються такі діапазони:
| range | value |
|---|---|
| low | [4, 11] |
| mid | [12, 16] |
| high | [17, 20] |
| blackjack | [21] |
Реалізуйте метод Blackjack.card_range, який приймає дві карти як рядки тексту в аргументах.
Метод має повернути назву діапазону значень, до якого належать ці дві карти.
Blackjack.card_range("ten", "king")
# => "high"
Залежно від наших двох карт і карти дилера для першого ходу в грі є стратегія, яка передбачає такі варіанти:
Хоча вона ще не оптимальна, ми будемо дотримуватися стратегії, яку розробляє наш друг Алекс. Ось вона:
Реалізуйте метод Blackjack.first_turn, який приймає три карти як рядки тексту в аргументах.
Метод має повернути рішення, яке треба ухвалити, як рядок тексту.
Blackjack.first_turn("ace", "ace", "two")
# => "P"
Зареєструйтеся на Exercism, щоб вивчати й опановувати Crystal, а також 26 концепцій142 вправи та справжнє наставництво від людей, і все це безкоштовно.