Andreas Kirsch
Aufgabe 5 "Die Paderbox"

1. Lösungsidee
==============

Dazu lässt sich eigentlich nur sagen, dass die Angaben 1:1 umgesetzt werden sollen.
Es gibt nur 2 Dinge, die geklärt werden müssen:
1. Wie wird ein ganzahliger Zufallswert zwischen 0 und r_max am besten auf eine ganze Zahl zwischen min und max (beide eingeschlossen) abgebildet?
2. Wie verbindet man die Lampen mit den Zuständen und umgekehrt?

Zu 1:
Am einfachsten ist der Modulo-Ansatz: r % (max - min + 1) + min, der auch, wie man mit TestGetRandom() sehen kann, eine beinahe perfekte Verteilung bietet.

Zu 2:
Jede Lampe ist mit genau 2 Zuständen verbunden und jeder Zustand ist mit genau 2 Lampen verbunden, es ist also eine bidirektionale Verbindung und es reicht für alle Zustände anzugeben mit welchen Lampen sie verbunden sind, um die Umkehrung zu bestimmen.
Der erste Zustand kann sich aus den 3 Lampen frei 2 aussuchen, der zweite dagegen muss die andere, noch freie Lampe wählen und dann eine von den beiden Lampen des 1. Zustandes, da sonst der 3. Zustand nur 1 Lampe zur Auswahl hätte und der 3. Zustand muss dann einfach die letzten beiden freien Verbindungen nehmen, wobei er die eine Verbindung mit dem 1., die andere mit dem 2. Zustand gemein hat.
Beispiel, wieso der 2. Zustand nur 1 Lampe freiwählen darf:
Zustand 1 -> Lampe 1, Lampe 2
Zustand 2 -> Lampe 1, Lampe 2 (!)
=> Zustand 3 -> Lampe 3 (Widerspruch: es kann keine 2. Verbindung gefunden werden!)
Beispiel für das oben beschriebenes Vorgehen:
Zustand 1 -> Lampe 1, Lampe 3
Zustand 2 -> Lampe 1 oder 3, Lampe 2
Zustand 3 -> Lampe 3 oder 1, Lampe 2

2. Programm-Dokumentation
=========================

Das Programm besteht eigentlich aus 2 Einheiten: einerseits der Paderbox-Klasse, die das Verhalten einer Paderbox beschreibt und die zufällige Initialisierung durchführt, andererseits das Hauptprogramm, das dem Benutzer simple Konsolen-Menüs zur Verfügung stellt um das Spiel zu starten und die Paderbox zu bedienen.
Das einzige interessante ist die Initialisierung, die aber genauso umgesetzt wird, wie in der Lösungsidee beschrieben aber etwas gestraffter ist.
Für die Wahl der zweiten Lampe des 1. Zustandes, verwende ich folgenden Code:
do {
	stateLampLinks[ 0 ][ 1 ] = GetRandom( 0, LAMP_COUNT - 1 );
} while( stateLampLinks[ 0 ][ 0 ] == stateLampLinks[ 0 ][ 1 ] );
Die Frage ist, ob dadurch die Schleife die Wahrscheinlichkeit der gewählten Lampe irgendwie beeinflusst wird, die 1/2 betragen sollte, das ja eine Lampe wegfällt.
Die Wahrscheinlichkeit, das eine der beiden Lampen gewählt wird, sollte 1/2 betragen und für den Quellcode beträgt die Wahrscheinlichkeit: 1/2 + 1/3 * 1/2 + (1/3)^2 * 1/2 + ... =
limit for n->infinity { sum from i = 0 to n of { 1/2 * (1/3)^i }} = 1/2 limit for n -> infinity { sum from i = 0 to n of { (1/3)^i }} = 1/2 * 1 over { 1 - 1 / 3 } = 1/2*3/2 = 1/2 und damit korrekt.

Das Programm ist eine einfache Konsolen-Applikation, erlaubt aber trotzdem das Tüffteln an der Geheimprogrammierung, und ist möglicherweise sogar übersichtlicher als eine grafische Anwendung, da man immer die alten Lampenzustände vor Augen hat und sich dadurch weniger merken muss.

3. Programm-Ablaufprotokoll
===========================
[...]>"Aufgabe 5.exe"

P Starte ein Spiel
Q Ende des Programms

Menüwahl: p
Spiel startet..

Lampe 1: AN Lampe 2: AN Lampe 3: AN
0 Drücke Taste 0
1 Drücke Taste 1
R Setze die PaderBox zurück
? Verrate die Programmierung
Q Gehe zurück zum Hauptmenü

Menüwahl: 0
Lampe 1: AUS Lampe 2: AUS Lampe 3: AN
0 Drücke Taste 0
1 Drücke Taste 1
R Setze die PaderBox zurück
? Verrate die Programmierung
Q Gehe zurück zum Hauptmenü

Menüwahl: 0
Lampe 1: AN Lampe 2: AN Lampe 3: AN
0 Drücke Taste 0
1 Drücke Taste 1
R Setze die PaderBox zurück
? Verrate die Programmierung
Q Gehe zurück zum Hauptmenü

Menüwahl: 1
Lampe 1: AUS Lampe 2: AN Lampe 3: AUS
0 Drücke Taste 0
1 Drücke Taste 1
R Setze die PaderBox zurück
? Verrate die Programmierung
Q Gehe zurück zum Hauptmenü

Menüwahl: r
Lampe 1: AN Lampe 2: AN Lampe 3: AN
0 Drücke Taste 0
1 Drücke Taste 1
R Setze die PaderBox zurück
? Verrate die Programmierung
Q Gehe zurück zum Hauptmenü

Menüwahl: ?
Taste 0         Taste 1 (Z steht für Zustand)
Z1->Z1          Z1->Z3
Z2->Z1          Z2->Z1
Z3->Z1          Z3->Z2

Zustand         Lampen
Z1              Lampe 2, Lampe 1
Z2              Lampe 2, Lampe 3
Z3              Lampe 1, Lampe 3

Anfangszustand: Z1
Lampe 1: AN Lampe 2: AN Lampe 3: AN
0 Drücke Taste 0
1 Drücke Taste 1
R Setze die PaderBox zurück
? Verrate die Programmierung
Q Gehe zurück zum Hauptmenü

Menüwahl: q

P Starte ein Spiel
Q Ende des Programms

Menüwahl: q
