Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Willkommen bei der Rustanleitung!

Hallo und herzlich willkommen! 👋

Diese Anleitung hilft dir dabei, das Programmieren zu lernen – und zwar mit der Programmiersprache Rust und einer besonderen Hilfe: der Schildkröten-Grafik (englisch: Turtle Graphics).

Für wen ist diese Anleitung?

Diese Anleitung ist für alle, die:

  • Noch nie programmiert haben
  • Neugierig sind, wie Programmieren funktioniert
  • Gerne etwas Neues lernen möchten
  • Spaß daran haben, mit dem Computer kreativ zu sein

Du brauchst keine Vorkenntnisse – wir fangen ganz von vorne an!

Was wirst du lernen?

In dieser Anleitung wirst du lernen:

  • Was Programmieren überhaupt ist
  • Wie man einfache Programme schreibt
  • Wie man mit der Schildkröte bunte Bilder zeichnet
  • Grundlegende Konzepte der Programmierung wie Wiederholungen, Variablen und Funktionen

Die Schildkröten-Grafik

Die Schildkröten-Grafik ist eine besondere Art, das Programmieren zu lernen. Du stellst dir vor, dass eine kleine Schildkröte über den Bildschirm läuft und dabei mit einem Stift eine Spur hinterlässt. Du kannst der Schildkröte Befehle geben wie:

  • “Gehe 100 Schritte vorwärts”
  • “Drehe dich 90 Grad nach rechts”
  • “Wechsle die Farbe zu Blau”

So entstehen nach und nach Bilder und Muster!

Los geht’s!

Bist du bereit? Dann lass uns anfangen! 🚀

Im nächsten Kapitel richten wir gemeinsam deine Programmierumgebung ein, damit du direkt loslegen kannst.

Einrichtung der Programmierumgebung

Bevor wir mit dem Programmieren beginnen können, müssen wir ein paar Programme auf deinem Computer installieren. Keine Sorge – wir gehen das Schritt für Schritt durch!

Was brauchen wir?

  1. Rust – Die Programmiersprache, die wir verwenden
  2. Zed – Der empfohlene Editor, in dem wir unseren Code schreiben
  3. Rust-Unterstützung in Zed – Sprach- und Code-Hilfe für Rust

Schritt 1: Rust installieren

Rust ist die Programmiersprache, mit der wir arbeiten werden. Zusammen mit Rust wird auch Cargo installiert – ein Werkzeug, das uns bei der Verwaltung unserer Programme hilft.

Installation auf Windows

  1. Gehe zu https://rustup.rs/
  2. Lade die Installationsdatei herunter
  3. Führe die Datei aus und folge den Anweisungen
  4. Wenn du gefragt wirst, wähle die Standardinstallation (Option 1)

Installation auf macOS oder Linux

  1. Öffne das Terminal
  2. Kopiere diesen Befehl und drücke Enter:
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
  3. Folge den Anweisungen auf dem Bildschirm
  4. Wähle die Standardinstallation (Option 1)

Installation überprüfen

Um zu prüfen, ob die Installation geklappt hat:

  1. Öffne ein neues Terminal oder eine neue Eingabeaufforderung
  2. Tippe cargo --version und drücke Enter
  3. Du solltest eine Versionsnummer sehen, z.B. cargo 1.92.0

Schritt 2: Zed installieren

Zed ist der empfohlene Editor für diese Anleitung. Er ist schnell, modern und gut für Rust geeignet.

  1. Gehe zu https://zed.dev/
  2. Lade Zed für dein Betriebssystem herunter
  3. Installiere das Programm
  4. Starte Zed

Rust-Unterstützung in Zed

In den meisten Fällen funktioniert Rust in Zed direkt sehr gut. Wenn du die Sprachanalyse nicht sofort siehst, öffne die Erweiterungen in Zed und installiere die Rust-Unterstützung bzw. rust-analyzer.

So sieht Zed nach dem ersten Start ungefähr aus: Auf dem Startbildschirm findest du schnell die wichtigsten Optionen wie „Neues Projekt“, „Projekt öffnen“ und die zuletzt geöffneten Ordner. Wenn du ein Projekt öffnest, erscheint die typische Arbeitsfläche mit Projektstruktur links und dem Editor rechts:

Schritt 3: Projekt einrichten

Jetzt erstellen wir unser erstes Projekt!

1. Projekt-Ordner erstellen

Wähle einen Ort auf deinem Computer, wo du deine Programmier-Projekte speichern möchtest, z.B. in deinem Dokumente-Ordner.

2. Projekt mit Cargo erstellen

  1. Öffne das Terminal mit dem Knopf unten rechts in Zed.

  2. Gehe zu dem Ordner, wo du dein Projekt erstellen möchtest:

    cd ~/Dokumente
    
  3. Erstelle ein neues Projekt:

    cargo new mein-turtle-projekt
    cd mein-turtle-projekt
    

Cargo hat jetzt automatisch einen Ordner mit allem erstellt, was du brauchst!

3. Projekt in Zed öffnen

  1. In Zed: Datei → Ordner öffnen
  2. Wähle den Ordner mein-turtle-projekt
  3. Zed lädt jetzt das Projekt

Danach sieht die Arbeitsfläche in Zed so aus: links siehst du die Projektstruktur, rechts die geöffnete Datei src/main.rs mit deinem Code:

4. Turtle-Bibliothek hinzufügen

Öffne die Datei Cargo.toml in deinem Projekt-Ordner. Das ist die Konfigurationsdatei für dein Projekt.

In Zed sieht die Datei so aus, wenn du sie öffnest. Die Abhängigkeiten werden hier in der rechten Spalte bearbeitet, während du links das Projekt und die Datei-Struktur siehst:

Füge unter [dependencies] folgende Zeilen hinzu:

[dependencies]
turtle-lib = { git = "https://github.com/enaut/turtlers", package = "turtle-lib", features = ["svg"] }
macroquad = "0.4"

Deine Cargo.toml sollte jetzt ungefähr so aussehen:

[package]
name = "mein-turtle-projekt"
version = "0.1.0"
edition = "2021"

[dependencies]
turtle-lib = { git = "https://github.com/enaut/turtlers", package = "turtle-lib", features = ["svg"] }
macroquad = "0.4"

Schritt 4: Dein erstes Programm schreiben

  1. Öffne die Datei src/main.rs im Projekt-Ordner
  2. Ersetze den Inhalt mit diesem Code:
use turtle_lib::*;

#[turtle_main]
fn main() {
    turtle.set_pen_color(BLUE);
    turtle.forward(100.0);
    turtle.right(90.0);
    turtle.forward(100.0);
}
  1. Speichere die Datei (Strg+S oder Cmd+S)

Schritt 5: Programm starten

Es gibt mehrere Möglichkeiten, dein Programm zu starten:

Methode 1: Run-Button (empfohlen)

Über der fn main() Zeile siehst du kleine Schaltflächen: Run | Debug. In der aktuellen Zed-Oberfläche erscheint das Menü direkt über dem Funktionsblock.

  1. Klicke auf Run
  2. Warte, während das Programm kompiliert wird (beim ersten Mal dauert es etwas länger)
  3. Ein Fenster öffnet sich und zeigt deine Zeichnung!

So sieht das in Zed aus:

Methode 2: Terminal

Im Terminal von Zed:

cargo run

So führst das Programm aus:

Was ist Cargo?

Cargo ist das Werkzeug, das alle Rust-Entwickler verwenden. Es hilft dir dabei:

  • Neue Projekte zu erstellen (cargo new)
  • Programme zu kompilieren und auszuführen (cargo run)
  • Bibliotheken zu verwalten (wie unsere turtle-lib)
  • Code zu überprüfen (cargo check)

Wo finde ich Rust-Bibliotheken?

Wenn du später weitere Rust-Bibliotheken nutzen möchtest, findest du diese auf:

  • crates.io – Das offizielle Repository für Rust-Bibliotheken
  • Dort kannst du nach Bibliotheken suchen und sie deinem Projekt hinzufügen

Häufige Probleme

“Rust-Hilfe funktioniert nicht”

  • Stelle sicher, dass Rust richtig installiert ist (cargo --version im Terminal)
  • Starte Zed neu
  • Öffne den Projektordner über “Datei → Ordner öffnen” (nicht nur einzelne Dateien)

“Das Programm kompiliert nicht”

  • Überprüfe, ob Cargo.toml die richtigen Dependencies hat
  • Schau dir die Fehlermeldungen im Terminal genau an
  • Die Rust-Unterstützung in Zed zeigt Fehler im Editor mit roten Wellenlinien an

“Das Fenster öffnet sich nicht”

  • Warte einen Moment – beim ersten Mal dauert es länger
  • Schau ins Terminal, ob Fehlermeldungen erscheinen

Zusammenfassung

Du hast jetzt:

  • ✅ Rust und Cargo installiert
  • ✅ Zed als empfohlenen Editor eingerichtet
  • ✅ Dein erstes Projekt erstellt
  • ✅ Die Turtle-Bibliothek hinzugefügt
  • ✅ Gelernt, wie du Programme startest

Perfekt! Deine Programmierumgebung ist jetzt einsatzbereit. Im nächsten Kapitel erfährst du, was Programmieren eigentlich ist und warum die Schildkröten-Grafik dir dabei hilft, es zu lernen.

Was ist Programmieren?

Computer können nur Befehle ausführen

Computer sind sehr schnelle Maschinen, aber sie sind nicht besonders schlau. Sie können nur genau das tun, was man ihnen sagt. Programmieren bedeutet, dem Computer eine Liste von Befehlen zu geben, die er dann Schritt für Schritt ausführt.

Stell dir vor, du erklärst jemandem, wie man ein Sandwich macht:

  1. Nimm zwei Scheiben Brot
  2. Bestreiche eine Scheibe mit Butter
  3. Lege Käse darauf
  4. Lege die zweite Scheibe Brot obendrauf

Das ist wie ein kleines Programm! Jeder Schritt ist eine Anweisung, die nacheinander ausgeführt wird.

Ein Programm ist eine Anleitung

Ein Programm ist nichts anderes als eine Anleitung für den Computer. Diese Anleitung schreibst du in einer besonderen Sprache – einer Programmiersprache. In unserem Fall verwenden wir die Programmiersprache Rust.

Computer verstehen keine normale menschliche Sprache wie Deutsch oder Englisch. Deshalb brauchen wir eine Programmiersprache, die sehr genau und eindeutig ist.

Was ist Rust?

Rust ist eine moderne Programmiersprache, die dafür bekannt ist, dass sie:

  • Sicher ist (weniger Fehler)
  • Schnell läuft
  • Beim Lernen hilft, gute Programme zu schreiben

Rust wird heute von vielen Firmen und Entwicklern auf der ganzen Welt verwendet, zum Beispiel bei Microsoft, Amazon und vielen anderen.

Warum mit der Schildkröte lernen?

Die Schildkröten-Grafik macht das Programmieren lernen besonders einfach, weil:

  • Du sofort siehst, was dein Programm macht
  • Es Spaß macht, bunte Bilder zu erzeugen
  • Die Befehle einfach und verständlich sind
  • Du kreativ sein kannst

Anstatt nur Text auf dem Bildschirm zu sehen, kannst du richtige Zeichnungen erstellen!

Bereit für dein erstes Programm?

Jetzt weißt du, was Programmieren ist und warum Rust eine tolle Sprache dafür ist. Im nächsten Kapitel wird es praktisch: Wir schreiben gemeinsam dein erstes Programm und lassen die Schildkröte einfache Formen zeichnen!

Dein erstes Programm

Jetzt wird es spannend! Du hast gelernt, was Programmieren ist und dass Rust die Sprache ist, mit der wir arbeiten. Jetzt wird es praktisch: Wir schreiben unser erstes Programm. Die Schildkröte soll einfache Linien zeichnen und daraus ein L bilden.

Wo schreibst du den Code?

Wenn du den Anweisungen aus Kapitel 0 (Einrichtung) gefolgt bist, hast du bereits ein Projekt erstellt. Jetzt öffnest du die Datei src/main.rs in deinem Projekt-Ordner – dort schreibst du dein Programm hinein.

Wichtig: Die Datei src/main.rs ist die Hauptdatei deines Projekts. Hier beginnt dein Programm, wenn du es startest.

Mehrere Programme im gleichen Projekt (optional)

Später möchtest du vielleicht mehrere verschiedene Programme ausprobieren, ohne das vorherige zu überschreiben. Dafür kannst du zusätzliche Programmdateien im Ordner src/bin/ erstellen:

  1. Erstelle einen Ordner bin in deinem src-Verzeichnis (falls er noch nicht existiert)
  2. Lege dort neue Dateien an, z.B. src/bin/mein_programm.rs
  3. Starte sie mit: cargo run --bin mein_programm

Für den Anfang reicht aber src/main.rs vollkommen aus!

Das erste Programm

Hier ist der Code für unser erstes Programm:

//! Erstes Beispiel: Einfache Linien zeichnen
//!
//! Dieses Programm zeichnet ein einfaches L auf dem Bildschirm.

use turtle_lib::*;

#[turtle_main]
fn main() {
    // Setze die Stiftfarbe auf Blau
    turtle.set_pen_color(BLUE);
    
    // Zeichne eine Linie nach rechts
    turtle.forward(100.0);
    
    // Drehe nach unten
    turtle.right(90.0);
    
    // Zeichne eine Linie nach unten
    turtle.forward(100.0);
}

Was passiert hier?

Lass uns das Programm Schritt für Schritt durchgehen:

1. Die erste Zeile

use turtle_lib::*;

Diese Zeile sagt dem Computer: “Ich möchte die Schildkröten-Bibliothek verwenden.” Eine Bibliothek ist eine Sammlung von fertigen Befehlen, die wir nutzen können. So müssen wir nicht alles selbst programmieren.

2. Die Hauptfunktion

#[turtle_main]
fn main() {
    // Hier steht unser Code
}

Jedes Rust-Programm hat eine main-Funktion (englisch für “Haupt”). Das ist der Startpunkt des Programms – hier beginnt der Computer mit der Ausführung.

Das #[turtle_main] darüber ist eine spezielle Anweisung, die das Fenster für die Schildkröte vorbereitet.

Tipp: Über der Zeile fn main() siehst du in Zed einen Run-Button. Damit kannst du das Programm starten!

3. Die Stiftfarbe setzen

turtle.set_pen_color(BLUE);

Hier sagen wir der Schildkröte: “Verwende die Farbe Blau zum Zeichnen.” turtle ist unsere Schildkröte und set_pen_color ist der Befehl, um die Farbe zu ändern.

4. Die erste Linie zeichnen

turtle.forward(100.0);

Dieser Befehl sagt der Schildkröte: “Gehe 100 Schritte vorwärts.” Dabei zeichnet sie eine Linie.

5. Drehen

turtle.right(90.0);

Jetzt dreht sich die Schildkröte 90 Grad nach rechts. Sie schaut jetzt nach unten!

6. Die zweite Linie zeichnen

turtle.forward(100.0);

Die Schildkröte geht wieder 100 Schritte vorwärts – jetzt entsteht eine Linie nach unten.

Das Ergebnis ist ein L!

Programm starten

So startest du dein Programm:

  1. Run-Button verwenden (einfachste Methode):

    • Klicke auf Run über der fn main() Zeile
    • Warte einen Moment (beim ersten Mal dauert es etwas länger)
    • Ein Fenster öffnet sich und zeigt deine Zeichnung!
  2. Terminal verwenden:

    • Öffne das Terminal in Zed
    • Tippe cargo run und drücke Enter

Was siehst du?

Wenn du das Programm ausführst, öffnet sich ein Fenster. Darin siehst du:

  • Eine kleine Schildkröte (oft als Dreieck dargestellt)
  • Die Schildkröte bewegt sich und zeichnet dabei
  • Am Ende siehst du ein blaues L!

Ein Quadrat zeichnen

Jetzt wollen wir etwas Anspruchsvolleres zeichnen: ein Quadrat! Ein Quadrat hat vier gleich lange Seiten. Wir müssen also viermal das Gleiche machen: vorwärts gehen und nach rechts drehen.

//! Beispiel: Ein Quadrat zeichnen (ohne Schleife)
//!
//! Dieses Programm zeichnet ein einfaches Quadrat auf dem Bildschirm.

use turtle_lib::*;

#[turtle_main]
fn main() {
    // Setze die Stiftfarbe auf Blau
    turtle.set_pen_color(BLUE);
    
    // Zeichne die erste Seite
    turtle.forward(100.0);  // Gehe 100 Schritte vorwärts
    turtle.right(90.0);     // Drehe 90 Grad nach rechts
    
    // Zeichne die zweite Seite
    turtle.forward(100.0);
    turtle.right(90.0);
    
    // Zeichne die dritte Seite
    turtle.forward(100.0);
    turtle.right(90.0);
    
    // Zeichne die vierte Seite
    turtle.forward(100.0);
    turtle.right(90.0);
}

Hier wiederholen wir den Code viermal:

  • Erste Seite: vorwärts, dann rechts drehen
  • Zweite Seite: vorwärts, dann rechts drehen
  • Dritte Seite: vorwärts, dann rechts drehen
  • Vierte Seite: vorwärts, dann rechts drehen

Das funktioniert, aber du siehst: Der Code wiederholt sich! Es muss doch einen besseren Weg geben…

Genau! Den gibt es – und den lernst du in Kapitel 4 kennen, wenn wir über Schleifen sprechen. Schleifen sind ein Weg, Code-Wiederholungen zu vermeiden.

Zusammenfassung

Du hast gerade gelernt:

  • Wie ein einfaches Rust-Programm aufgebaut ist
  • Was use, fn main() und #[turtle_main] bedeuten
  • Wie man die Schildkröte bewegt (forward)
  • Wie man die Schildkröte dreht (right)
  • Wie man eine Farbe setzt (set_pen_color)
  • Wie man das Programm mit dem Run-Button startet
  • Dass sich Code manchmal wiederholt (das werden wir später eleganter lösen!)

Im nächsten Kapitel schauen wir uns die verschiedenen Bewegungs- und Drehbefehle genauer an.

Bewegung und Drehung

Du hast bereits dein erstes Programm geschrieben und die Schildkröte ein L und ein Quadrat zeichnen lassen. Dabei hast du die Befehle forward() und right() kennengelernt. In diesem Kapitel schauen wir uns alle wichtigen Bewegungsbefehle genauer an und lernen, wie die Schildkröte sich noch bewegen und drehen kann.

Vorwärts und rückwärts gehen

Die Schildkröte kann sich vorwärts und rückwärts bewegen:

Vorwärts gehen

turtle.forward(100.0);

Dieser Befehl bewegt die Schildkröte 100 Schritte vorwärts in die Richtung, in die sie gerade schaut.

Rückwärts gehen

turtle.backward(50.0);

Dieser Befehl bewegt die Schildkröte 50 Schritte rückwärts, ohne dass sie sich umdreht.

Beispiel: Vor und zurück

Hier ist ein Programm, das beides zeigt:

//! Beispiel: Vorwärts und rückwärts bewegen
//!
//! Dieses Programm zeigt, wie man die Schildkröte vorwärts und rückwärts bewegt.

use turtle_lib::*;

#[turtle_main]
fn main() {
    turtle.set_pen_color(RED);

    // Gehe vorwärts
    turtle.forward(100.0);

    turtle.set_pen_color(BLUE);

    // Gehe rückwärts
    turtle.backward(50.0);
}

Die Schildkröte geht zuerst 100 Schritte vorwärts, dann 50 Schritte zurück. Die Linie wird rot sein.

Die Schildkröte kann sich drehen, ohne sich zu bewegen:

turtle.left(90.0);

Dreht die Schildkröte 90 Grad nach links (gegen den Uhrzeigersinn).

Nach rechts drehen

turtle.right(90.0);

Dreht die Schildkröte 90 Grad nach rechts (im Uhrzeigersinn).

Was sind Grade?

Grade sind ein Maß für Winkel. Ein voller Kreis hat 360 Grad:

  • 90 Grad = ein rechter Winkel (ein Viertel eines Kreises)
  • 180 Grad = ein halber Kreis (die Schildkröte schaut in die entgegengesetzte Richtung)
  • 360 Grad = ein ganzer Kreis (zurück zur Ausgangsrichtung)

Beispiel: Drehen und zeichnen

//! Beispiel: Drehen
//!
//! Dieses Programm zeigt, wie man die Schildkröte dreht.

use turtle_lib::*;

#[turtle_main]
fn main() {
    turtle.set_pen_color(GREEN);
    
    // Zeichne eine Linie
    turtle.forward(100.0);
    
    // Drehe nach links
    turtle.left(90.0);
    
    // Zeichne noch eine Linie
    turtle.forward(100.0);
    
    // Drehe nach rechts
    turtle.right(45.0);
    
    // Zeichne eine dritte Linie
    turtle.forward(100.0);
}

In diesem Programm:

  1. Die Schildkröte geht vorwärts und zeichnet eine grüne Linie
  2. Sie dreht sich 90 Grad nach links
  3. Sie zeichnet eine weitere Linie
  4. Sie dreht sich 45 Grad nach rechts
  5. Sie zeichnet eine dritte Linie

So entsteht eine interessante Form!

Die Startposition der Schildkröte

Wenn ein Programm startet:

  • Die Schildkröte ist in der Mitte des Bildschirms
  • Sie schaut nach rechts (das ist 0 Grad)
  • Der Stift ist unten (sie zeichnet also)

Übungsaufgaben

Jetzt bist du dran! Hier sind einige Aufgaben, um das Gelernte zu üben.

Aufgabe 1: Geometrische Übung

Zeichne ein Quadrat, eine Box im 45° Winkelund ein gleichseitiges Dreieck mit der Schildkröte. Ein gleichseitiges Dreieck hat drei gleich lange Seiten und drei gleiche Winkel von je 60 Grad.

Hinweis: Du musst die Schildkröte bei jedem Eckpunkt drehen.

So sollte dein Ergebnis aussehen:

Aufgabe 2: Haus vom Nikolaus

Kennst du den Spruch “Das ist das Haus vom Nikolaus”? Dabei zeichnet man ein Haus in einem Zug, ohne den Stift abzusetzen. Versuche, diese klassische Zeichenübung nachzuprogrammieren!

Hinweis: Das Haus besteht aus einem Quadrat und einem Dreieck als Dach. Du musst verschiedene Winkel verwenden: 90 Grad für die Ecken des Quadrats und 45 Grad für die Diagonalen. Die Diagonale ist etwas länger als die Seiten (ungefähr 141 statt 100).

So sollte dein Ergebnis aussehen:

Aufgabe 3: Fünfstern

Zeichne einen fünfzackigen Stern! Dies ist etwas anspruchsvoller, weil du einen besonderen Winkel verwenden musst.

Hinweis: Bei einem fünfzackigen Stern musst du bei jeder Zacke 144 Grad drehen (das ist 720 ÷ 5). Wiederhole die Bewegung forward() und right(144.0) fünf Mal. Da du noch keine Schleifen kennst, musst du den Code fünf Mal schreiben – im nächsten Kapitel lernst du, wie du das eleganter lösen kannst!

So sollte dein Ergebnis aussehen:

Zusammenfassung

Du hast gelernt:

  • forward(schritte) - bewegt die Schildkröte vorwärts
  • backward(schritte) - bewegt die Schildkröte rückwärts
  • left(grad) - dreht die Schildkröte nach links
  • right(grad) - dreht die Schildkröte nach rechts
  • Grade messen Winkel (90° = rechter Winkel, 360° = voller Kreis)

Im nächsten Kapitel lernst du, wie du Kreise und gekrümmte Linien zeichnest – das eröffnet dir völlig neue Möglichkeiten!

Kreise und gekrümmte Linien

Du hast gelernt, wie du gerade Linien und Winkel verwendest, um verschiedene Formen zu zeichnen. Aber nicht alle Formen bestehen aus geraden Linien! In diesem Kapitel lernst du, wie du Kreise und gekrümmte Linien mit der Schildkröte zeichnest – viel einfacher, als viele kleine gerade Linien zu kombinieren!

Was ist eine gekrümmte Linie?

Eine gekrümmte Linie (oder ein Kreisbogen) ist ein Teil eines Kreises. Die Schildkröte zeichnet sanfte Kurven statt nur gerader Linien.

Mit circle_left() zeichnest du einen Kreisbogen, bei dem die Schildkröte nach links (gegen den Uhrzeigersinn) dreht:

turtle.circle_left(radius, angle, steps);
  • radius: Der Abstand vom Mittelpunkt des Kreises zur Schildkröte (in Pixeln)
  • angle: Der Winkel des Bogens in Grad (360° = ein ganzer Kreis)
  • steps: Die Anzahl der Liniensegmente (je größer, desto glatter)
//! Beispiel: Halbkreis nach links
//!
//! Dieses Programm zeichnet einen schwarzen Halbkreis nach links.

use turtle_lib::*;

#[turtle_main]
fn main() {
    turtle.set_pen_color(BLACK);
    turtle.circle_left(50.0, 180.0, 36);

    // Dass die Bilder nicht so riesig sind, fügen wir hier noch ein paar Linien hinzu
    turtle.set_pen_color(WHITE);
    turtle.pen_up();
    turtle.backward(200.0);
    turtle.pen_down();
    turtle.forward(1.0);
    turtle.pen_up();
    turtle.forward(400.0);
    turtle.pen_down();
    turtle.forward(1.0);
}

circle_right() – Nach rechts drehen und zeichnen

Mit circle_right() zeichnest du einen Kreisbogen, bei dem die Schildkröte nach rechts (im Uhrzeigersinn) dreht:

turtle.circle_right(radius, angle, steps);

Die Parameter sind gleich wie bei circle_left(), aber die Kurve dreht sich in die andere Richtung.

Beispiel: Ein Halbkreis nach rechts

//! Beispiel: Halbkreis nach rechts
//!
//! Dieses Programm zeichnet einen blauen Halbkreis nach rechts.

use turtle_lib::*;

#[turtle_main]
fn main() {
    turtle.set_pen_color(BLUE);
    turtle.circle_right(50.0, 180.0, 36);
    // Dass die Bilder nicht so riesig sind, fügen wir hier noch ein paar Linien hinzu
    turtle.set_pen_color(WHITE);
    turtle.pen_up();
    turtle.backward(200.0);
    turtle.pen_down();
    turtle.forward(1.0);
    turtle.pen_up();
    turtle.forward(400.0);
    turtle.pen_down();
    turtle.forward(1.0);
}

Volle Kreise zeichnen

Um einen vollen Kreis zu zeichnen, verwendest du einen Winkel von 360°:

turtle.circle_left(50.0, 360.0, 36);

Das zeichnet einen perfekten Kreis mit einem Radius von 50 Pixeln!

Kombinieren von Kurven

Du kannst mehrere circle_left() und circle_right() Befehle hintereinander verwenden, um komplexere Formen zu erstellen. Zum Beispiel:

turtle.circle_left(50.0, 180.0, 36);   // Halbkreis nach links
turtle.circle_right(50.0, 180.0, 36);  // Halbkreis nach rechts

Das zeichnet eine S-förmige Kurve!

Übungsaufgaben

Jetzt bist du dran! Hier sind einige Aufgaben, um das Gelernte zu üben.

Aufgabe 1: Ein Herz

Zeichne ein Herz! Ein Herz besteht aus zwei Halbkreisen oben und einer Spitze unten.

Hinweis: Beginne unten bei der Spitze.Du kannst das Herz mit circle_right() für die beiden oberen Rundungen zeichnen.

So sollte dein Ergebnis aussehen:

Aufgabe 2: Ein Stern mit abgerundeten Spitzen

Zeichne einen Stern wie in Kapitel 4, aber mit abgerundeten Spitzen statt scharfen Ecken!

Hinweis: Statt forward() und right() direkt zu verwenden, nutze circle_right() für die Spitzen des Sterns. Das gibt ihnen eine schöne, gerundete Form. Du brauchst 5 Schleifen für die 5 Spitzen des Sterns.

So sollte dein Ergebnis aussehen:

Aufgabe 3: Yin und Yang

Zeichne das klassische Yin-Yang Symbol mit zwei ineinanderliegenden Kurven!

Hinweis: Das Yin-Yang Symbol besteht aus einer großen Kurve, die den Kreis halbiert, und einer kleineren Kurve, die die andere Hälfte füllt. Verwende circle_right() und circle_left() in Kombination. Du kannst auch verschiedene Radien und Füllfarben verwenden.

So sollte dein Ergebnis aussehen:

Aufgabe 4: Eine Blume

Zeichne eine Blume mit Blütenblättern! Jedes Blütenblatt ist eine gekrümmte Form.

Hinweis: Eine Blume besteht aus mehreren Blütenblättern, die in einem Kreis angeordnet sind. Du kannst jedes Blütenblatt mit circle_left() und circle_right() zeichnen und dann die Schildkröte drehen, um das nächste Blütenblatt zu zeichnen. Eine Schleife hilft dir dabei!

So sollte dein Ergebnis aussehen:

Zusammenfassung

Du hast gelernt:

  • circle_left(radius, angle, steps) - Zeichnet einen Kreisbogen nach links
  • circle_right(radius, angle, steps) - Zeichnet einen Kreisbogen nach rechts
  • Mit angle = 360.0 zeichnest du einen vollen Kreis
  • Mit Kurven kannst du viel interessantere und realistischere Formen zeichnen

Im nächsten Kapitel lernst du, wie du mit Farben arbeitest und den Stift heben und senken kannst.

Farben und Stift

Du hast gelernt, wie du gerade Linien oder gekrümmte Kurven zeichnest. Jetzt machen wir unsere Zeichnungen bunter! Viele der Beispiele haben schon farben verwendet. In diesem Kapitel lernst du, wie du die Farbe änderst und den Stift hebst und senkst und wie du Flächen füllst.

Die Stiftfarbe ändern

Du kannst die Farbe des Stifts jederzeit ändern:

turtle.set_pen_color(RED);    // Rot
turtle.set_pen_color(BLUE);   // Blau
turtle.set_pen_color(GREEN);  // Grün
turtle.set_pen_color(YELLOW); // Gelb

Verfügbare Farben

Die Turtle-Bibliothek bietet viele vordefinierte Farben:

  • RED (Rot)
  • BLUE (Blau)
  • GREEN (Grün)
  • YELLOW (Gelb)
  • ORANGE (Orange)
  • PURPLE (Lila)
  • PINK (Rosa)
  • BLACK (Schwarz)
  • WHITE (Weiß)
  • GOLD (Gold)

Wenn du mehr Farben möchtest, kannst du mit use macroquad::color::colors::*; noch mehr Farben verwenden, z.B. DARKGREEN, CYAN, MAGENTA und viele mehr! Eine Liste der Farben bekommt man, wenn man nach dem einbinden von macroquad::color::colors die Autovervollständigung des Editors benutzt, also colors:: eingibt und dann die Vorschläge anschaut.

Beispiel: Bunte Linien

//! Beispiel: Farben verwenden
//!
//! Dieses Programm zeigt verschiedene Farben.

use macroquad::color::colors;
use turtle_lib::*;

#[turtle_main]
fn main() {
    // Rote Linie
    turtle.set_pen_color(RED);
    turtle.forward(100.0);

    // Drehe und zeichne eine blaue Linie
    turtle.left(90.0);
    turtle.set_pen_color(BLUE);
    turtle.forward(100.0);

    // Drehe und zeichne eine grüne Linie
    turtle.left(90.0);
    turtle.set_pen_color(GREEN);
    turtle.forward(100.0);

    // Drehe und zeichne eine gelbe Linie
    turtle.left(90.0);
    turtle.set_pen_color(YELLOW);
    turtle.forward(100.0);

    // Drehe und zeichne eine Violette Linie
    turtle.left(135.0);
    turtle.set_pen_color(colors::VIOLET);
    turtle.forward(141.0);
}

Dieses Programm zeichnet ein buntes Quadrat, bei dem jede Seite eine andere Farbe hat!

Den Stift heben und senken

Manchmal möchtest du die Schildkröte bewegen, ohne eine Linie zu zeichnen. Dafür kannst du den Stift heben:

Stift heben

turtle.pen_up();

Nach diesem Befehl zeichnet die Schildkröte keine Linie mehr, wenn sie sich bewegt.

Stift senken

turtle.pen_down();

Nach diesem Befehl zeichnet die Schildkröte wieder Linien.

Beispiel: Unterbrochene Linie

//! Beispiel: Stift heben und senken
//!
//! Dieses Programm zeigt, wie man den Stift hebt und senkt.

use turtle_lib::*;

#[turtle_main]
fn main() {
    turtle.set_pen_color(RED);
    
    // Zeichne eine Linie
    turtle.forward(50.0);
    
    // Hebe den Stift (keine Linie mehr)
    turtle.pen_up();
    turtle.forward(50.0);
    
    // Senke den Stift wieder (zeichne wieder)
    turtle.pen_down();
    turtle.forward(50.0);
}

Dieses Programm zeichnet eine Linie, hebt dann den Stift, bewegt sich ohne zu zeichnen, und zeichnet dann wieder eine Linie. Es entsteht eine unterbrochene Linie!

Flächen ausfüllen

Du kannst auch Formen mit Farbe ausfüllen:

//! Beispiel: Fläche ausfüllen
//!
//! Dieses Programm zeichnet ein ausgefülltes Dreieck.

use turtle_lib::*;

#[turtle_main]
fn main() {
    // Setze die Füllfarbe
    turtle.set_fill_color(BLUE);
    turtle.set_pen_color(BLACK);

    // Beginne mit dem Füllen
    turtle.begin_fill();

    // Zeichne ein Dreieck
    turtle.forward(100.0);
    turtle.left(120.0);
    turtle.forward(100.0);
    turtle.left(120.0);
    turtle.forward(100.0);
    turtle.left(120.0);

    // Beende das Füllen
    turtle.end_fill();
}

Wie funktioniert das Füllen?

  1. set_fill_color(BLUE) - Setzt die Füllfarbe auf Blau
  2. begin_fill() - Beginnt mit dem Füllen (merkt sich den Startpunkt)
  3. Zeichne die Form (hier ein Dreieck)
  4. end_fill() - Beendet das Füllen und füllt die Form aus

Die Form wird automatisch zwischen dem Start- und Endpunkt geschlossen und ausgefüllt.

Die Stiftdicke ändern

Du kannst auch die Dicke des Stifts ändern:

turtle.set_pen_width(5.0);  // Dicker Stift
turtle.set_pen_width(1.0);  // Dünner Stift

Je größer die Zahl, desto dicker die Linie!

Übungsaufgaben

Jetzt bist du dran! Hier sind einige Aufgaben, um das Gelernte zu üben.

Aufgabe 1: Ein ausgefüllter Stern

Zeichne einen fünfzackigen Stern und fülle ihn mit einer Farbe aus!

Hinweis: Verwende begin_fill() vor dem Zeichnen des Sterns und end_fill() danach. Du kannst die Füllfarbe mit set_fill_color() setzen und die Randfarbe mit set_pen_color() wählen. Für den Stern brauchst du eine Schleife mit 5 Wiederholungen und einem Drehwinkel von 144 Grad.

So sollte dein Ergebnis aussehen:

Aufgabe 2: Ein Käse

Zeichne ein gelbes Käsestück! Ein Käsestück ist ein Viereck mit drei runden Löchern darin.

Hinweis: Zeichne zuerst ein ausgefülltes gelbes Viereck. Dann hebe den Stift (pen_up()), bewege die Schildkröte zu verschiedenen Positionen mit goto(x, y), senke den Stift wieder (pen_down()) und zeichne drei kleine ausgefüllte weiße Kreise (du kannst einen Kreis zeichnen, indem du ein Vieleck mit vielen Seiten und kleinen Winkeln zeichnest, z.B. 36 Seiten mit je 10 Grad Drehung).

So sollte dein Ergebnis aussehen:

Aufgabe 3: Drei ineinanderliegende Quadrate

So sollte dein Ergebnis aussehen:

Zeichne drei Quadrate, die ineinander liegen, aber sich nicht berühren!

Hinweis: Zeichne zuerst ein kleines Quadrat in der Mitte. Dann hebe den Stift (pen_up()), bewege die Schildkröte etwas nach links und unten, senke den Stift (pen_down()) und zeichne ein größeres Quadrat. Wiederhole das für ein drittes, noch größeres Quadrat. Du kannst auch verschiedene Farben für jedes Quadrat verwenden!

Zusammenfassung

Du hast gelernt:

  • set_pen_color(farbe) - Ändert die Stiftfarbe
  • pen_up() - Hebt den Stift (zeichnet nicht mehr)
  • pen_down() - Senkt den Stift (zeichnet wieder)
  • set_fill_color(farbe) - Setzt die Füllfarbe
  • begin_fill() - Beginnt mit dem Füllen einer Form
  • end_fill() - Beendet das Füllen und füllt die Form aus
  • set_pen_width(dicke) - Ändert die Stiftdicke

Im nächsten Kapitel lernst du, wie du deine Zeichnungen noch effizienter machen kannst!

Lerne die Programmiersprachenfunktionen kennen

Bisher hast du vor allem Turtle-Befehle kennengelernt: forward(), right(), circle_left(), pen_up() und set_pen_color(). Das sind wichtige Befehle für die Schildkröte – aber das wird natürlich nie wirklich für richtige Programme verwendet. Im folgenden werden einige Konzepte der Programmiersprache Rust anhand von Turtleprogrammen erläutert. Diese Konzepte finden sich in jedem Rust-Programm. Tatsächlich funktionieren die meisten Programmiersprachen ähnlich und nutzen dieselben grundlegenden Ideen, um Probleme sauber, kürzer und leichter verständlich zu lösen.

In den nächsten Kapiteln wirst du genau diese allgemeinen Bausteine lernen. Die eigentliche Erklärung steckt in den Unterkapiteln – hier nur ein kurzer Überblick:

1. Wiederholungen (Schleifen)

Manchmal willst du denselben Befehl oder einige Befehle mehrfach ausführen, zum Beispiel vier Seiten eines Quadrats oder zehn Kreise hintereinander. Dafür benutzt man Schleifen.

Wichtige Idee:

  • Ein Befehl wird automatisch mehrfach ausgeführt
  • Du sparst Zeit und Schreibarbeit
  • Der Code wird kürzer und verständlicher

Detaillierte Erklärung: Wiederholungen (Schleifen)

2. Variablen

Mit Variablen kannst du Werte speichern und später wiederverwenden. Statt eine Zahl immer wieder von Hand einzutippen, legst du sie einmal an und nutzt sie dann immer wieder den Namen statt des Zahlenwertes. So kann man zum Beispiel die Grösse eines Quadrats an nur einer einzigen Stelle festlegen und später auch ändern.

Wichtige Idee:

  • Werte werden in einer Variable gespeichert
  • Du kannst sie später ändern oder weiterverwenden
  • Code wird flexibler und leichter anpassbar

Detaillierte Erklärung: Variablen

3. Funktionen

Funktionen sind kleine, benannte Codeblöcke, die du immer wieder aufrufen kannst. So kannst du komplexe Aufgaben in überschaubare Teile aufteilen.

Wichtige Idee:

  • Wiederverwendbarer Code
  • Ein Problem in einzelne Aufgaben zerlegen
  • Programme werden besser organisiert

Beispiele:

  • zeichne_quadrat()
  • zeichne_herz()
  • zeichne_blume()

Detaillierte Erklärung: Funktionen

4. Weitere Beispiele

Am Ende bringst du alles zusammen: Bewegung, Wiederholungen, Variablen und Funktionen. Dadurch kannst du echte kleine Kunstwerke und Programme bauen.

Detaillierte Erklärung: Weitere Beispiele

Warum sind diese Grundlagen so wichtig?

Diese „allgemeinen“ Programmierkonzepte tauchen in fast jeder Sprache auf – nicht nur in Rust, sondern auch in Python, JavaScript, C++ und vielen anderen.

Sie helfen dir:

  • Code kürzer zu schreiben
  • Fehler leichter zu finden
  • Programme besser zu strukturieren
  • komplexe Aufgaben verständlich zu lösen

Lernplan für die nächsten Kapitel

Der natürliche Reihenfolge nach geht es so weiter:

  1. Schleifen lernen
  2. Variablen verstehen
  3. Funktionen verwenden
  4. Alles in größeren Beispielen kombinieren

Wenn du diese Grundbausteine beherrschst, bist du schon weit auf dem Weg zu echten Programmen – nicht nur zu Schildkrötenzeichnungen!

Im nächsten Abschnitt lernst du zuerst, wie du Befehle wiederholt ausführen kannst: mit Schleifen.

Wiederholungen (Schleifen)

Du kennst jetzt gerade Linien und auch gekrümmte Linien mit Kreisen. Egal ob gerade oder gekrümmt – wenn du die gleiche Bewegung mehrmals hintereinander brauchst, möchtest du das nicht jedes Mal von Hand aufschreiben. In diesem Kapitel lernst du Schleifen – damit kannst du Befehle automatisch wiederholen!

turtle.forward(100.0);
turtle.right(90.0);

turtle.forward(100.0);
turtle.right(90.0);

turtle.forward(100.0);
turtle.right(90.0);

turtle.forward(100.0);
turtle.right(90.0);

Das war ziemlich mühsam! Stell dir vor, du möchtest 100 mal den gleichen Befehl ausführen. Es wäre sehr mühsam, diesen Befehl 100 mal zu schreiben! Hier kommen Schleifen ins Spiel.

Was ist eine Schleife?

Eine Schleife ist ein Programmierkonstrukt, das Befehle mehrmals wiederholt. Du sagst dem Computer: “Führe diese Befehle X-mal aus.”

Die for-Schleife

Die häufigste Art von Schleife ist die for-Schleife. Hier ist die Grundstruktur:

for _ in 0..anzahl {
    // Befehle, die wiederholt werden
}
  • for bedeutet “für jede Wiederholung”
  • 0..anzahl gibt an, wie oft wiederholt wird (von 0 bis anzahl-1)
  • Der Unterstrich _ bedeutet, dass wir die Zählvariable nicht brauchen
  • Die Befehle innerhalb der geschweiften Klammern { } werden wiederholt

Aufgabe 1: Ein Quadrat mit Schleife

Erinnere dich an unser Quadrat von vorhin. Versuche jetzt, ein Quadrat mit einer Schleife zu zeichnen. Das wird viel kürzer und übersichtlicher als den Code viermal zu schreiben!

Hinweis: Ein Quadrat hat 4 Seiten. Die Formel 360 ÷ 4 = 90 Grad zeigt dir den Drehwinkel.

So sollte dein Ergebnis aussehen:

Lösungsblock

Zeige die Lösung
//! Beispiel: Ein Quadrat mit Schleife zeichnen
//!
//! Dieses Programm zeichnet ein Quadrat mit einer Schleife.

use turtle_lib::*;

#[turtle_main]
fn main() {
    // Setze die Stiftfarbe auf Blau
    turtle.set_pen_color(BLUE);
    
    // Zeichne ein Quadrat mit 4 Seiten
    for _ in 0..4 {
        turtle.forward(100.0);  // Gehe 100 Schritte vorwärts
        turtle.right(90.0);     // Drehe 90 Grad nach rechts
    }
}

Statt 8 Zeilen Code haben wir jetzt nur noch 3 Zeilen in der Schleife. Das macht genau das Gleiche wie der lange Code vorher, ist aber viel einfacher zu lesen und zu verstehen!

Aufgabe 2: Ein Achteck

Ein Achteck hat 8 gleich lange Seiten. Versuche, es mit einer Schleife zu zeichnen.

Hinweis: Verwende die Formel 360 ÷ 8 = 45 Grad für den Drehwinkel. Du brauchst eine Schleife mit 8 Wiederholungen.

So sollte dein Ergebnis aussehen:

Die Formel für regelmäßige Vielecke

Für ein Vieleck mit n Seiten ist der Drehwinkel:

360 ÷ n

Beispiele:

  • Dreieck (3 Seiten): 360 ÷ 3 = 120 Grad
  • Quadrat (4 Seiten): 360 ÷ 4 = 90 Grad
  • Fünfeck (5 Seiten): 360 ÷ 5 = 72 Grad
  • Sechseck (6 Seiten): 360 ÷ 6 = 60 Grad
  • Achteck (8 Seiten): 360 ÷ 8 = 45 Grad

Aufgabe 3: Ein Stern

Wollen wir etwas Komplexeres zeichnen? Versuche, einen fünfzackigen Stern zu zeichnen!

Hinweis: Ein fünfzackiger Stern braucht einen anderen Winkel als ein regelmäßiges Fünfeck. Hier verwendest du 144 Grad (das ist 720 ÷ 5). Du brauchst eine Schleife mit 5 Wiederholungen.

So sollte dein Ergebnis aussehen:

Warum sind Schleifen nützlich?

Schleifen sind sehr nützlich, weil:

  1. Weniger Code: Statt 8 mal den gleichen Befehl zu schreiben, schreibst du ihn nur einmal
  2. Weniger Fehler: Du kannst dich nicht vertippen, wenn du nur einmal schreibst
  3. Leichter zu ändern: Willst du ein Zehneck statt eines Achtecks? Ändere einfach die 8 zu 10!

Weitere Aufgaben zum Üben

Versuche, diese Formen zu zeichnen:

  • Ein Dreieck (3 Seiten, 120 Grad)
  • Ein Sechseck (6 Seiten, 60 Grad)
  • Ein Zwölfeck (12 Seiten, 30 Grad)

Zusammenfassung

Du hast gelernt:

  • Was eine Schleife ist (ein Befehl, der sich wiederholt)
  • Wie man eine for-Schleife schreibt
  • Die Formel für regelmäßige Vielecke: 360 ÷ anzahl_seiten
  • Dass Schleifen den Code kürzer und einfacher machen

Im nächsten Kapitel lernst du, wie du Werte speichern und wiederverwenden kannst – mit Variablen!

Variablen

Du kannst jetzt bunte Zeichnungen erstellen und hast gelernt, wie du den Stift hebst und senkst. Aber was, wenn du bestimmte Werte – wie die Größe eines Quadrats oder die Anzahl der Seiten – mehrmals verwenden möchtest? Hier kommen Variablen ins Spiel. Variablen sind wie Schubladen, in denen du Werte aufbewahren kannst. Sie machen deine Programme flexibler und leichter zu verstehen.

Was ist eine Variable?

Eine Variable ist ein Name, der einen Wert speichert. Stell dir vor, du hast eine Schublade mit dem Etikett “Seitenlänge”. In dieser Schublade liegt eine Zahl, zum Beispiel 80. Immer wenn du diese Zahl brauchst, schaust du in die Schublade “Seitenlänge”.

In Rust sieht das so aus:

let seitenlaenge = 80.0;
  • let bedeutet “lass” oder “erstelle” (eine neue Variable)
  • seitenlaenge ist der Name der Variable
  • = bedeutet “bekommt den Wert”
  • 80.0 ist der Wert, den wir speichern

Warum Variablen verwenden?

Variablen haben mehrere Vorteile:

  1. Lesbarkeit: Der Code ist leichter zu verstehen
  2. Wiederverwendung: Du kannst den Wert mehrmals verwenden
  3. Änderbarkeit: Du musst nur an einer Stelle ändern

Beispiel: Quadrat mit Variable

    turtle.set_pen_color(GREEN);

    // Eine Variable für die Seitenlänge
    let seitenlaenge = 80.0;

    // Zeichne ein Quadrat mit dieser Seitenlänge
    for _ in 0..4 {
        turtle.forward(seitenlaenge);
        turtle.right(90.0);
    }

Hier verwenden wir eine Variable seitenlaenge für die Größe des Quadrats. Wenn wir die Größe ändern wollen, müssen wir nur die Zeile let seitenlaenge = 80.0; ändern, statt alle vier forward-Befehle!

Mehrere Variablen

Du kannst so viele Variablen verwenden, wie du möchtest:

    // Variablen für verschiedene Werte
    let seitenlaenge = 60.0;
    let anzahl_seiten = 6;
    let winkel = 60.0;

    turtle.set_pen_color(ORANGE);

    // Zeichne ein Sechseck
    for _ in 0..anzahl_seiten {
        turtle.forward(seitenlaenge);
        turtle.right(winkel);
    }

Hier haben wir drei Variablen:

  • seitenlaenge - für die Länge jeder Seite
  • anzahl_seiten - für die Anzahl der Seiten
  • winkel - für den Drehwinkel

Das macht den Code sehr übersichtlich!

Variablen in Schleifen verwenden

Du kannst auch Variablen in Schleifen verwenden:

for _ in 0..anzahl_seiten {
    turtle.forward(seitenlaenge);
    turtle.right(winkel);
}

Hier verwenden wir anzahl_seiten als Anzahl der Wiederholungen!

Variablen ändern

Manchmal möchtest du den Wert einer Variable ändern. Dafür brauchst du das Wort mut (von “mutable” = veränderbar):

let mut laenge = 5.0;
laenge = laenge + 3.0;  // Jetzt ist laenge 8.0

Beispiel: Spirale mit sich ändernder Variable

    turtle.set_pen_color(PURPLE);

    let mut laenge = 5.0;

    // Zeichne eine Spirale
    for _ in 0..50 {
        turtle.forward(laenge);
        turtle.right(90.0);
        laenge = laenge + 3.0;  // Erhöhe die Länge bei jedem Schritt
    }

Hier beginnt laenge bei 5.0 und wird in jedem Schritt um 3.0 erhöht. So entsteht eine Spirale, bei der die Linien immer länger werden!

Rechenoperationen mit Variablen

Du kannst mit Variablen rechnen:

let a = 10.0;
let b = 5.0;
let summe = a + b;        // 15.0 (Addition)
let differenz = a - b;    // 5.0 (Subtraktion)
let produkt = a * b;      // 50.0 (Multiplikation)
let quotient = a / b;     // 2.0 (Division)

Ein praktisches Beispiel ist ein Vieleck, bei dem der Drehwinkel mit einer Berechnung entsteht:

    let seitenlaenge = 60.0;
    let anzahl_seiten = 8;
    let winkel = 360.0 / anzahl_seiten as f64;

    turtle.set_pen_color(PINK);

    for _ in 0..anzahl_seiten {
        turtle.forward(seitenlaenge);
        turtle.right(winkel);
    }

Hier berechnen wir den Winkel mit 360.0 / anzahl_seiten as f64. Wenn du die Anzahl der Seiten änderst, passt der Winkel automatisch mit!

Zahlentypen

In Rust gibt es verschiedene Arten von Zahlen:

  • Ganze Zahlen (ohne Komma): let anzahl = 5;
  • Kommazahlen (mit Punkt): let laenge = 10.0;

Für die Turtle-Befehle brauchst du meist Kommazahlen (mit .0 am Ende).

Mehr dazu findest du in Kapitel Mehr über Daten.

Gute Namen für Variablen

Wähle Namen, die beschreiben, was in der Variable gespeichert ist:

Gut:

  • seitenlaenge
  • anzahl_wiederholungen
  • drehwinkel

Nicht so gut:

  • x
  • zahl1
  • dings

Gute Namen machen deinen Code viel leichter verständlich!

Zusammenfassung

Du hast gelernt:

  • let name = wert; - Erstellt eine Variable
  • let mut name = wert; - Erstellt eine veränderbare Variable
  • Variablen machen Code lesbarer und flexibler
  • Du kannst mit Variablen rechnen
  • Gute Variablennamen sind wichtig für verständlichen Code

Im nächsten Kapitel lernst du Funktionen kennen – eine Möglichkeit, Code zu organisieren und wiederzuverwenden!

Funktionen

Mit Variablen kannst du Werte speichern und wiederverwenden – das hast du im letzten Kapitel gelernt. Aber was, wenn du nicht nur Werte, sondern ganze Code-Abschnitte wiederverwenden möchtest? Hier kommen Funktionen ins Spiel. Funktionen sind wie kleine Unterprogramme, die eine bestimmte Aufgabe erledigen. Sie helfen dir, deinen Code zu organisieren und wiederzuverwenden.

Was ist eine Funktion?

Eine Funktion ist ein benannter Block von Code, den du immer wieder aufrufen kannst. Stell dir vor, du hast ein Rezept für Pfannkuchen. Anstatt jedes Mal die ganze Anleitung aufzuschreiben, sagst du einfach “Mache Pfannkuchen” – und alle wissen, was zu tun ist.

Die main-Funktion

Du kennst bereits eine Funktion – die main-Funktion! Das ist die Funktion, in der dein Programm startet:

fn main() {
    // Dein Code hier
}

Eine eigene Funktion erstellen

So erstellst du eine eigene Funktion:

fn zeichne_quadrat(turtle: &mut TurtlePlan, groesse: f32) {
    for _ in 0..4 {
        turtle.forward(groesse);
        turtle.right(90.0);
    }
}

Was bedeutet das?

  • fn bedeutet “function” (Funktion)
  • zeichne_quadrat ist der Name der Funktion. Diesen Namen kannst du frei wählen. Wähle ihn so, dass er die Funktion kurz und verständlich beschreibt.
  • (turtle: &mut TurtlePlan, groesse: f32) sind die Parameter (Werte, die die Funktion braucht)
  • Der Code zwischen { } wird ausgeführt, wenn die Funktion aufgerufen wird

Parameter

Parameter sind Werte, die du einer Funktion übergibst. In unserem Beispiel:

  • turtle: &mut TurtlePlan - Die Schildkröte, die zeichnen soll
  • groesse: f32 - Die Größe des Quadrats

So kann die gleiche Funktion Quadrate in verschiedenen Größen zeichnen!

Eine Funktion aufrufen

Um eine Funktion zu verwenden, rufst du sie auf:

zeichne_quadrat(&mut turtle, 50.0);

Das bedeutet: “Führe die Funktion zeichne_quadrat aus und übergib ihr die Schildkröte und die Größe 50.0.”

Vollständiges Beispiel

//! Beispiel: Funktionen verwenden
//!
//! Dieses Programm zeigt, wie man eigene Funktionen erstellt.

use turtle_lib::*;

// Eine Funktion, die ein Quadrat zeichnet
fn zeichne_quadrat(turtle: &mut TurtlePlan, groesse: f32) {
    for _ in 0..4 {
        turtle.forward(groesse);
        turtle.right(90.0);
    }
}

#[turtle_main]
fn main() {
    turtle.set_pen_color(BLUE);
    
    // Zeichne ein kleines Quadrat
    zeichne_quadrat(turtle, 50.0);
    
    // Bewege die Schildkröte
    turtle.pen_up();
    turtle.forward(120.0);
    turtle.pen_down();
    
    // Zeichne ein größeres Quadrat
    turtle.set_pen_color(RED);
    zeichne_quadrat(turtle, 80.0);
}

Dieses Programm:

  1. Definiert eine Funktion zeichne_quadrat
  2. Zeichnet ein kleines Quadrat (50.0)
  3. Bewegt die Schildkröte
  4. Zeichnet ein größeres Quadrat (80.0) in einer anderen Farbe

Die Funktion können wir so oft aufrufen, wie wir wollen – mit verschiedenen Größen!

Mehrere Funktionen

Du kannst so viele Funktionen erstellen, wie du möchtest:

//! Beispiel: Mehrere Formen
//!
//! Dieses Programm zeichnet mehrere verschiedene Formen.

use turtle_lib::*;

fn zeichne_dreieck(turtle: &mut TurtlePlan, groesse: f32) {
    for _ in 0..3 {
        turtle.forward(groesse);
        turtle.left(120.0);
    }
}

fn zeichne_quadrat(turtle: &mut TurtlePlan, groesse: f32) {
    for _ in 0..4 {
        turtle.forward(groesse);
        turtle.right(90.0);
    }
}

#[turtle_main]
fn main() {
    // Zeichne ein Dreieck
    turtle.set_pen_color(RED);
    zeichne_dreieck(turtle, 80.0);
    
    // Bewege zur nächsten Position
    turtle.pen_up();
    turtle.forward(150.0);
    turtle.pen_down();
    
    // Zeichne ein Quadrat
    turtle.set_pen_color(BLUE);
    zeichne_quadrat(turtle, 70.0);
}

Hier haben wir zwei Funktionen:

  • zeichne_dreieck - zeichnet ein Dreieck
  • zeichne_quadrat - zeichnet ein Quadrat

Jede Funktion macht genau eine Sache – das macht den Code übersichtlich!

Warum Funktionen verwenden?

Funktionen haben viele Vorteile:

  1. Wiederverwendung: Schreibe den Code einmal, verwende ihn oft
  2. Organisation: Teile komplexe Programme in kleine, verständliche Teile
  3. Lesbarkeit: zeichne_stern() ist leichter zu verstehen als 20 Zeilen Code
  4. Fehlersuche: Wenn etwas nicht funktioniert, weißt du genau, wo du suchen musst

Funktionen ohne Parameter

Funktionen müssen nicht unbedingt Parameter haben. Wenn eine Funktion keine Informationen von außen braucht, kann sie auch ohne Parameter definiert werden:

fn sag_hallo() {
    println!("Hallo, Welt!");
}

Diese Funktion macht immer dasselbe, ohne irgendeinen Wert zu benötigen.

In einem Turtle-Programm ist turtle oft ein Parameter, weil die Funktion die Schildkröte zum Zeichnen braucht. Wenn du also eine Funktion schreibst, die die Schildkröte zeichnet, brauchst du sie meistens als Parameter.

Das DRY-Prinzip

Programmierer folgen oft dem DRY-Prinzip: “Don’t Repeat Yourself” (Wiederhole dich nicht).

Schlecht (sich wiederholend):

// Quadrat 1
for _ in 0..4 {
    turtle.forward(50.0);
    turtle.right(90.0);
}
// ... Position ändern ...
// Quadrat 2
for _ in 0..4 {
    turtle.forward(80.0);
    turtle.right(90.0);
}

Gut (mit Funktion):

zeichne_quadrat(&mut turtle, 50.0);
// ... Position ändern ...
zeichne_quadrat(&mut turtle, 80.0);

Die Version mit Funktion ist kürzer, klarer und leichter zu ändern!

Übungsaufgaben

Jetzt bist du dran! Hier sind Aufgaben zum Üben von Funktionen. Denke daran: Mit Funktionen kannst du denselben Code immer wieder aufrufen – und mit Parametern kannst du ihn flexibel gestalten!

Aufgabe 1: Dreieck-Funktion

Erstelle eine Funktion zeichne_dreieck(), die ein gleichseitiges Dreieck zeichnet. Die Funktion soll einen Parameter groesse haben, damit du Dreiecke verschiedener Größen zeichnen kannst.

Aufgabe 2: Viereck und Fünfeck

Schreibe zwei Funktionen:

  • zeichne_viereck(turtle: &mut TurtlePlan, groesse: f32) für ein Quadrat
  • zeichne_fuenfeck(turtle: &mut TurtlePlan, groesse: f32) für ein regelmäßiges Fünfeck

Aufgabe 3: Fünfstern-Funktion

Erstelle eine Funktion zeichne_fuenfstern(), die einen fünfzackigen Stern zeichnet. Der Stern soll einen Parameter groesse haben.

Aufgabe 4: Herz-Funktion

Schreibe eine Funktion zeichne_herz(), die ein Herz zeichnet. Überlege, wie du Kurven mit geraden Linien und Drehungen näherungsweise zeichnen kannst!

Aufgabe 5: Blume-Funktion

Erstelle eine Funktion zeichne_blume(turtle: &mut TurtlePlan, blaetter: i32), die eine Blume mit mehreren Blütenblättern zeichnet. Die Funktion soll bestimmen können, wie viele Blütenblätter die Blume hat.

Aufgabe 6: Haus mit Funktionen

Schreibe eine Funktion zeichne_haus(turtle: &mut TurtlePlan, breite: f32), die ein komplettes Haus zeichnet (ein Quadrat mit einem dreieckigen Dach). Die Größe soll über den Parameter breite bestimmt werden.

Rufe die Funktion mehrmals auf, um ein ganzes Dorf mit unterschiedlich großen Häusern zu zeichnen! Bewege die Schildkröte zwischen den Häusern, damit die Häuser nebeneinander stehen.

Zusammenfassung

Du hast gelernt:

  • fn name() { } - Erstellt eine neue Funktion
  • Parameter ermöglichen es, Werte an Funktionen zu übergeben
  • Funktionen machen Code wiederverwendbar und übersichtlich
  • Das DRY-Prinzip: “Don’t Repeat Yourself”
  • Jede Funktion sollte eine klare Aufgabe haben

Im nächsten Kapitel siehst du weitere kreative Beispiele, die alles zusammenbringen, was du gelernt hast!

Weitere Beispiele

Du hast in den letzten Kapiteln viel gelernt: Bewegung, Schleifen, Farben, Variablen und Funktionen. Jetzt ist es Zeit, alles zusammenzubringen! In diesem Kapitel schauen wir uns einige kreative Beispiele an, die zeigen, was du mit der Turtle-Grafik alles machen kannst.

Ideen zum Experimentieren

Jetzt bist du dran! Hier sind einige Ideen, was du ausprobieren kannst:

1. Muster mit verschiedenen Farben

Versuche, ein Programm zu schreiben, das mehrere Quadrate in verschiedenen Farben zeichnet, die sich überlappen.

Tipp: Verwende pen_up() und pen_down(), um die Schildkröte zwischen den Quadraten zu bewegen.

2. Ein Haus zeichnen

Zeichne ein einfaches Haus:

  • Ein Quadrat für das Gebäude
  • Ein Dreieck für das Dach
  • Ein kleines Rechteck für die Tür
  • Zwei kleine Quadrate für die Fenster

Tipp: Erstelle Funktionen für zeichne_rechteck() und zeichne_dreieck().

3. Eine Blume

Zeichne eine Blume mit mehreren Blütenblättern:

  • Jedes Blütenblatt ist ein ausgefüllter Kreis oder eine Ellipse
  • Drehe die Schildkröte nach jedem Blütenblatt
  • Verwende verschiedene Farben

4. Ein Regenbogen

Zeichne konzentrische Halbkreise in verschiedenen Farben:

  • Rot (außen)
  • Orange
  • Gelb
  • Grün
  • Blau
  • Lila (innen)

Tipp: Du kannst circle_left() oder circle_right() für Kreisbögen verwenden.

5. Dein Name

Versuche, die Buchstaben deines Namens mit der Schildkröte zu zeichnen! Du kannst mit einem großen Anfangsbuchstaben starten und dann immer weiter einzelne Buchstaben zu einem Wort kombinieren.

Tipps für kreative Zeichnungen

  1. Plane vorher: Überlege dir, welche Formen du brauchst
  2. Funktionen: Erstelle Funktionen für wiederholte Formen
  3. Farben: Experimentiere mit verschiedenen Farben
  4. Füllung: Verwende begin_fill() und end_fill() für ausgefüllte Formen
  5. Position: Nutze pen_up() und pen_down(), um die Schildkröte zu bewegen

Was du bis jetzt gelernt hast

Herzlichen Glückwunsch! Du hast die Grundlagen des Programmierens gelernt:

Konzepte

  • Sequenz: Befehle werden nacheinander ausgeführt
  • Wiederholung: Schleifen wiederholen Befehle
  • Variablen: Werte speichern und wiederverwenden
  • Funktionen: Code organisieren und wiederverwenden

Turtle-Befehle

  • Bewegung: forward(), backward()
  • Drehung: left(), right()
  • Farben: set_pen_color(), set_fill_color()
  • Stift: pen_up(), pen_down()
  • Füllung: begin_fill(), end_fill()
  • Dicke: set_pen_width()

Rust-Grundlagen

  • let für Variablen
  • for für Schleifen
  • fn für Funktionen
  • Kommentare mit //

Wie geht es weiter?

Du hast jetzt eine solide Grundlage für das Programmieren! Mit Bewegung, Schleifen, Farben, Variablen und Funktionen kannst du schon viele tolle Zeichnungen erstellen.

Aber Rust kann noch viel mehr! In den nächsten Kapiteln lernst du:

  • Strings: Wie man mit Text arbeitet
  • Sammlungen: Listen von Werten verwalten
  • Structs: Eigene Datentypen erstellen
  • Enums: Verschiedene Zustände modellieren

Diese Konzepte sind wichtig, um richtige Programme zu schreiben – zum Beispiel ein Hangman-Spiel!

Wichtige Tipps für Anfänger

  1. Fehler sind normal: Jeder Programmierer macht Fehler – auch erfahrene!
  2. Ausprobieren: Experimentiere mit dem Code und schau, was passiert
  3. Kleine Schritte: Ändere immer nur eine Sache und teste dann
  4. Fragen stellen: Wenn du nicht weiterkommst, frage jemanden oder suche online

Zusammenfassung

Programmieren ist wie eine neue Sprache lernen – am Anfang ist es ungewohnt, aber mit der Zeit wird es immer leichter. Die Schildkröten-Grafik ist ein großartiger Einstieg, weil du sofort siehst, was dein Code bewirkt.🐢

Eingabe vom Benutzer

Bisher haben alle Werte fest im Code gestanden. Jetzt lernst du, wie der Benutzer selbst etwas eingeben kann!

Was ist eine Dialogbox?

Eine Dialogbox ist ein kleines Fenster, das eine Frage stellt. Du kennst das bestimmt:

  • “Wie heißt du?”
  • “Gib eine Zahl ein:”

Bevor du sie benutzen kannst, musst du die Bibliothek in deiner Cargo.toml ergänzen:

[dependencies]
rustydialogs = "0.4"

Eine einfache Eingabe

So fragst du nach einem Namen:

    let input = TextInput {
        title: "Name",
        message: "Wie heißt du?",
        value: "",
        mode: TextInputMode::SingleLine,
        owner: None,
    };
    match input.show() {
        Some(name) => {
            println!("Hallo, {}!", name);
        }
        _ => {
            println!("Keine Eingabe.");
        }
    };

Was passiert?

  • TextInput { ... } erstellt die Frage
  • .show() zeigt die Box an
  • Some(text) enthält die Eingabe, None bedeutet Abbruch
  • Der Benutzer tippt etwas ein
  • Wir bekommen den Text zurück

Eine Zahl eingeben

Oft möchtest du eine Zahl haben:

    let input = TextInput {
        title: "Zahl",
        message: "Gib eine Zahl ein:",
        value: "",
        mode: TextInputMode::SingleLine,
        owner: None,
    };

    match input.show() {
        Some(text) => match text.parse::<i32>() {
            Ok(zahl) => {
                let message = format!("Deine Zahl mal 2 ist: {}", zahl * 2);
                let _ = MessageBox {
                    title: "Ergebnis",
                    message: &message,
                    icon: MessageIcon::Info,
                    buttons: MessageButtons::Ok,
                    owner: None,
                }
                .show();
            }
            Err(_) => {
                let _ = MessageBox {
                    title: "Fehler",
                    message: "Das muss eine Zahl sein!",
                    icon: MessageIcon::Warning,
                    buttons: MessageButtons::Ok,
                    owner: None,
                }
                .show();
            }
        },
        None => {
            let _ = MessageBox {
                title: "Abbruch",
                message: "Keine Eingabe.",
                icon: MessageIcon::Info,
                buttons: MessageButtons::Ok,
                owner: None,
            }
            .show();
        }
    }

Mit .parse() wird der Text in eine Zahl umgewandelt.
Wenn die Eingabe keine Zahl ist, zeigt das Beispiel eine Fehlermeldung an.
TextInput::show() liefert Option<String> zurück: Some(...) bei gültiger Eingabe oder Abbruch, sonst None.

Übung: Dein Alter

Schreibe ein Programm, das:

  1. Nach deinem Namen fragt
  2. Nach deinem Alter fragt
  3. Ausgibt: “Hallo [Name], du bist [Alter] Jahre alt!”
Lösung
use turtle_lib::turtle_main;
use rustydialogs::{MessageBox, MessageButtons, MessageIcon, MessageResult, TextInput, TextInputMode};

#[turtle_main]
fn main() {
    let name = match TextInput {
        title: "Name",
        message: "Wie heißt du?",
        value: "",
        mode: TextInputMode::SingleLine,
        owner: None,
    }
    .show()
    {
        Some(n) => n,
        None => return,
    };

    let alter_text = match TextInput {
        title: "Alter",
        message: "Wie alt bist du?",
        value: "",
        mode: TextInputMode::SingleLine,
        owner: None,
    }
    .show()
    {
        Some(a) => a,
        None => return,
    };

    let alter: u32 = match alter_text.parse() {
        Ok(value) => value,
        Err(_) => {
            let _ = MessageBox {
                title: "Fehler",
                message: "Bitte gib eine gültige Zahl ein!",
                icon: MessageIcon::Warning,
                buttons: MessageButtons::Ok,
                owner: None,
            }
            .show();
            return;
        }
    };

    let text = format!("Hallo {}, du bist {} Jahre alt!", name, alter);
    let _ = MessageBox {
        title: "Ergebnis",
        message: &text,
        icon: MessageIcon::Info,
        buttons: MessageButtons::Ok,
        owner: None,
    }
    .show();
}

Eine Nachricht anzeigen

Manchmal willst du nur etwas mitteilen:

use rustydialogs::{MessageBox, MessageButtons, MessageIcon};

fn main() {
    let _ = MessageBox {
        title: "Hallo",
        message: "Willkommen zu meinem Programm!",
        icon: MessageIcon::Info,
        buttons: MessageButtons::Ok,
        owner: None,
    }
    .show();
}

Ja/Nein-Frage

Du kannst auch Ja/Nein fragen:

use rustydialogs::{MessageBox, MessageButtons, MessageIcon, MessageResult};

fn main() {
    match MessageBox {
        title: "Frage",
        message: "Möchtest du fortfahren?",
        icon: MessageIcon::Question,
        buttons: MessageButtons::YesNo,
        owner: None,
    }
    .show()
    {
        Some(MessageResult::Yes) => {
            println!("Los geht's!");
        }
        _ => {
            println!("Okay, tschüss!");
        }
    }
}

Übung: Ja/Nein mit Turtle

Erstelle ein Programm, das:

  1. Fragt: “Möchtest du ein Quadrat sehen?”
  2. Bei Ja: Zeichnet ein Quadrat mit der Turtle
  3. Bei Nein: Gibt “Okay, bis dann!” aus

Zusammenfassung

  • TextInput { ... } fragt nach Text
  • MessageBox { ... } zeigt eine Nachricht
  • MessageButtons::YesNo fragt Ja/Nein
  • .parse() wandelt Text in Zahl um
  • Option::Some(...) bedeutet eine gültige Eingabe, None bedeutet Abbruch

Im nächsten Kapitel baust du dein erstes richtiges Spiel mit Schleifen und Eingaben!

Spielschleifen: Dein erstes Spiel

Jetzt wird es spannend! Du lernst, wie man ein richtiges Spiel programmiert: Ein Zahlenratespiel!

Was ist eine Spielschleife?

Eine Spielschleife wiederholt immer wieder:

  1. Frage den Spieler
  2. Reagiere auf die Antwort
  3. Ist das Spiel vorbei? Wenn nein, wiederhole

Das Zahlenratespiel

Wir bauen ein Spiel, bei dem der Computer sich eine Zahl zwischen 0 und 100 ausdenkt und du sie erraten musst!

Schritt 1: Die Zufallszahl

Zuerst brauchen wir eine Zufallszahl:

    let geheime_zahl = gen_range(0, 101); // 0 bis 100
    println!("Ich habe mir eine Zahl ausgedacht!");

Wichtig: Macroquad verwendet einen globalen Zufallszahlengenerator. Deshalb seedest du ihn einmal am Anfang mit dem aktuellen Zeitstempel:

use std::time::{SystemTime, UNIX_EPOCH};

macroquad::rand::srand(
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_millis() as u64,
);

Ohne diesen Aufruf bleibt der Generator beim Standardwert stehen und gen_range(0, 101) liefert immer wieder 0.

Schritt 2: Nach einer Zahl fragen

Jetzt fragen wir den Spieler:

    let eingabe = TextInput {
        title: "Ratespiel",
        message: "Rate die Zahl (0-100):",
        value: "",
        mode: TextInputMode::SingleLine,
        owner: None,
    }
    .show()
    .unwrap();

    let tipp: i32 = eingabe.parse().unwrap();

    println!("Du hast {} geraten", tipp);

Schritt 3: Prüfen, ob richtig

Jetzt vergleichen wir:

    if tipp == geheime_zahl {
        println!("Richtig!");
    } else if tipp < geheime_zahl {
        println!("Zu klein!");
    } else {
        println!("Zu groß!");
    }

Schritt 4: Die Schleife

Eine Schleife wiederholt einen Block wieder und wieder. Genau das brauchen wir für ein Ratespiel: Solange der Spieler falsch liegt, soll das Programm erneut fragen.

Erst eine einfache Schleife

loop {
    println!("Noch ein Durchlauf!");
    break;
}

loop { ... } startet eine Endlosschleife. break; beendet sie sofort wieder. Ohne break würde das Programm für immer weiterlaufen.

Jetzt mit Zähler

let mut versuche = 0;

loop {
    versuche += 1;
    println!("Versuch {}", versuche);

    if versuche == 3 {
        break;
    }
}

Was passiert hier?

  1. let mut versuche = 0; erstellt einen Zähler
  2. In jedem Durchlauf wird versuche += 1; ausgeführt
  3. println!(...) zeigt den aktuellen Versuch an
  4. if versuche == 3 { break; } beendet die Schleife nach 3 Versuchen

Das ist die Grundidee der Spielschleife: Zähle mit, mache etwas, prüfe, ob das Spiel vorbei ist.

Jetzt mit Tipp und Vergleich

Als Nächstes ersetzen wir nur den println! durch eine echte Prüfung:

let mut versuche = 0;
let geheime_zahl = 42;

loop {
    versuche += 1;

    let tipp = 10; // später wird hier die Eingabe stehen
    println!("Dein Tipp: {}", tipp);

    if tipp == geheime_zahl {
        println!("Richtig!");
        break;
    } else if tipp < geheime_zahl {
        println!("Zu klein!");
    } else {
        println!("Zu groß!");
    }
}

Jetzt sieht die Schleife schon sehr nach einem Ratespiel aus:

  • Frage nach einer Zahl
  • Vergleiche den Tipp mit der geheimen Zahl
  • Wenn falsch: gib eine Meldung aus
  • Wenn richtig: break und Spiel ist beendet

Du musst jetzt nur noch die feste Zahl let tipp = 10; durch die echte Benutzereingabe ersetzen. Genau das macht die nächste Übung!

Dialoge in der Schleife

Jetzt kommt der letzte wichtige Schritt: In einer echten Spielschleife fragt das Programm nicht mit einer festen Zahl, sondern mit einem Dialogfenster nach der Eingabe des Spielers.

let mut versuche = 0;
let geheime_zahl = 42;

loop {
    versuche += 1;

    let eingabe = rustydialogs::TextInput {
        title: "Dein Tipp",
        message: "Rate die Zahl (0-100):",
        value: "",
        mode: rustydialogs::TextInputMode::SingleLine,
        owner: None,
    }
    .show();

    let tipp = match eingabe {
        Some(text) => text.parse::<i32>().unwrap(),
        None => break,
    };

    if tipp == geheime_zahl {
        println!("Richtig!");
        break;
    } else if tipp < geheime_zahl {
        println!("Zu klein!");
    } else {
        println!("Zu groß!");
    }
}

Schritt für Schritt:

  1. TextInput { ... } zeigt einen Dialog an
  2. .show() liefert den eingegebenen Text oder None, wenn der Spieler abbricht
  3. text.parse::<i32>() wandelt den Text in eine Zahl um
  4. Danach prüft das Programm mit if/else if wieder, ob die Zahl richtig ist
  5. Wenn nicht, läuft die Schleife erneut und fragt erneut

Damit hast du das Muster der Spielschleife mit echten Dialogen verstanden. Jetzt kannst du daraus das komplette Zahlenratespiel bauen.

Dialog für richtig geraten

Jetzt kannst du natürlich das Spiel weiter ausbauen. Zum Beispiel kannst du einen Dialog anzeigen, wenn der Spieler richtig geraten hat.

        if tipp == geheime_zahl {
            let message = format!(
                "🎉 Richtig!\n\nDie Zahl war {}!\nDu hast {} Versuche gebraucht.",
                geheime_zahl, versuche
            );
            let _ = MessageBox {
                title: "Gewonnen!",
                message: &message,
                icon: MessageIcon::Info,
                buttons: MessageButtons::Ok,
                owner: None,
            }
            .show();
            break;
        } else if tipp < geheime_zahl {

Übung: Eigene Verbesserungen

Verändere das Spiel:

  • Ändere den Zahlenbereich (z.B. 1-50)
  • Verwende auch für die Antworten Dialog-Fenster
  • Füge eine Willkommensnachricht am Anfang hinzu
  • Füge auch eine Endnachricht hinzu
  • Schwieriger: Füge wenn man gewonnen hat die möglichkeit neu zu starten hinzu
  • Schwieriger: Zeige nach jedem Gewinn einen Highscore an

Zusammenfassung

  • loop { } ist eine Endlosschleife
  • break verlässt die Schleife
  • macroquad::rand::srand(...) initialisiert den Zufallszahlengenerator einmal am Anfang
  • gen_range(a, b) gibt eine Zufallszahl
  • unwrap() holt den Wert heraus
  • Mit if-else reagierst du auf verschiedene Situationen

Glückwunsch! Du hast dein erstes richtiges Spiel programmiert! 🎉

Im nächsten Teil des Kurses lernst du fortgeschrittenere Konzepte, um noch komplexere Spiele wie Hangman zu bauen.

Mehr über Daten

Bis jetzt hast du bereits mit Zahlen, Text und einfachen Befehlen gearbeitet. Jetzt kommt ein wichtiges Grundprinzip der Programmierung: jedes Stück Daten hat einen Datentyp.

Was ist ein Datentyp?

Ein Datentyp beschreibt, welche Art von Information ein Wert ist. Er sagt dem Computer zum Beispiel:

  • ist das etwas mit Zahlen?
  • ist das Text?
  • ist das wahr oder falsch?
  • ist das eine Liste von Dingen?

Stell dir Datentypen wie Etiketten auf Gegenständen vor:

  • 12 ist eine Zahl
  • 3.14 ist eine Zahl mit Komma
  • "Hallo" ist Text
  • true ist ein Wahrheitswert

Rust ist eine starke, statische Sprache. Das heißt: Der Typ eines Werts wird meistens von Rust erkannt und überprüft. Dadurch werden viele Fehler schon vorher entdeckt.

Warum brauchen wir Datentypen?

Datentypen helfen dem Computer, zu verstehen, was du tun willst.

Der Computer speichert Daten im Endeffekt nur als Nullen und Einsen. Ein einzelnes Byte ist 8 Bits, zum Beispiel:

01000001

Diese Bitfolge kann auf verschiedene Weise interpretiert werden:

  • als ASCII-Buchstabe: A
  • als Zahl vom Typ u8: 65

Das Wichtigste ist: Die Bits sind gleich, aber der Datentyp sagt dem Computer, wie er sie lesen soll.

Ohne Datentypen könnte der Computer nicht wissen, ob 01000001 ein Buchstabe, eine Zahl oder ein Teil einer Kommazahl ist.

let alter = 12;
let preis = 9.99;
let ist_aktiv = true;
let name = "Anna";

Diese Werte sind alle unterschiedlich:

  • alter ist eine ganze Zahl
  • preis ist eine Komman-Zahl mit Nachkommastellen
  • ist_aktiv ist ein Wahrheitswert (true oder false)
  • name ist Text, also mehrere Buchstaben hintereinander.

Rust erkennt Typen oft automatisch

In vielen Fällen musst du den Typ nicht selbst schreiben:

let zahl = 42;
let text = "Hallo";

Rust erkennt automatisch, dass 42 eine Zahl ist und "Hallo" Text.

Manchmal willst du aber den Typ bewusst festlegen, zum Beispiel wenn du ein bestimmtes Verhalten brauchst:

let alter: u32 = 12;
let preis: f64 = 9.99;

Das u32 und f64 sind Typen aus Rust. Du wirst sie später noch genauer kennenlernen.

Ein wichtiger Gedanke

Datentypen sind die Grundlage dafür, dass Programme zuverlässig funktionieren. Sie helfen dabei, Daten sauber zu speichern und zu verarbeiten.

Einige typische Datentypen, die du später kennen wirst, sind:

  • Text: Strings
  • Liste von Werten: Sammlungen
  • zusammengesetzte Daten: Structs
  • verschiedene Zustände: Enums

Zusammenfassung

  • Jeder Wert hat einen Datentyp
  • Der Datentyp sagt, welche Art von Daten gespeichert werden
  • Rust prüft Typen oft automatisch
  • Datentypen verhindern viele Fehler

In den nächsten Kapiteln lernst du die wichtigsten Datentypen in Rust genauer kennen: Strings, Sammlungen, Structs und Enums.

Strings und Text

In den bisherigen Kapiteln hast du mit Zahlen und Grafiken gearbeitet. Jetzt lernst du, wie man mit Text arbeitet. Text brauchst du für Namen, Nachrichten oder Wörter in Spielen.

Was ist ein String?

Ein String ist einfach Text – eine Folge von Buchstaben und Zeichen.

let name = "Anna";
let wort = "Schildkröte";

Text steht immer in Anführungszeichen "...".

Text mit der Turtle anzeigen

Probier das aus:

    let name = "Max";
    println!("Hallo, {}!", name);

    turtle.write_text(name, 50.0);

Das {} ist ein Platzhalter für den Text aus der Variable name.

Übung: Dein Name

Ändere den Code so, dass dein eigener Name ausgegeben wird!

Text zusammenfügen

Du kannst Text kombinieren:

let vorname = "Anna";
let nachname = "Müller";
let ganzer_name = format!("{} {}", vorname, nachname);
turtle.write_text(ganzer_name, 50.0);  // Gibt aus: Anna Müller

Text vergleichen

Um zu prüfen, ob zwei Texte gleich sind, verwendest du ==:

let wort1 = "Katze";
let wort2 = "Katze";

if wort1 == wort2 {
    turtle.write_text("Die Wörter sind gleich!", 50.0);
}

Wichtig: "Katze" ist nicht gleich "katze" – Groß-/Kleinschreibung zählt!

Übung: Turtle mit deinem Namen

Erstelle ein Programm, das:

  1. Deinen Namen in einer Variable speichert
  2. “Hallo, [dein Name]!” schreibt
  3. Ein Quadrat mit der Turtle und dabei auf jeder Seite “Hallo, [dein Name]!” schreibt.
Tipp
    let name = "..."; // Dein Name hier

    // Zeichne ein Quadrat
    for _ in 0..4 {
        turtle.write_text(&format!("Hallo, {}!", name), 30.0);
        turtle.forward(200.0);
        turtle.right(90.0);
    }

Zusammenfassung

  • Text steht in Anführungszeichen: "Hallo"
  • Mit {} kannst du Text einfügen
  • Mit == vergleichst du Text
  • Text kann in Variablen gespeichert werden

Im nächsten Kapitel lernst du, wie man mehrere Werte in Listen speichert!

Sammlungen: Listen

Im letzten Kapitel hast du gelernt, wie man einen Text speichert. Aber was, wenn du mehrere Wörter oder Zahlen speichern möchtest? Dafür gibt es Listen!

Was ist eine Liste?

Eine Liste ist wie eine Reihe von Schubladen, in denen du mehrere Werte aufbewahren kannst.

In Rust heißt eine Liste Vec (kurz für “Vektor”):

let zahlen = vec![10, 20, 30, 40];

Eine Liste erstellen

So erstellst du eine Liste:

let farben = vec!["Rot", "Grün", "Blau"];
  • vec! erstellt eine neue Liste
  • Die Werte stehen in eckigen Klammern []
  • Die Werte werden mit Komma getrennt

Auf Elemente zugreifen

Jedes Element in der Liste hat eine Nummer (Index). Die Zählung beginnt bei 0!

let tiere = vec!["Hund", "Katze", "Vogel"];

turtle.write_text(tiere[0], 50.0);  // Gibt aus: Hund
turtle.write_text(tiere[1], 50.0);  // Gibt aus: Katze
turtle.write_text(tiere[2], 50.0);  // Gibt aus: Vogel

Übung: Turtle mit Farben

Probier dieses Programm aus:

    let farben = vec![RED, GREEN, BLUE];
    for farbe in &farben {
        turtle.set_pen_color(*farbe);
        turtle.forward(100.0);
        turtle.right(120.0);
    }

Was zeichnet das Programm? Ändere die Farben und probiere es aus!

Durch eine Liste gehen

Mit einer for-Schleife kannst du alle Elemente durchgehen:

let zahlen = vec![5, 10, 15];

for zahl in &zahlen {
    turtle.write_text(&zahl.to_string(), 50.0);
}

Das gibt aus:

5
10
15

Übung: Mehrere Quadrate

Erstelle ein Programm, das:

  • Eine Liste mit Größen hat: vec![30.0, 50.0, 70.0]
  • Für jede Größe ein Quadrat zeichnet
  • Die Turtle zwischen den Quadraten bewegt
Tipp
    let groessen = vec![30.0, 50.0, 70.0];
    
    for groesse in &groessen {
        // Zeichne ein Quadrat
        for _ in 0..4 {
            turtle.forward(*groesse);  // Das * holt den Wert
            turtle.right(90.0);
        }
        // Bewege dich nach rechts
        turtle.pen_up();
        turtle.forward(groesse + 20.0);
        turtle.pen_down();
    }

Zusammenfassung

  • Listen speichern mehrere Werte: vec![1, 2, 3]
  • Index beginnt bei 0: liste[0] ist das erste Element
  • for element in &liste geht durch alle Elemente
  • Listen sind praktisch für mehrere gleiche Dinge

Im nächsten Kapitel lernst du Structs – damit kannst du zusammengehörige Daten gruppieren!

Strukturen (Structs)

Du kannst jetzt einzelne Werte und Listen speichern. Aber was, wenn zusammengehörige Dinge eine Einheit bilden sollen? Dafür gibt es Structs!

Was ist ein Struct?

Ein Struct ist wie eine Karteikarte mit mehreren Feldern. Zum Beispiel für eine Person:

┌─────────────────┐
│ Name:   Anna    │
│ Alter:  12      │
│ Stadt:  Berlin  │
└─────────────────┘

Einen Struct definieren

So erstellst du einen eigenen Datentyp:

struct Person {
    name: String,
    alter: u32,
}
  • struct bedeutet “Struktur”
  • Person ist der Name (groß geschrieben!)
  • Die Felder stehen in geschweiften Klammern

Einen Struct verwenden

So erstellst du eine Person:

let person = Person {
    name: String::from("Max"),
    alter: 12,
};

turtle.write_text(&format!("Name: {}", person.name), 50.0);
turtle.write_text(&format!("Alter: {}", person.alter), 50.0);

Mit dem Punkt . greifst du auf die Felder zu.

Übung: Rechteck mit Struct

Probier dieses Beispiel aus:

    let rechteck = Rechteck {
        breite: 100.0,
        hoehe: 60.0,
    };
    
    // Zeichne das Rechteck
    for _ in 0..2 {
        turtle.forward(rechteck.breite);
        turtle.right(90.0);
        turtle.forward(rechteck.hoehe);
        turtle.right(90.0);
    }

Ändere die Breite und Höhe und schau, was passiert!

Mehrere Structs

Du kannst mehrere Rechtecke erstellen:

let rechteck1 = Rechteck { breite: 80.0, hoehe: 40.0 };
let rechteck2 = Rechteck { breite: 120.0, hoehe: 60.0 };

Übung: Drei Rechtecke

Erstelle ein Programm, das:

  • Drei verschiedene Rechtecke definiert
  • Alle drei nacheinander zeichnet
  • Die Turtle dazwischen bewegt
Lösung (nur anschauen, wenn du nicht weiterkommst!)
    let rechtecke = vec![
        Rechteck { breite: 50.0, hoehe: 30.0 },
        Rechteck { breite: 70.0, hoehe: 40.0 },
        Rechteck { breite: 90.0, hoehe: 50.0 },
    ];
    
    for rechteck in &rechtecke {
        // Zeichne Rechteck
        for _ in 0..2 {
            turtle.forward(rechteck.breite);
            turtle.right(90.0);
            turtle.forward(rechteck.hoehe);
            turtle.right(90.0);
        }
        
        // Bewege nach rechts
        turtle.pen_up();
        turtle.forward(rechteck.breite + 20.0);
        turtle.pen_down();
    }

Zusammenfassung

  • Structs gruppieren zusammengehörige Daten
  • Definition: struct Name { feld: Typ, ... }
  • Verwendung: instanz.feld
  • Structs machen Code übersichtlicher

Im nächsten Kapitel lernst du Enums – für Dinge, die verschiedene Zustände haben können!

Enums und Zustände

Du kennst jetzt Structs für zusammengehörige Daten. Aber was, wenn etwas verschiedene Zustände haben kann? Dafür gibt es Enums!

Was ist ein Enum?

Ein Enum (Aufzählung) definiert, welche Möglichkeiten es gibt. Zum Beispiel eine Ampel:

enum Ampel {
    Rot,
    Gelb,
    Gruen,
}

Eine Ampel ist entweder rot oder gelb oder grün – aber niemals zwei gleichzeitig!

Einen Enum verwenden

So verwendest du einen Enum:

let farbe = Ampel::Rot;

Mit match kannst du auf verschiedene Werte reagieren:

match farbe {
    Ampel::Rot => turtle.write_text("Stopp!", 50.0),
    Ampel::Gelb => turtle.write_text("Achtung!", 50.0),
    Ampel::Gruen => turtle.write_text("Fahr!", 50.0),
}

Übung: Turtle mit Richtung

Probier dieses Beispiel:

    let richtung = Richtung::Rechts;

    match richtung {
        Richtung::Oben => turtle.left(90.0),
        Richtung::Rechts => turtle.right(0.0),
        Richtung::Unten => turtle.right(90.0),
        Richtung::Links => turtle.right(180.0),
    };

    turtle.forward(100.0);

Ändere die Richtung und schau, was passiert!

Enum für Spielzustand

Enums sind perfekt für Spielzustände:

enum Spielstand {
    Laeuft,
    Gewonnen,
    Verloren,
}

let zustand = Spielstand::Laeuft;

match zustand {
    Spielstand::Laeuft => turtle.write_text("Spiel läuft noch...", 50.0),
    Spielstand::Gewonnen => turtle.write_text("Du hast gewonnen! 🎉", 50.0),
    Spielstand::Verloren => turtle.write_text("Verloren 💀", 50.0),
}

Übung: Turtle-Quadrat mit Farbe

Erstelle ein Programm, das:

  • Einen Enum Farbe mit Rot, Gruen, Blau hat
  • Je nach gewählter Farbe ein Quadrat in dieser Farbe zeichnet
Tipp
    let farbe = Farbe::Gruen;  // Ändere das!
    
    match farbe {
        Farbe::Rot => turtle.set_pen_color(RED),
        Farbe::Gruen => turtle.set_pen_color(GREEN),
        Farbe::Blau => turtle.set_pen_color(BLUE),
    };
    
    // Zeichne Quadrat
    for _ in 0..4 {
        turtle.forward(80.0);
        turtle.right(90.0);
    }

Zusammenfassung

  • Enums definieren Auswahlmöglichkeiten
  • Definition: enum Name { Variante1, Variante2, ... }
  • Verwendung: Name::Variante
  • match reagiert auf verschiedene Varianten
  • Perfekt für Zustände (Ampel, Spielstand, Richtung)

Du hast jetzt wichtige Grundlagen: Text, Listen, Structs und Enums. Im nächsten Kapitel lernst du, wie der Benutzer selbst Eingaben machen kann!

Anhang: VS Code installieren (optional)

Zed ist der empfohlene Editor für diese Anleitung. Wenn du lieber mit VS Code arbeitest, kannst du hier die Einrichtung nachlesen.

Warum VS Code?

Visual Studio Code (kurz: VS Code) ist ein kostenloser und sehr beliebter Editor für Programmieren. Er ist leicht zu benutzen und unterstützt Rust gut mit Erweiterungen.

Schritt 1: VS Code installieren

  1. Gehe zu https://code.visualstudio.com/
  2. Lade VS Code für dein Betriebssystem herunter
  3. Installiere das Programm
  4. Starte VS Code

Schritt 2: Wichtige Erweiterungen installieren

Erweiterungen sind wie Apps für VS Code – sie fügen nützliche Funktionen hinzu. Für Rust brauchen wir zwei wichtige Erweiterungen:

rust-analyzer

Diese Erweiterung hilft dir beim Schreiben von Rust-Code. Sie zeigt Fehler an, schlägt Code vor und erklärt Befehle.

Installation:

  1. Klicke in VS Code auf das Erweiterungs-Symbol in der linken Leiste (vier Quadrate)
  2. Suche nach rust-analyzer
  3. Klicke auf “Installieren”

CodeLLDB

Diese Erweiterung ermöglicht es, deine Programme zu starten und zu testen.

Installation:

  1. Suche im Erweiterungs-Bereich nach CodeLLDB
  2. Klicke auf “Installieren”

Projekt in VS Code öffnen

Wenn du ein Projekt starten möchtest:

  1. Öffne VS Code
  2. Klicke auf Datei → Ordner öffnen
  3. Wähle dein Rust-Projekt aus
  4. VS Code lädt die Dateien und zeigt dir die Rust-Hilfen an

Häufige Probleme

“rust-analyzer funktioniert nicht”

  • Stelle sicher, dass Rust richtig installiert ist (cargo --version im Terminal)
  • Starte VS Code neu
  • Öffne den Ordner über “Datei → Ordner öffnen” (nicht nur einzelne Dateien)

“Das Programm kompiliert nicht”

  • Überprüfe, ob Cargo.toml die richtigen Abhängigkeiten hat
  • Schau dir die Fehlermeldungen im Terminal genau an
  • rust-analyzer zeigt Fehler auch im Editor mit roten Wellenlinien an

“Das Fenster öffnet sich nicht”

  • Warte einen Moment – beim ersten Mal dauert es länger
  • Schau ins Terminal, ob Fehlermeldungen auftauchen

Fazit

VS Code ist ein gutes Alternativ-Setup, aber für diese Anleitung ist Zed der bevorzugte Editor. Wenn du also mit dem empfohlenen Setup starten willst, kannst du direkt zu Kapitel 0 zurückkehren.