Aufgaben zum Praktikum C++ für Computerspielentwickler
Funktionen
Erstelle eine bzw. mehrere Funktionen zum sicheren Vergleich zweier Fließkommazahlen.
- Die Funktion soll für die Datentypen float und double einsetzbar sein und für beide Datentypen den gleichen Namen haben!
- Der Funktion soll ein treshold übergeben werden, der bestimmt, bei welcher Differenz der zu vergleichenden Fließkommazahlen trotzdem von einer Gleichheit ausgegangen wird. Für diesen Parameter soll ein Standardwert angegeben werden, der in der Datei stdafx.h definiert wird.
- Die Funktion soll 'true' liefern, wenn beide Zahlen gleich innerhalb des vorgegebenen Tresholds sind.
Spiel Zahlenraten
- Im Spiel Zahlenraten denkt sich das Programm eine Zahl aus, die der Spieler erraten soll
- Verwende für das Programm precompiled header
- Einfache Begrüßung des Spielers
- Spieler gibt gewünschten Schwierigkeitsgrad an (zB.:)
- leicht: Bereich 1 – 10
- mittel: Bereich 1 – 50
- schwer: Bereich 1 – 500
- Ermittlung der Zufallszahl
- Spieler rät (Eingabe über die Konsole), bis er die Zahl gefunden hat
- Hinweis geben, ob geratene Zahl größer oder kleiner als die gesuchte Zahl
- Verabschiedung mit Angabe der Anzahl der Versuche
Sortiere und Finde
Hinweis: Auch wenn Parameter an eine Funktion nur by value übergeben werden können, kann man den Inhalt eines als Parameter übergebenen statischen Arrays ändern. (Warum das so ist, dazu kommen wir später)
Testarray erzeugen
- Erstelle ein statisches Array vom Typ int mit 100 Elementen und fülle es mit Zufallszahlen
- Gib das Array auf der Konsole aus (je 10 Werte pro Zeile, durch Tabulator getrennt)
Array sortieren
- Ordne die Elemente des Arrays in aufsteigender Reihenfolge. Benutze dazu den Sortieralgorithmus «Sortieren durch Auswählen» (Selection Sort)
- Gib das Array auf der Konsole aus (je 10 Werte pro Zeile, durch Tabulator getrennt)
Element finden
- Frage vom Benutzer die zu findende Zahl ab
- Suche diese Zahl im Array mittels binärer Suche
- Gib die Position der Zahl im Array aus, sowie den Wert von Vorgänger und Nachfolger
- Sollte die Zahl nicht im Array vorhanden sein, gib die Positionen und Werte der beiden Elemente aus, zwischen denen die gesuchte Zahl stehen würde.
Pointer
Aus alt mach Pointer
- Stelle die bisherigen Übungs- und Beispielaufgaben so um, dass diese anstatt mit normalen Variablen mit Pointern arbeiten
Unterschiedlich sortieren
- Implementiere zur Übungsaufgabe Sortiere und Finde zusätzlich zum Selection Sort Algorithmus folgende Sortieralgorithmen
- Bubblesort
- Shellsort
- Quicksort
- Mergesort
- Ändere das Programm Sortiere und Finde so ab, dass der Benutzer auswählen kann, welchen Sortieralgorithmus er verwendet
- Verwende anstelle von primitiven Variablen Pointer
Verkettete Listen
- Erstelle mittels struct eine Datenstruktur, die als Element für (doppelt) verkettete Listen dienen soll. Die in der Liste zu speichernden Daten sollen dabei vom Typ int32 sein.
- Erstelle folgende Funktionalitäten für die verkettete Liste
- Hinzufügen eines Elementes in die Liste
- Entfernen eines Elementes aus der Liste
- Ordnen der Liste mittels Merge-Sort
- Füge eine Reihe zufälliger, ungeordneter Zahlen so in die verkettete Liste ein, dass diese sortiert ist
- Teile die verkettete Liste in zwei verkettete Listen, so dass in der ersten Liste alle geradzahligen Elemente und in der zweiten Liste alle ungeraden Elemente sind.
- Mische beide Liste, so dass die gemischte Liste wieder geordnet ist
- Erstelle eine verkettete Liste mit 1000 zufälligen, ungeordneten Elementen. Ordne diese Liste per Mergesort.
Weihnachtsaufgaben zum Praktikum C++ für Computerspielentwickler
Um auch über Weihnachten eure C+±Kenntnisse stetig zu verbessern, gibt es hier ein paar Übungsaufgaben, die ihr über die Feiertage lösen könnt.
15-puzzle
Beim 15-puzzle müssen 15 in einem Vier-mal-vier-Quadrat angeordneten Zahlen durch Verschiebungen aufsteigend geordnet werden. (siehe auch Wikipedia )
Die Darstellung des Spielfeldes soll dabei in folgender Form geschehen (Im Bild die Gewinnstellung). Bei Spielstart ist das Puzzlespiel in zufälliger Reihenfolge der Zahlen zu initialisieren. Achtet dabei darauf, dass die Lösbarkeit des Puzzles sichergestellt werden muss! Der Spieler kann nun einen Spielstein verschieben, indem er Spalte (a-d) und Zeile (1–4) des zu verschiebenden Spielsteines angibt. Dies wiederholt sich solange, bis die Siegstellung erreicht wurde, oder der Spieler das Spiel abbricht. Der Spieler soll ebenfalls die Möglichkeit bekommen, per Tastendruck eine Hilfestellung über alle ihm möglichen Eingaben zu erhalten.
Hat der Spieler die Siegstellung erreicht, wird ihm gratuliert und die Anzahl der benötigten Züge ausgegeben. Diese sollten ebenfalls qualitativ (super schnell, gut, mittelmäßig, lahm ...) bewertet werden. (Die Zuordnung dieser Attribute zur Anzahl der Züge bleibt dabei euch überlassen)
Ring-Puffer
Ein Ringpuffer ist eine Warteschlange mit Fi Fo- Prinzip und fester Größe. Es soll eine Klasse erstellt werden, die einen Ringpuffer implementiert. Um nicht für jeden Typ von zu speichernden Elementen den Ring-Puffer neu erfinden zu müssen, soll dabei so viel wie möglich Funktionalität in eine Basisklasse gelegt werden, von der dann die datentypspezifischen Ringpufferklassen abgeleitet werden. Implementiere spezifische Klassen für Zeichenketten (char *) und int32.
Beim Initialisieren des jeweiligen Objektes muss der Benutzer folgende Angaben machen:
- Größe des Puffers
- Wie soll mit Pufferüberläufen (Puffer erweitern? Letztes Element überschreiben? Anforderung ignorieren? Exception auslösen? ...) umgegangen werden.
Folgende Funktionalitäten soll der Ringpuffer zur Verfügung stellen:
- Einfügen eines Elementes (enqueue)
- Auslesen und Entfernen eines Elementes (dequeue)
- Angabe des belegten und freien Pufferspeichers
Schreibt dazu ein Testprogramm, in dem über die Konsole ein Puffer angelegt werden kann. Nachdem der Puffer angelegt wurde, soll der Benutzer folgende Möglichkeiten haben:
- Hinzufügen eines Elementes zum Puffer
- Auslesen eines Elementes vom Puffer
- Informationen über den Füllstand des Puffers
- Beenden des Programmes. Dabei sollen die noch im Puffer vorhandenen Elemente ausgelesen und ausgegeben werden.
Teste dabei, ob sich dein Programm in folgenden Situationen korrekt verhält:
- Es wird versucht, in einen bereits vollen Puffer ein weiteres Element hinzuzufügen
- Es wird versucht, aus einem leeren Puffer ein Element auszulesen.
Session 8
löst die Beispielaufgaben der 8. Session.
Abschlussaufgabe
Auch wenn wir noch nicht am Ende des Semesters angekommen sind und uns noch einige wichtige Themen fehlen, ist jetzt ein günstiger Zeitpunkt, sich über den Aufbau und die Architektur des zu entwickelnden kleinen Spiels zu machen. Macht euch also Gedanken (am besten schriftlich!) über die interne Architektur eurer Software. Ihr solltet dabei funktionale Grobmodule definieren, die danach jeweils feiner spezifiziert werden.
Darauf aufbauend kann dann ein Klassendiagramm erstellt werden, aus dem die vollständige Deklaration der einzelnen Klassen hervorgeht.
Logfile-Klasse
Die zu erstellende Logfile-Klasse soll in der Lage sein, Fehler oder Nachrichten, die an beliebiger Stelle im Programm erzeugt werden können sollen, dauerhaft in eine dafür vorgesehene Datei zu schreiben. Dies kann bei der Entwicklung angewendet werden, um Programmstati zu überprüfen und/oder während der Laufzeit, um auftretende Fehler zu dokumentieren. Die Form der Meldung bleibt dabei dir überlassen.
Inhalt der Meldung
Zur späteren Analyse sollten folgende Informationen in der Meldung zu finden sein:
- Informationen zum meldungserzeugenden Programm
- Informationen zum ausführenden System
- Zeitpunkt der Meldung
- ist die Meldung ein Fehler?
- Name der meldungserzeugenden Funktion
- evtl. Fehlermeldung (Exception)
- allgemeine Meldung
Sollten dir noch weiter wichtige oder interessante Informationen einfallen, können diese natürlich eingefügt werden.
Funktionalität der Klasse
Die Instanz der Logfile-Klasse soll von beliebigen Stellen im Programmcode aus aufgerufen werden können. Es empfielt sich daher eine Implementation als Singleton.
Die Klasse muss in der Lage sein, in eine Datei schreiben zu können. Der Name der Datei kann dabei fest vorgegeben werden (z.B. logFile.txt).
Zufall
Es ist eine Klasse zu erstellen, die das Ermitteln von Zufallszahlen durch die C+±Funktion rand() kapselt. Zusätzlich soll die Möglichkeit geschaffen werden, den Generator mit einem bestimmten Seed zu initialisieren.
Initialisierung
- mit einem «zufälligem» Wert (aktuelle Zeit)
- mit einem zu übergebenden Seed-Wert
Funktionalität
- Rückgabe des aktuellen Seed-Wertes
- Ermitteln einer Zufallszahl mit Angabe des Maximalwertes
- Ermitteln einer Zufallszahl mit Angabe eines Bereiches
- Vorspulen der Zufallszahlenermittlung durch n-faches Aufrufen der Funktion