3-Karten-Blackjack
Es wäre natürlich praktisch, wenn das Programm die Werte der gezogenen Karten
automatisch addieren würde.
Dazu müssten wir uns die gezogenen Karten merken und ihre Werte summieren.
Allerdings müssten wir uns dann hier damit beschäftigen was bei einem leeren
Stapel passiert.
Kotlin ist "null-sicher", das bedeutet, dass das Programm dich zwingt,
dich mit dem Fall zu beschäftigen, dass keine Karte mehr im Stapel ist.
Selbst wenn unser Programm immer nur drei Karten zieht,
müssten wir also den Fall behandeln, dass der Stapel leer ist.
null und die Behandlung von null-Werten
werden in späteren Kapiteln behandelt.
Blackjack mit fester Zahl an Karten
Mit dem Wissen aus den vorherigen Kapiteln kannst du nun ein vereinfachtes Blackjack-Spiel programmieren, bei dem der Spieler genau drei Karten zieht.
Aufgabe
- ... einen Stapel mit einem oder mehreren Blättern erzeugt
- ... drei Karten aus dem Stapel zieht und anzeigt
Wenn zwei Spieler gegeneinander spielen möchten, können sie einfach das Programm zweimal nacheinander ausführen.
Alternativ zur Bearbeitung in BlueJ kannst du das Programm auch hier online testen:
class Stapel {
private val karten: MutableList<Karte> = mutableListOf()
fun zaehleKarten(): Int = karten.size
fun erzeugeBlaetter(anzahlBlaetter: Int) {
val raenge = listOf(
"2", "3", "4", "5", "6", "7", "8", "9", "10",
"B", "D", "K", "A"
)
val farben = listOf("Herz", "Karo", "Pik", "Kreuz")
repeat(anzahlBlaetter) {
for (farbe in farben) {
for (rang in raenge) {
karten.add(Karte(farbe, rang))
}
}
}
}
fun mischen() = karten.shuffle()
private fun zieheKarte(): Karte? {
if (karten.isEmpty())
return null
else
return karten.removeAt(0)
}
fun zieheUndZeige() {
if (karten.isEmpty()) {
println("Es ist keine Karte mehr übrig")
}
else {
zeigeObersteKarte()
zieheKarte()
}
}
fun zeigeObersteKarte() {
if (karten.isEmpty())
println("Stapel ist leer")
else
karten.first().druckeKarte()
}
fun druckeAlle() {
for (karte in karten) {
karte.druckeKarte()
}
}
}
class Karte(
farbe: String, // "Herz", "Karo", "Pik", "Kreuz" (ausgeschrieben, Groß/Kleinschreibung egal)
rang: String // "2"–"10", "B"/"Bube", "D"/"Dame", "K"/"Koenig", "A"/"Ass"
) {
val rang: String = kuerzeRang(rang)
val farbe: String = normalisiereFarbe(farbe)
fun berechneWert(): Int {
return when (rang) {
"A" -> 11
"B", "D", "K" -> 10
else -> rang.toInt()
}
}
fun druckeKarte() {
val symbol = when (farbe) {
"herz" -> "♥"
"karo" -> "♦"
"pik" -> "♠"
"kreuz" -> "♣"
else -> "?"
}
val right = rang.padStart(2, ' ')
val left = rang.padEnd(2, ' ')
println("┌─────┐")
println("│$left │")
println("│ $symbol │")
println("│ $right│")
println("└─────┘")
}
private fun kuerzeRang(roherRang: String): String {
val normalisiert = roherRang.trim().lowercase()
return when (normalisiert) {
"a", "ass" -> "A"
"k", "koenig", "könig" -> "K"
"d", "dame" -> "D"
"b", "bube" -> "B"
else -> {
val zahl = normalisiert.toIntOrNull()
?: throw IllegalArgumentException("Unbekannter Rang: $roherRang")
if (zahl in 2..10) zahl.toString()
else throw IllegalArgumentException("Rang ausserhalb des Bereichs: $roherRang")
}
}
}
private fun normalisiereFarbe(roheFarbe: String): String {
return when (val normalisiert = roheFarbe.trim().lowercase()) {
"herz", "karo", "pik", "kreuz" -> normalisiert
else -> throw IllegalArgumentException("Unbekannte Farbe: $roheFarbe")
}
}
}
fun main() {
}