Tracks
/
Clojure
Clojure
/
Übungen
/
Kartenspiele
Kartenspiele

Kartenspiele

Lernübung

Einführung

In Clojure sind Listen Collections, genau wie Listen in anderen Sprachen. Ähnlich wie andere Sprachen aus der Lisp-Familie verwendet Clojure runde Klammern, um Listen auszudrücken.

Clojure-Listen kannst du auf zwei Arten erstellen. Die Funktion list kann eine Liste erzeugen, oder du kannst ein Listen-Literal mit quote quoten.

Listen sind etwas Besonderes, weil Clojure sie als Aufrufe behandelt. Clojure erwartet, dass der Aufruf mit einem Operator beginnt, der normalerweise eine Funktion ist. Die übrigen Elemente der Liste gelten als Operanden, das heißt, sie werden zu den Argumenten der Funktion.

Clojures besondere Behandlung von Listen ist der Grund, warum wir ein Listen-Literal nicht direkt erstellen können. Wenn du eine Liste mit quote oder der Kurzform ' quotest, zeigt das an, dass die Liste nicht ausgewertet werden soll.

Anders als einige moderne Sprachen sind Clojure-Listen heterogen, das heißt, sie können intern verschiedene Arten von Elementen enthalten, z. B. '(2 "a" "b" 3). Anders als andere Lisps gilt eine leere Liste in Clojure als wahr und ist nicht gleichbedeutend mit nil oder false.

Anleitung

Elyse freut sich schon sehr darauf, auf ihrer bevorstehenden Reise nach Vegas Poker (und andere Kartenspiele) zu spielen. Als großer Fan von „Self-Tracking“ möchte sie ein paar kleine Funktionen zusammenstellen, die ihr bei Tracking-Aufgaben helfen, und hat dich gebeten, ihr dabei zu helfen, sie durchzudenken.

1. Pokerrunden verfolgen

Elyse mag Poker besonders gern und möchte verfolgen, wie viele Runden sie spielt, und welche Runden das sind. Jede Runde hat ihre eigene Nummer, und jeder Tisch zeigt die Runde, die gerade gespielt wird. Elyse wählt einen Tisch und setzt sich hin, um ihre erste Runde zu spielen. Sie hat vor, drei Runden zu spielen.

Implementiere eine Funktion rounds, die die aktuelle Rundennummer entgegennimmt und eine einzelne list mit dieser Runde und den nächsten beiden zurückgibt, die als Nächstes kommen:

(rounds 27)
;;=> (27 28 29)

2. Alle Runden an einem Ort behalten

Elyse hat ein paar Runden am ersten Tisch gespielt, dann eine Pause gemacht und noch ein paar Runden an einem zweiten Tisch gespielt ... aber am Ende hatte sie für jeden Tisch eine andere Liste! Sie möchte die beiden Listen zusammenführen, damit sie alle Pokerrunden an einem Ort verfolgen kann.

Implementiere eine Funktion concat-rounds, die zwei Listen entgegennimmt und eine einzelne list zurückgibt, die aus allen Runden in der ersten list besteht, gefolgt von allen Runden in der zweiten list:

(concat-rounds '(27 28 29) '(35 36))
;;=> (27 28 29 35 36)

3. Frühere Runden finden

Als sie über einige der früheren Pokerrunden sprechen, bemerkt ein anderer Spieler, wie ähnlich zwei davon verlaufen sind. Elyse ist sich nicht sicher, ob sie diese Runden gespielt hat oder nicht.

Implementiere eine Funktion contains-round?, die zwei Argumente entgegennimmt: eine Liste gespielter Runden und eine Rundennummer. Die Funktion gibt true zurück, wenn die Runde in der Liste der gespielten Runden ist, und false, wenn nicht:

(contains-round? '(27 28 29 35 36) 29)
;;=> true

(contains-round? '(27 28 29 35 36) 30)
;;=> false

4. Kartenwerte mitteln

Elyse möchte ein neues Spiel namens Black Joe ausprobieren. Es ähnelt Black Jack, wo dein Ziel ist, dass die Karten auf deiner Hand eine Zielsumme ergeben, aber bei Black Joe ist das Ziel, dass der Durchschnitt der Kartenwerte 7 beträgt. Den Durchschnitt findest du, indem du alle Kartenwerte addierst und diese Summe dann durch die Anzahl der Karten auf der Hand teilst.

Implementiere eine Funktion card-average, die den Durchschnittswert einer Hand bei Black Joe zurückgibt.

(card-average '(5 6 7))
;;=> 6.0

5. Alternative Mittelwerte

Bei Black Joe ist Schnelligkeit wichtig. Elyse will versuchen, einen schnelleren Weg zu finden, den Durchschnitt zu berechnen.

Sie hat sich zwei Wege ausgedacht, um eine durchschnittsähnliche Zahl zu erhalten:

  • Nimm den Durchschnitt der ersten und letzten Zahl auf der Hand.
  • Verwende den Median (die mittlere Karte) der Hand.

Implementiere die Funktion approx-average?, die hand entgegennimmt, eine Liste mit den Werten der Karten auf deiner Hand.

Gib true zurück, wenn eine or beide der oben genannten Strategien eine Zahl ergeben, die gleich dem tatsächlichen Durchschnitt ist.

Hinweis: Die Länge aller Hände ist ungerade, damit sich der Median leichter finden lässt.

(approx-average? '(1 2 3))
;;=> true

(approx-average? '(2 3 4 8 8))
;;=> true

(approx-average? '(1 2 3 5 9))
;;=> false

6. Weitere Mittelwerttechniken

Fasziniert von den Ergebnissen ihres Mittelwert-Experiments fragt sich Elyse, ob der Durchschnitt der Karten an den geraden Positionen und der Durchschnitt der Karten an den ungeraden Positionen dasselbe Ergebnis liefern würden. Zeit für eine weitere Testfunktion!

Implementiere eine Funktion average-even-odd?, die einen booleschen Wert zurückgibt, der angibt, ob der Durchschnitt der Karten an geraden Indizes derselbe ist wie der Durchschnitt der Karten an ungeraden Indizes.

(average-even-odd? '(1 2 3))
;;=> true

(average-even-odd? '(1 2 3 4))
;;=> false

7. Regeln für Bonusrunden

Jede 11. Hand bei Black Joe ist eine Bonushand mit einer Bonusregel: Wenn die letzte Karte, die du ziehst, ein Bube ist, verdoppelst du ihren Wert.

Implementiere eine Funktion maybe-double-last, die eine Hand entgegennimmt und prüft, ob die letzte Karte ein Bube (11) ist. Wenn die letzte Karte ein Bube (11) ist, verdopple ihren Wert, bevor du die Hand zurückgibst.

(maybe-double-last '(5 9 11))
;;=> '(5 9 22)

(maybe-double-last '(5 9 10))
;;=> '(5 9 10)
Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab
Clojure Exercism

Bereit, mit Kartenspiele zu starten?

Melde dich bei Exercism an, um Clojure mit 12 Konzepte105 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.