case (in anderen Sprachen oft „switch“ genannt) ist eine Art Kontrollausdruck, ähnlich wie if-else.
Mit case lassen sich mehrere if-else-if-Anweisungen verketten, das kann lesbarer sein und ermöglicht mächtige Konstrukte.
Ein case wird durch das Schlüsselwort case eingeleitet, auf das ein optionaler Ausdruck folgt.
Dann wird für jeden Fall das Schlüsselwort when verwendet, gefolgt von einem Ausdruck, der mit dem case-Ausdruck verglichen wird.
Das Schlüsselwort when sollte nicht gegenüber dem Schlüsselwort case eingerückt werden.
Nach dem Schlüsselwort when folgt der Code, der ausgeführt werden soll, wenn der case-Ausdruck zum when-Ausdruck passt.
Case erlaubt eine optionale else-Anweisung, die ausgeführt wird, wenn kein anderer Fall passt.
Der case-Ausdruck wird ausgewertet und dann mit jedem when-Ausdruck verglichen.
Der Vergleich erfolgt mit dem Case-Subsumptionsoperator (===).
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
===)Der Case-Subsumptionsoperator (===) unterscheidet sich ein wenig vom Gleichheitsoperator (==).
Der Operator prüft, ob die rechte Seite ein Element der Menge ist, die die linke Seite beschreibt.
Das bedeutet, dass es sehr wohl darauf ankommt, an welcher Stelle die einzelnen Operanden stehen.
Wie das genau funktioniert, hängt vom Typ der linken Seite ab: Eine Range prüft zum Beispiel, ob die rechte Seite im Bereich liegt, und ein Object prüft, ob die rechte Seite eine Instanz des Object ist.
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
In einem Case lassen sich mehrere Ausdrücke gleichzeitig abgleichen, wobei die einzelnen möglichen Werte durch ein Komma getrennt werden. Der Code wird ausgeführt, wenn einer der Ausdrücke passt. Das ist nützlich, wenn ein einzelner Fall mehrere mögliche Werte haben kann.
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
Ein Case kann auch prüfen, ob ein Wert in einem Bereich liegt. Dazu verwendest du einen Bereich als when-Ausdruck.
case var
when 1..3
puts "One to three"
else
puts "Other"
end
Wenn du keinen case-Ausdruck brauchst, kannst du ihn weglassen. Dadurch wird jeder when-Ausdruck auf seinen Wahrheitswert geprüft. So verhalten sie sich wie if-else-if-Anweisungen.
case
when 1 == 1
puts "One is equal to one"
when 1 > 2
puts "One is greater than two"
else
puts "Other"
end
Crystal erlaubt einzeilige Case-Anweisungen.
Das bietet sich an, wenn du eine einfache einzeilige Anweisung hast.
Die einzeilige when-Anweisung wird als when <expression> then <statement>. geschrieben.
Und in der else-Anweisung wird sie als else <statement> geschrieben.
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
Case erlaubt auch den Abgleich mit Typen.
Der Vergleich verwendet den Operator is_a?, um den Typ der Variable zu prüfen.
So kannst du zum Beispiel für jeden Typ eines Union-Typs einen eigenen Zweig angeben.
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
Case erlaubt die Verwendung eines impliziten Objekts. Damit kann ein when-Ausdruck zum Beispiel ein Methodenaufruf auf dem case-Ausdruck sein. Je nachdem, ob die Methode einen truthy- oder falsey-Wert zurückgibt, passt das Case oder nicht.
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
In dieser Übung simulieren wir den ersten Zug eines Blackjack-Spiels.
Du bekommst zwei Karten und siehst die offene Karte des Dealers. Alle Karten werden durch einen String wie „ace“, „king“, „three“, „two“ usw. dargestellt. Die Werte der einzelnen Karten sind:
| Karte | Wert | Karte | Wert |
|---|---|---|---|
| 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 | other | 0 |
Üblicherweise können Asse den Wert 1 oder 11 annehmen, aber der Einfachheit halber gehen wir davon aus, dass sie nur den Wert 11 annehmen können.
Implementiere die Methode Blackjack.parse_card, die eine Karte als String-Argument entgegennimmt.
Die Methode sollte den Wert der Karte als Ganzzahl zurückgeben.
Blackjack.parse_card("ace")
# => 11
Der Punktestand eines Spielers muss in Wertebereiche eingeteilt werden. Der Punktestand eines Spielers wird berechnet, indem man die Werte seiner beiden Karten addiert. Die verwendeten Bereiche sind:
| Bereich | Wert |
|---|---|
| low | [4, 11] |
| mid | [12, 16] |
| high | [17, 20] |
| blackjack | [21] |
Implementiere die Methode Blackjack.card_range, die zwei Karten als String-Argumente entgegennimmt.
Die Methode sollte den Namen des Wertebereichs zurückgeben, in den die beiden Karten fallen.
Blackjack.card_range("ten", "king")
# => "high"
Je nach deinen beiden Karten und der Karte des Dealers gibt es eine Strategie für den ersten Zug des Spiels, bei dem du die folgenden Optionen hast:
Zwar ist die Strategie noch nicht optimal, aber du folgst der Strategie, die dein Freund Alex entwickelt hat. Sie sieht so aus:
Implementiere die Methode Blackjack.first_turn, die drei Karten als String-Argumente entgegennimmt.
Die Methode sollte die Entscheidung, die du treffen solltest, als String zurückgeben.
Blackjack.first_turn("ace", "ace", "two")
# => "P"
Melde dich bei Exercism an, um Crystal mit 26 Konzepte142 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.