Case(他の言語ではしばしばswitchと呼ばれます)は、if-elseのような制御式の一種です。
caseでは複数のif-elsif文をつなげて書くことができ、制御フローを保ったまま、より読みやすく書けます。
caseは、caseというキーワードと、そのあとに続く省略可能な式で定義します。
次に、それぞれの分岐にはwhenというキーワードを使い、そのあとにcaseの式と比較される式を書きます。
whenキーワードは、caseキーワードよりインデントしてはいけません。
whenキーワードのあとには、caseの式がwhenの式に一致したときに実行されるコードを書きます。
caseには省略可能なelse文があり、どの分岐にも一致しなかったときに実行されます。
caseの式が評価され、次にそれぞれのwhenの式と比較されます。
比較には、case等価演算子(===)を使います。
value = 1
case value
when 1
"One"
when 2
"Two"
else
"Other"
end
# This is the same as:
value = 1
if 1 === value
"One"
elsif 2 === value
"Two"
else
"Other"
end
case等価演算子(===)case等価演算子(===)は、等値演算子(==)とは少し違います。
この演算子は、右辺が左辺の表す集合に含まれるかどうかを調べます。
つまり、それぞれのオペランドをどちら側に置くかが重要になります。
どのように判定されるかは左辺の型によって変わり、たとえばRangeなら右辺がその範囲に含まれるかどうかを調べ、Objectなら右辺がObjectのインスタンスかどうかを調べます。
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
caseでは、複数の式を1つの分岐で一致させることができ、それぞれの値をカンマで区切って書きます。 いずれかの式が一致すれば、そのコードが実行されます。 1つの分岐に複数の値を指定したいときに便利です。
case var
when 1, 2
"One or two"
else
"Other"
end
caseでは、値が範囲に含まれるかどうかも調べられます。
これは、whenの式に範囲を指定して行います。
case var
when 1..3
puts "One to three"
else
puts "Other"
end
caseの式を省略するcaseの式が不要なときは、省略できます。
省略すると、各whenの式が真かどうかで評価されます。
そのため、if-elsif文と同じように動作します。
case
when 1 == 1
"One is equal to one"
when 1 > 2
"One is greater than two"
else
"Other"
end
when
Rubyでは、case文を1行で書くことができます。
これは、単純な1行の文を書きたいときに使えます。
1行のwhen文はwhen <expression> then <statement>のように書きます。
また、elseで使う場合はelse <statement>のように書きます。
case var
when 1 then "One"
when 2 then "Two"
else "Other"
end
caseでは、型に基づいて一致させることもできます。 変数の型によって動作を変えたいときに便利です。
case var
when Integer
"Integer"
when String
"String"
else
"Other"
end
この演習では、ブラックジャックの最初のターンをシミュレーションします。
2枚のカードを受け取り、ディーラーの表向きのカードを見ることができます。 カードはすべて、"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
プレイヤーのスコアは、値の範囲に分類する必要があります。 プレイヤーのスコアは、プレイヤーの2枚のカードの値を合計して計算します。 使用する範囲は次のとおりです:
| range | value |
|---|---|
| low | [4, 11] |
| mid | [12, 16] |
| high | [17, 20] |
| blackjack | [21] |
2枚のカードを文字列として受け取るメソッドBlackjack.card_rangeを実装してください。
このメソッドは、2枚のカードが該当する値の範囲の名前を返すようにします。
Blackjack.card_range("ten", "king")
# => "high"
手持ちの2枚のカードとディーラーのカードに応じて、ゲームの最初のターンには戦略があります。選択肢は次のとおりです:
まだ最適ではありませんが、友人のAlexが開発を進めている次の戦略に従います:
3枚のカードを文字列として受け取るメソッドBlackjack.first_turnを実装してください。
このメソッドは、取るべき判断を文字列として返すようにします。
Blackjack.first_turn("ace", "ace", "two")
# => "P"