CS_LEVEL_18_SOLUTION - OnlyCook/abitur-elite-code GitHub Wiki

Level 18 – Musterlösung: Die Sicherheitsschleuse (System-Integration)

Lösung

public class Rover
{
    private static int autowert = 0;
    private int fahrzeugNr;
    private string id;
 
    public Rover(string id)
    {
        this.id = id;
        this.fahrzeugNr = ++autowert;
    }
 
    public int GetFahrzeugNr()
    {
        return fahrzeugNr;
    }
 
    public void Unlock() { }
    public void Lock() { }
}
 
public class Controller
{
    private Rover rover;
    private RFIDReader reader;
    private Serial serial;
    private FunkModul funk;
 
    public Controller(string port, Rover r)
    {
        this.rover = r;
        this.serial = new Serial(port, 9600, 8, 1, 0);
        this.reader = new RFIDReader(serial);
        this.funk = new FunkModul();
    }
 
    public void Run()
    {
        while (true)
        {
            if (reader.IsCardAvailable())
            {
                string id = reader.ReadCard();
                if (id != "")
                {
                    funk.Send($"UNLOCK {rover.GetFahrzeugNr()} {id}");
                    if (funk.Receive() == 0x06)
                    {
                        rover.Unlock();
                    }
                }
            }
        }
    }
}

Erklärung

Der statische Autowert

Das Neue an der Rover-Klasse ist der statische Zähler zur automatischen Vergabe der Fahrzeugnummer:

private static int autowert = 0;

Ein static-Attribut gehört nicht zu einem einzelnen Objekt, sondern zur Klasse selbst. Alle Rover-Instanzen teilen sich denselben autowert. Jedes Mal, wenn ein neuer Rover erzeugt wird, wird der Zähler um 1 erhöht – und genau dieser erhöhte Wert wird als Fahrzeugnummer gespeichert:

this.fahrzeugNr = ++autowert;

Das ++ vor der Variable ist entscheidend: Pre-Inkrement erhöht autowert zuerst und gibt dann den neuen Wert zurück. Der erste Rover bekommt also fahrzeugNr = 1, der zweite 2, und so weiter. Mit Post-Inkrement (autowert++) würde der erste Rover die 0 bekommen – falsch.

Im Abitur taucht dieses Muster regelmäßig auf. Sobald du static int autowert = 0 im Klassendiagramm siehst, ist ++autowert im Konstruktor die erwartete Lösung.


Der Controller-Konstruktor – Objekte intern erstellen

public Controller(string port, Rover r)
{
    this.rover = r;
    this.serial = new Serial(port, 9600, 8, 1, 0);
    this.reader = new RFIDReader(serial);
    this.funk = new FunkModul();
}

Der Rover wird von außen übergeben, alle anderen Abhängigkeiten werden intern erstellt. Die Reihenfolge ist dabei wichtig: serial muss vor reader erstellt werden, weil RFIDReader das serial-Objekt im Konstruktor erwartet. Das serial-Objekt öffnet sich dann automatisch im RFIDReader-Konstruktor – genau so, wie wir es in Level 17 implementiert haben.

Die Parameter für Serial stehen im Material: 9600 Baud, 8 Datenbits, 1 Stoppbit, 0 für kein Paritätsbit.


Run() – die Endlosschleife

while (true)
{
    if (reader.IsCardAvailable())
    {
        string id = reader.ReadCard();
        if (id != "")
        {
            funk.Send($"UNLOCK {rover.GetFahrzeugNr()} {id}");
            if (funk.Receive() == 0x06)
            {
                rover.Unlock();
            }
        }
    }
}

while (true) ist die klassische Endlosschleife – sie läuft so lange, bis das Programm von außen beendet wird. Im Abitur steht das oft für den Dauerbetrieb eines eingebetteten Systems.

Der Ablauf folgt einer klaren Kette:

  1. Erst prüfen, ob überhaupt eine Karte da ist (IsCardAvailable()).
  2. Karte auslesen – gibt ReadCard() einen Leerstring zurück, war das Paket ungültig, also nichts tun.
  3. Ist die ID gültig, den Funk-Befehl senden: "UNLOCK <FahrzeugNr> <CardID>" – String-Interpolation mit $ wie bekannt.
  4. Auf das ACK-Byte 0x06 warten: Erst wenn das Funkmodul mit ACK antwortet, wird rover.Unlock() aufgerufen. Das ist eine einfache Quittierung – der Rover wird nur freigegeben, wenn die Gegenstelle bestätigt hat.

Diese Struktur – prüfen, lesen, validieren, handeln – ist ein typisches Muster für Hardware-nahe Kommunikation im Abitur.

⚠️ **GitHub.com Fallback** ⚠️