MINT lernen

Ein Konsolenspiel bauen

Wie oft musst du höchstens raten, wenn der Computer sich eine Zahl von 1 bis 100 ausdenkt?

1

Das Spiel planen

Vor dem ersten Code steht der Ablauf in Worten — wie ein Struktogramm für „Zahlenraten“:

  • Ziehen:Der Computer denkt sich eine Zufallszahl von 1 bis 100.
  • Zählen:Die Anzahl der Versuche beginnt bei 0.
  • Wiederholen:Tipp einlesen, Versuche um 1 erhöhen, Hinweis „zu klein“ oder „zu groß“ ausgeben …
  • Bedingung:… solange der Tipp nicht die gesuchte Zahl ist.
  • Ende:Treffer melden und die Anzahl der Versuche ausgeben.
C++ · wuerfel.cpp
#include <iostream>
#include <cstdlib>                       // rand, srand
#include <ctime>                         // time
using namespace std;

int main() {
    srand(time(0));                      // einmal: Startwert aus der Uhrzeit
    for (int i = 0; i < 5; i++) {
        cout << rand() % 6 + 1 << " ";   // Würfel: 1 … 6
    }
    cout << endl;
    return 0;
}
Konsole (bei jedem Start anders)
$ g++ wuerfel.cpp -o wuerfel
$ ./wuerfel
1 3 3 6 4
  • rand():liefert eine große ganze Zahl ≥ 0 (bis RAND_MAX, mit g++ unter Linux 2 147 483 647).
  • srand(time(0)):setzt den Startwert aus der aktuellen Uhrzeit — genau einmal am Programmanfang.
  • Ohne srand:liefert rand() bei jedem Start dieselbe Folge.
  • Bereich:mit dem Rest % auf den gewünschten Bereich zuschneiden:
Herleitung:
\(\texttt{rand()} \in \{0,\ 1,\ 2,\ \dots,\ \texttt{RAND\_MAX}\}\)
Start

Sehr großer Bereich, beginnt bei 0.

\(\texttt{rand()}\ \%\ n \in \{0,\ 1,\ \dots,\ n-1\}\)
Rest bei : n

Der Rest beim Teilen durch \(n\) ist nie negativ und immer kleiner als \(n\) — also \(n\) mögliche Werte.

\(a + \texttt{rand()}\ \%\ n \in \{a,\ a+1,\ \dots,\ a+n-1\}\)
+ a

Alle Werte um \(a\) nach oben verschieben.

\(a + n - 1 = b \;\Rightarrow\; n = b - a + 1\)
n bestimmen

Die größte Zahl soll genau \(b\) sein.

\(a + \texttt{rand()}\ \%\ (b - a + 1) \in \{a,\ \dots,\ b\}\)
Ergebnis

Für 1 … 100: \(a = 1,\ b = 100\) ergibt 1 + rand() % 100, also rand() % 100 + 1.

Merke

Zufallszahl von a bis b: \(a + \texttt{rand()}\ \%\ (b - a + 1)\) — vorher einmal srand(time(0)); mit <cstdlib> und <ctime>.

2

Die Spielschleife

do … while passt genau: Der erste Tipp kommt immer, geprüft wird erst danach.

Die Zeilen von main sind durcheinandergeraten. Bringe sie in die richtige Reihenfolge — mit der Maus ziehen oder antippen, mit der Tastatur Leertaste zum Aufnehmen, Pfeiltasten zum Verschieben. Stimmt alles, spielst du in der Konsole — oder lässt mit ▶ den Computer per Halbierung raten.

Code-Puzzle: Zahlenraten

C++ · raten.cpp

        

      
Konsole

Halte fest: Die Zufallszahl wird vor der Schleife einmal gezogen, Einlesen und Zählen stehen in der Schleife, der Treffer wird nach der Schleife gemeldet. Wer immer die Mitte des noch möglichen Bereichs tippt, halbiert ihn mit jedem Hinweis.

  • do … while:Rumpf läuft mindestens einmal, Wiederholung solange tipp != zahl.
  • Zählen:versuche++; steht in der Schleife — einmal je Tipp.
  • Hinweise:if / else if: bei einem Treffer wird keiner der beiden Hinweise ausgegeben.
  • Halbierung:Tipp in der Mitte des möglichen Bereichs, jeder Hinweis halbiert ihn ungefähr.
  • Höchstens 7:\(2^6 = 64 \lt 100 \le 128 = 2^7\): nach 6 Hinweisen bleibt höchstens eine Zahl (100 → 50 → 25 → 12 → 6 → 3 → 1), der 7. Tipp trifft.
Merke

Spielschleife: Vorbereiten (Zufallszahl, Zähler) → do { einlesen; zählen; Hinweis; } while (nicht getroffen); → Ergebnis ausgeben. Bei 1 … 100 genügen mit Halbierung höchstens 7 Versuche.

3

Allgemeine Hinweise

srand nur einmal aufrufen

Steht srand(time(0)); in der Schleife, bekommt jede Runde derselben Sekunde denselben Startwert — Ausgabe z. B. 5 5 5 5 5.

Ohne srand kein Zufall

Fehlt srand, zieht das Spiel bei jedem Start dieselbe Zahl — praktisch zum Testen, langweilig zum Spielen.

Ränder prüfen

rand() % 100 liefert 0 bis 99. Rechne die kleinste und größte Möglichkeit nach: erst + 1 macht daraus 1 bis 100.

Videos