<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.freitagsrunde.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alexander+K%C3%BChrmann</id>
	<title>FreitagsrundenWiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.freitagsrunde.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alexander+K%C3%BChrmann"/>
	<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/Spezial:Beitr%C3%A4ge/Alexander_K%C3%BChrmann"/>
	<updated>2026-05-08T15:03:55Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Tron&amp;diff=14979</id>
		<title>C-Kurs/Tron</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Tron&amp;diff=14979"/>
		<updated>2010-09-20T12:39:25Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Formattierung und Rechtschreibung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:Tron-screenshot.png|miniatur|300px|So in etwa soll dann unser Spiel aussehen]]Hier wollen wir euch mal ein wenig SDL zeigen - am Beispiel von Tron. SDL steht für &amp;quot;Simple Direct media Layer&amp;quot; und kümmert sich um Tastatureingaben und um ein Zeichenfenster (eigentlich um noch viel mehr, [[#Further_reading_oder_.22Was_kann_SDL_denn_noch.3F.22|siehe unten]]). SDL ist plattformunabhängig; ihr könnt euren Code also sowohl unter Linux als auch unter Windows oder Mac compilen und ausführen.  &lt;br /&gt;
&lt;br /&gt;
'''Tron:''' Tron ist ein kleines Spiel für zwei (oder mehr) Spieler, dass ihr vielleicht aus dem Film Tron oder dem Spiel Amagetronad kennt. In unserer Zwei-Spieler-2D-Variante startet jeder Spieler als ein Punkt auf dem Spielfeld. Während des Spieles zieht jeder Spieler eine Linie hinter sich her. Fährt man irgendwo gegen (gegnerische Linie, eigene Linie, Bildschirmrand), so hat man verloren und eine neue Runde beginnt.&lt;br /&gt;
&lt;br /&gt;
Das Ganze machen wir Schritt für Schritt, vom Initialisieren des Fensters über Abarbeiten der Tastatur-Events und Erkennen der Kollisionen bis hin zum Zeichnen des Feldes.&lt;br /&gt;
Falls ihr mehr über eine der SDL-Funktionen wissen wollt (also alle Funktionen/Datenstrukturen, die mit SDL_ anfangen), könnt ihr entweder auf http://www.libsdl.org/cgi/docwiki.cgi gucken oder (falls ihr ein Unix-artiges Betriebssystem mit installiertem SDL habt) einfach &amp;quot;man FUNKTION&amp;quot; (z.B. man SDL_Init) in eine Konsole eingeben um Hilfe zu dieser Funktion zu bekommen. Ich werde an entsprechenden Stellen einfach (man funktion) als Hinweis schreiben, dass man mit dieser Funktion noch mehr anstellen könnte.&lt;br /&gt;
&lt;br /&gt;
== Was ihr braucht == &lt;br /&gt;
* SDL mit Development-Headers (unter Debian/Ubuntu heißt das Paket libsdl1.2-dev)&lt;br /&gt;
* Die beiden Hilfs-Funktionen um Pixel von zu setzen/lesen (putpixel/getpixel). Diese könnt ihr hier ([http://docs.freitagsrunde.org/Veranstaltungen/ckurs_2010/aufgaben/tron/pixel.h pixel.h]/[http://docs.freitagsrunde.org/Veranstaltungen/ckurs_2010/aufgaben/tron/pixel.c pixel.c]) von uns downloaden oder auch von http://www.libsdl.org/cgi/docwiki.cgi/Pixel_Access .&lt;br /&gt;
&lt;br /&gt;
== Ein erstes Fenster ==&lt;br /&gt;
Fangen wir mit unserem Fenster an.&lt;br /&gt;
&lt;br /&gt;
=== SDL initialisieren ===&lt;br /&gt;
Zu Beginn müssen wir das SDL Headerfile und unsere pixel.h includen.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 #include &amp;lt;SDL/SDL.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;pixel.h&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der Main-Funktion rufen wir zu aller erst die Initialisierungsfunktion von SDL auf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SDL_Init(SDL_INIT_EVERYTHING);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Einfachheit halber initialisieren wir alles, was SDL zu bieten hat. Man kann ggf. nur Teilsysteme initialisieren (man SDL_Init), das ist für uns aber gerade nicht so wichtig.&lt;br /&gt;
&lt;br /&gt;
Als nächstes müssen wir SDL sagen, dass wir ein Fenster haben wollen und wie groß dieses sein soll. Das machen wir mit der Funktion &amp;lt;tt&amp;gt;SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)&amp;lt;/tt&amp;gt;. Wir geben der Funktion die gewünschten Parameter für das Fenster und SDL gibt uns ein &amp;lt;tt&amp;gt;SDL_Surface&amp;lt;/tt&amp;gt; (dieser Typ hält in SDL eine Grafik, in diesem Fall unser Fenster).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Oookay.. SDL gibt uns hier ein&lt;br /&gt;
* 640 Pixel breites&lt;br /&gt;
* 480 Pixel hohes Fenster mit&lt;br /&gt;
* 32 Bits pro Pixel (hat was mit der Farbtiefe zu tun, für uns nicht so wichtig, das passt schon so)&lt;br /&gt;
* als &amp;lt;tt&amp;gt;SDL_SW_SURFACE&amp;lt;/tt&amp;gt; (soll heißen wir benutzen keine Hardwarebeschleunigung)&lt;br /&gt;
Für den letzten Parameter, also die Window Flags, gibt es viele verschiedene Parameter (man SDL_VideoMode), die man einfach miteinaner verunden könnte (z.B. &amp;lt;tt&amp;gt;SDL_HWSURFACE | SDL_FULLSCREEN&amp;lt;/tt&amp;gt; für Vollbild mit Hardwarebeschleunigung), aber auch das ist für uns gerade nicht wichtig.&lt;br /&gt;
&lt;br /&gt;
Zu guter letzt rufen wir am Ende der main-Funktion noch ein &amp;lt;tt&amp;gt;SDL_Quit()&amp;lt;/tt&amp;gt; auf, damit SDL sich deinitialisiert, wenn wir das Programm beenden.&lt;br /&gt;
&lt;br /&gt;
Nun wollen wir unser Grundgerüst ausprobieren. Damit, wenn wir das Programm starten, das Fenster nicht sofort wieder zu geht packen wir hinter die Initialisierung (aber vor das &amp;lt;tt&amp;gt;SDL_Quit()&amp;lt;/tt&amp;gt;) ein &amp;lt;tt&amp;gt;SDL_Delay(5000)&amp;lt;/tt&amp;gt; (''SDL_Delay'' nimmt die Zeit in Millisekunden, d.h. der Aufruf wartet 5 Sekunden). Und nun compilen und ausprobieren!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gcc -Wall tron.c pixel.c -lSDL -o tron &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls ihr (wie ich) zu faul seid das jedes mal einzugeben könnt ihr auch folgendes Makefile benutzen (soll heißen in die Datei Makefile pasten) und dann nur noch make bzw. make run eingeben.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CFLAGS=`sdl-config --cflags` -Wall&lt;br /&gt;
LDFLAGS=`sdl-config --libs`&lt;br /&gt;
OBJ=tron.o pixel.c&lt;br /&gt;
&lt;br /&gt;
.PHONY: clean run&lt;br /&gt;
&lt;br /&gt;
tron: $(OBJ)&lt;br /&gt;
&lt;br /&gt;
run: tron&lt;br /&gt;
	./tron&lt;br /&gt;
&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o tron&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Jetzt solltet ihr für 5 Sekunden ein Fenster sehen, welches sich dann wieder schliesst.&lt;br /&gt;
&lt;br /&gt;
=== SDL Events ===&lt;br /&gt;
Ein sich nach einiger Zeit wieder schliessendes Fenster bringt uns natürlich nicht so viel. Was wir wollen ist mit SDL zu interagieren. Wir wollen wissen, ob jemand eine Taste auf der Tastatur gedrückt hat oder das Fenster schliessen wollte. All das sagt uns SDL mit sog. '''Events'''. Davon gibt es viele für alle möglichen Gegebenheiten (man SDL_Event), aber wir wollen als erstes nur den Fall des sich schliessenden Fensters betrachten.&lt;br /&gt;
&lt;br /&gt;
Als erstes brauchen wir eine Variable vom Typ &amp;lt;tt&amp;gt;SDL_Event&amp;lt;/tt&amp;gt; in der wir das Event speichern. Um SDL nach einem Event zu fragen übergeben wir &amp;lt;tt&amp;gt;int SDL_PollEvent(SDL_Event*)&amp;lt;/tt&amp;gt; eine Referenz zu dieser Variable.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 SDL_Event event;&lt;br /&gt;
 SDL_PollEvent(&amp;amp;event);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;SDL_PollEvent&amp;lt;/tt&amp;gt; hat als Rückgabewert 1, wenn es ein Event gefunden hat und 0, falls es kein neues Event gab. &amp;lt;tt&amp;gt;SDL_Event event&amp;lt;/tt&amp;gt; ist ein struct, in &amp;lt;tt&amp;gt;event.type&amp;lt;/tt&amp;gt; steht der Typ des aktuellen Events. Für unser Spiel sind folgende Events wichtig (Dies sind dann auch die Werte, welche in &amp;lt;tt&amp;gt;event.type&amp;lt;/tt&amp;gt; stehen): SDL_QUIT falls das Programm beendet werden soll und SDL_KEYDOWN, falls eine Taste auf der Tastatur gedrückt wurde.&lt;br /&gt;
&lt;br /&gt;
Schreibt nun in die main-Funktion eine while-Schleife. In dieser Schleife sollen SDL-Events abgefragt werden (unser sog. Event-Loop). Wenn ein SDL_QUIT-Event auftritt soll das Programm beendet werden. Damit die while-Schleife nicht all eure CPU-Zeit frisst solltet ihr mit &amp;lt;tt&amp;gt;SDL_Delay&amp;lt;/tt&amp;gt; eine Verzögerung von 10-50 Millisekunden einbauen.&lt;br /&gt;
&lt;br /&gt;
Nun kann man das Fenster über das ihm gegebene X (bei entsprechendem Windowmanager *hust*) schließen. Horray, unser Fenster hört auf uns!&lt;br /&gt;
&lt;br /&gt;
== Tron ==&lt;br /&gt;
&lt;br /&gt;
=== Zustandsvariablen ===&lt;br /&gt;
Es wird Zeit, dass wir zu unserem Spiel kommen. Ein Spieler in Tron hat in etwa folgende Eigenschaften:&lt;br /&gt;
* eine Position (x/y)&lt;br /&gt;
* eine Richtung (up, down, left, right)&lt;br /&gt;
* Punktestand&lt;br /&gt;
* Farbe des Spielers (Definiert als Rot/Grün/Blau-Wert von 0-255)&lt;br /&gt;
Für Position und Punke können wir jeweils den Typ int wählen. Für die Farbe nehmen wir &amp;lt;tt&amp;gt;SDL_Color&amp;lt;/tt&amp;gt; (das ist ein von SDL definiertes struct mit drei Uint8 r, g und b für den Farbwert rot, grün und blau (man SDL_Color)). Bei der Richtung könnt ihr euch überlegen, ob ihr lieber ein '''enum''' nehmen wollt anstatt eines ints. Wir packen diese Werte in ein struct Player, damit wir später Funktionen nur einmal schreiben müssen und dann für jeden Spieler jeweils einmal aufrufen können.&lt;br /&gt;
&lt;br /&gt;
Schreibt nun eine Funktion &amp;lt;tt&amp;gt;void initPlayers()&amp;lt;/tt&amp;gt;, welche die Variablen der beiden Spieler initialisiert (und ihnen auch eine schöne Farbe gibt ;). Die Startposition der Spieler machen wir abhängig von der Spielfeldgröße. Ich schlage halbe Höhe des Feldes als Y-Koordinate und 1/3 bzw. 2/3 der Breite als Startposition vor. Hier ein Codeschnipsel, wie ihr an das &amp;lt;tt&amp;gt;SDL_Surface&amp;lt;/tt&amp;gt; vom Fenster und an dessen Höhe/Breite kommt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 [...]&lt;br /&gt;
 SDL_Surface *screen = SDL_GetVideoSurface();&lt;br /&gt;
 int hoehe = screen-&amp;gt;h;&lt;br /&gt;
 int breite = screen-&amp;gt;w;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Der Rückgabewert von &amp;lt;tt&amp;gt;SDL_GetVideoSurface&amp;lt;/tt&amp;gt; ist hierbei mit dem von &amp;lt;tt&amp;gt;SDL_SetVideoMode&amp;lt;/tt&amp;gt; identisch (halt der Zeichenbereich unseres Fensters).&lt;br /&gt;
&lt;br /&gt;
Ruft nun &amp;lt;tt&amp;gt;initPlayers()&amp;lt;/tt&amp;gt; in eurer main-Funktion nach dem Initialisieren von SDL auf (sonst ist der Rückgabewert von &amp;lt;tt&amp;gt;SDL_GetVideoSurface()&amp;lt;/tt&amp;gt; nicht definiert und ihr habt keine Fensterhöhe/breite).&lt;br /&gt;
&lt;br /&gt;
=== Zeichnen der Spieler ===&lt;br /&gt;
Nun wollen wir anfangen unsere beiden Spieler zu zeichnen und sich bewegen zu lassen. Dazu setzen wir den Pixel, auf dem der Spieler sich gerade befindet auf seine Farbe.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 putpixel(SDL_Surface *screen, int x, int y, Uint32 pixel);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da &amp;lt;tt&amp;gt;putpixel&amp;lt;/tt&amp;gt; einen &amp;lt;tt&amp;gt;Uint32&amp;lt;/tt&amp;gt; als Farbwert erwartet müssen wir unser &amp;lt;tt&amp;gt;SDL_Color&amp;lt;/tt&amp;gt; wohl umwandeln. Dies passiert mit der Funktion&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
wobei mit &amp;lt;tt&amp;gt;SDL_PixelFormat&amp;lt;/tt&amp;gt; das PixelFormat unseres screens gemeint ist (screen-&amp;gt;format (man SDL_Surface)).&lt;br /&gt;
&lt;br /&gt;
* Schreibt eine Funktion &amp;lt;tt&amp;gt;Uint32 color2rgb(SDL_Color)&amp;lt;/tt&amp;gt; welche ein &amp;lt;tt&amp;gt;SDL_Color&amp;lt;/tt&amp;gt; in den entsprechenden &amp;lt;tt&amp;gt;Uint32&amp;lt;/tt&amp;gt; umwandelt.&lt;br /&gt;
* Schreibt eine Funktion &amp;lt;tt&amp;gt;void paintPlayer(struct Player*)&amp;lt;/tt&amp;gt; welche einen Spieler zeichnet.&lt;br /&gt;
&lt;br /&gt;
Wichtig: Eure Zeichenoperationen (also alles, was etwas in das Fenster bringt) werden erst sichtbar, wenn ihr SDL sagt, dass ihr eure &amp;quot;Änderungen&amp;quot; sehen wollt. Der Einfachheit halber benutzt nach euren Zeichenoperationen &amp;lt;tt&amp;gt;int SDL_Flip(screen)&amp;lt;/tt&amp;gt; (wobei screen unser Fenster (SDL_Surface*) ist) um dies zu tun (wer hier mehr drüber wissen will kann sich mal &amp;lt;tt&amp;gt;SDL_UpdateRect&amp;lt;/tt&amp;gt; anschauen).&lt;br /&gt;
&lt;br /&gt;
Nun zeichnet in eurer main-Funktion vor dem Event-Loop die beiden Spieler und startet das Programm. Jetzt können wir unsere beiden Spieler als Pixel sehen.&lt;br /&gt;
&lt;br /&gt;
=== Bewegen der Spieler ===&lt;br /&gt;
Ohne Bewegung wird das alles auf Dauer ziemlich langweilig. Deshalb brauchen wir eine Funktion &amp;lt;tt&amp;gt;void movePlayer(struct Player*)&amp;lt;/tt&amp;gt;, welche abhängig von der Richtung des Spielers dessen Position verändert. Diese Funktion müssen wir nun in unserer Event-Loop unterbringen. Wenn wir kein Event haben, dann wollen wir unsere Spieler beide bewegen (&amp;lt;tt&amp;gt;movePlayer&amp;lt;/tt&amp;gt;), beide zeichnen (&amp;lt;tt&amp;gt;paintPlayer&amp;lt;/tt&amp;gt;), unseren Bildschirm aktualisieren (&amp;lt;tt&amp;gt;SDL_Flip&amp;lt;/tt&amp;gt;) und dann ein wenig warten (&amp;lt;tt&amp;gt;SDL_Delay&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Wenn das fertig ist und wir unser Programm starten, dann sehen wir, dass beide Spieler sich in ihre Richtung bewegen und sich ggf. übermalen. Sobald aber einer aus dem Bildschirm verschwindet passieren komische Sachen: Entweder sie kommen auf der anderen Seite wieder raus oder unser Programm stürzt ab. Hmmmm, da fehlt uns wohl...&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen erkennen und behandeln ===&lt;br /&gt;
In unserem Spiel gibt es drei Arten von Kollision&lt;br /&gt;
* Ein Spieler fährt aus dem Fenster raus&lt;br /&gt;
* Ein Spieler fährt gegen eine Linie (eine eigene oder eines Gegners)&lt;br /&gt;
* Beide Spieler befinden sich auf der gleichen Position (unentschieden!)&lt;br /&gt;
&lt;br /&gt;
Die ersten beiden Fälle wollen wir mit der Funktion behandeln &amp;lt;tt&amp;gt;int playerCollided(struct Player*)&amp;lt;/tt&amp;gt;. Sie soll überprüfen, ob der Spieler in seiner aktuellen Position ausserhalb des Bildschirms ist oder ob dort schon einer vor ihm war. Letzteres könnt ihr leicht überprüfen, indem ihr guckt, ob an dieser Stelle ein schwarzer Pixel ist (soll heißen: leeres Spielfeld). Das könnt ihr überprüfen, indem ihr schaut, ob der Wert, den &amp;lt;tt&amp;gt;Uint32 getpixel(SDL_Surface *screen, int x, inty)&amp;lt;/tt&amp;gt; zurückliefert dem entspricht, was &amp;lt;tt&amp;gt;SDL_MapRGB&amp;lt;/tt&amp;gt; für Schwarz (0, 0, 0) zurückgibt. Die Funktion soll 1 für Kollision und 0 für keine Kollision zurückgeben.&lt;br /&gt;
&lt;br /&gt;
Nun brauchen wir die Funktion &amp;lt;tt&amp;gt;int gotCollison()&amp;lt;/tt&amp;gt; welche 0 für keine Kollision, 1 für Player1 kollidiert, 2 für Player2 kollidiert und 3 für Unentschieden zurückgibt. Benutzt hierzu &amp;lt;tt&amp;gt;playerCollided()&amp;lt;/tt&amp;gt; um herauszufinden, ob ein Spieler kollidiert ist und implementiert ausserdem den 3. Fall. &lt;br /&gt;
&lt;br /&gt;
Aber was machen wir, wenn wir eine Kollision erkannt haben? Wir setzen alles wieder auf den Startzustand. Also brauchen wir eine Funktion &amp;lt;tt&amp;gt;void resetGame()&amp;lt;/tt&amp;gt;, die&lt;br /&gt;
* unser Fenster komplett schwärzt (uns von den alten Linien befreit)&lt;br /&gt;
* die Spieler auf ihre Startpositionen setzt (Richtung nicht vergessen!)&lt;br /&gt;
* die beiden Spieler zeichnet&lt;br /&gt;
&lt;br /&gt;
Zum Schwärzen des Bildschirms könnt ihr &amp;lt;tt&amp;gt;SDL_FillRect(screen, NULL, SDL_MapRGB(screen-&amp;gt;format, 0, 0, 0))&amp;lt;/tt&amp;gt; benutzen (man SDL_FillRect). &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; steht hierbei für das zu füllende Rechteck - wir übergeben keines, denn dadurch wird automatisch der gesamte Bildschirm angenommen.&lt;br /&gt;
&lt;br /&gt;
Nun kombinieren wir all diese schönen Funktionen miteinander in unserer Event-Loop in unserer main-Funktion:&lt;br /&gt;
* Fortbewegen beider Spieler&lt;br /&gt;
* Überprüfen, ob eine Kollision stattfand&lt;br /&gt;
** Wenn ja: Dem jeweiligen Spieler, der nicht kollidiert ist, einen Punkt geben und das Spielfeld resetten&lt;br /&gt;
** Wenn nicht: Beide Spieler auf ihrer neuen Position zeichnen&lt;br /&gt;
* Den Bildschirm updaten (&amp;quot;flippen&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Puh! Nun haben wir es aber auch schon fast geschafft. Fehlt nur noch die Bewegung der Spieler und eine Punkteanzeige.&lt;br /&gt;
&lt;br /&gt;
=== Tastatureingaben zu Richtungswechsel ===&lt;br /&gt;
Um die Richtung eines Spielers zu wechseln müssen wir ihm eigentlich nur einen anderen Wert in seine Richtungsvariable schreiben. Den Rest macht dann schon unsere &amp;lt;tt&amp;gt;movePlayer&amp;lt;/tt&amp;gt;-Funktion in der Event-Loop. Aber wie kriegen wir raus, welche Taste gedrückt wurde? Genau, per Event. Momentan dümpelt in unserer Event-Abfrage nur unser &amp;lt;tt&amp;gt;SDL_QUIT&amp;lt;/tt&amp;gt;-Event rum. Nun wollen wir ausserdem gucken, ob es sich nich doch um ein &amp;lt;tt&amp;gt;SDL_KEYDOWN&amp;lt;/tt&amp;gt;-Event handelt. Wenn es eines ist (&amp;lt;tt&amp;gt;event.type == SDL_KEYDOWN&amp;lt;/tt&amp;gt;, schon vergessen?), steht in &amp;lt;tt&amp;gt;event.key.keysym.sym&amp;lt;/tt&amp;gt; die Taste, die gedrückt wurde. &amp;lt;tt&amp;gt;sym&amp;lt;/tt&amp;gt; ist vom Typ &amp;lt;tt&amp;gt;SDLKey&amp;lt;/tt&amp;gt;. Alle benutzbaren Tasten findet ihr unter (man SDLKey), aber momentan sollten &amp;lt;tt&amp;gt;SDLK_LEFT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SDLK_RIGHT&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SDLK_UP&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SDLK_DOWN&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SDLK_a&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SDLK_w&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;SDLK_s&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;SDLK_d&amp;lt;/tt&amp;gt; reichen.&lt;br /&gt;
&lt;br /&gt;
Also: Behandelt das &amp;lt;tt&amp;gt;SDL_KEYDOWN&amp;lt;/tt&amp;gt;-Event, schaut ob eine Taste für einen der Spieler gedrückt wurde und behandelt diese. Wenn ihr das Spiel etwas einfacher machen wollt, dann passt auf, das kein Spieler in sich selbst steuern kann (d.h. keine 180° Wendung, also z.B. von left zu right wechseln).&lt;br /&gt;
&lt;br /&gt;
Tja, nun habt ihr ein spielbares (und plattformunabhängiges) Multiplayer 2D Tron Spiel!&lt;br /&gt;
&lt;br /&gt;
=== Punkte? ===&lt;br /&gt;
Naja gut, was noch fehlt ist eine Punkteanzeige. Die realisieren wir ganz einfach über unseren Fenstertitel. Den kann man mit&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 SDL_WM_SetCaption(&amp;quot;Mein tolles Fenster!1!!&amp;quot;, 0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
setzen.&lt;br /&gt;
&lt;br /&gt;
Schreibt eine Funktion &amp;lt;tt&amp;gt;void updateWindowTitle()&amp;lt;/tt&amp;gt; welche (z.B. mit &amp;lt;tt&amp;gt;sprintf&amp;lt;/tt&amp;gt;) einen Titel für das Fenster (z.B. C-Kurs Tron) und dahinter den aktuellen Punktestand zusammensetzt und unserem Fenster diesen gibt. Diese Funktion muss immer aufgerufen werden, wenn sich der Punktestand verändert (und natürlich auch einmal am Anfang). Sucht euch einen schönen Platz dafür aus.&lt;br /&gt;
&lt;br /&gt;
== Bonusrunde == &lt;br /&gt;
Wer jetzt noch nicht genug hat...&lt;br /&gt;
&lt;br /&gt;
=== Einsteiger-Bonus: Quit on Esc ===&lt;br /&gt;
Das Spiel soll sich beenden, wenn jemand Escape drückt.&lt;br /&gt;
&lt;br /&gt;
=== Bonus: Fenster resizen ===&lt;br /&gt;
Macht das Fenster vergrößerbar bzw. verkleinerbar! Denkt dran, dass bei einer neuen Runde die Spieler auch an der richtigen Stelle anfangen (falls ihr diese Werte direkt als Zahlen reingeschrieben habt).&lt;br /&gt;
&lt;br /&gt;
=== Bonus: Ein Torus als Spielfeld ===&lt;br /&gt;
Warum sollte man an der Spielwand crashen? Man könnte doch an der jeweils anderen Seite des Feldes herauskommen...&lt;br /&gt;
&lt;br /&gt;
=== Bonus Bonus: Massive Multiplayer ===&lt;br /&gt;
Baut das Spiel so um, dass man beim Starten auf der Kommandozeile eine Spielerzahl übergeben kann (z.B. 2-4 Spieler). Damit es nich zu eng auf der Tastatur wird könnte es nützlich sein, wenn ihr das Spiel so umschreibt, dass man nur noch zwei Tasten für Links/Rechts hat um den Spieler zu kontrollieren (Megabonus: Ausser ihr baut Maus+Joysticksupport ein).&lt;br /&gt;
&lt;br /&gt;
== Further reading oder &amp;quot;Was kann SDL denn noch?&amp;quot; ==&lt;br /&gt;
SDL hat noch einige interessante Zusatzmodule&lt;br /&gt;
* SDL_Image - Kann ein haufen Bildformate laden und in ein SDL_Surface packen (von sich aus kann SDL nur .bmp)&lt;br /&gt;
* SDL_Mixer - SDL Soundausgabe&lt;br /&gt;
* SDL_Net - SDL Netzwerkbibliothek&lt;br /&gt;
Ausserdem kann SDL ziemlich einfach geladene Bilder auf den Bildschirm bringen (man SDL_BlitSurface), Tastatur/Maus/Joystick eingabe behandeln, Musik/Soundeffekte zusammenmixen oder auch (mit der entsprechenden Bibliothek) Netzwerkkram machen. Gerne wird es für 2D Spiele benutzt (z.B. supertux, xmame, frozen-bubbles, ...), aber auch als Wrapper für OpenGL (sauerbraten, der Quake3 Linux Port, warsow, armagetronad...); teilweise nutzen auch einige Anwendungen SDL (mplayer, virtualbox, dosbox, ...). &lt;br /&gt;
&lt;br /&gt;
Einsteigerfreundliche SDL-Tutorials:&lt;br /&gt;
* http://www.lazyfoo.net/SDL_tutorials/index.php&lt;br /&gt;
* http://www.libsdl.org/cgi/docwiki.cgi/&lt;br /&gt;
* http://www.libsdl.org/cgi/docwiki.cgi/Using_OpenGL_With_SDL&lt;br /&gt;
&lt;br /&gt;
Happy Hacking ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=14976</id>
		<title>C-Kurs/Übungsaufgaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=14976"/>
		<updated>2010-09-20T10:23:38Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Die Aufgaben */ Musterlösung für DTMF hinzu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wir haben jeder Aufgabe eine Einschätzung ihrer Schwierigkeit auf einer Skala von 1 bis 10 vorangestellt. Bei dieser Einschätzung sind wir von einem Gehirn ausgegangen, für welches das jeweilige Themengebiet völlig neu ist, das jedoch schon ein ganz gutes Verständnis dafür hat wie eine Programmiersprache denn so funktioniert. &lt;br /&gt;
Entsprechend kann eine schwer bewertete Aufgabe aus einem frühen Themengebiet für manch einen sehr einfach oder eine leicht bewertete aus einem späten Themengebiet für einen anderen sehr schwer sein. Es ist nur ein Wert, der euch helfen soll eure nächste Aufgabe zu wählen. &lt;br /&gt;
&lt;br /&gt;
Falls ihr Anmerkungen zu den Aufgaben habt, könnt ihr die Diskussionsseiten der jeweiligen Aufgaben nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeitsgrade ==&lt;br /&gt;
&lt;br /&gt;
#  Reines Tutorial. Man muss nicht viel selbst denken&lt;br /&gt;
#  ...&lt;br /&gt;
#  Leichte Übungsaufgabe. Studies, die noch eher unsicher sind werden hier gut begleitet.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Typische Aufgabe. Man muss den Kopf benutzen, bekommt an schwierigen Stellen aber Hilfestellungen.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Herausfordernd, eher etwas für Studies die etwas fitter sind.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Auch erfahrene Programmierer werden hier ein bis zwei Übungen beschäftigt sein&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#  Tja, die Idee war da. Wir finden sie auch gut, aber es könnte wirklich anstrengend werden.&lt;br /&gt;
&lt;br /&gt;
== Die Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;2&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
 |- bgcolor=&amp;quot;#D8D8D8&amp;quot;&lt;br /&gt;
 !Aufgabe&lt;br /&gt;
 !Schwierigkeit&lt;br /&gt;
 !Vorwissen&lt;br /&gt;
 !Lerneffekte&lt;br /&gt;
 !Bearbeiter&lt;br /&gt;
 !Korrektur gelesen&lt;br /&gt;
 !Musterlösung&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Von der Konsole zum HelloWorld | Von der Konsole zum HelloWorld]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Konsole benutzen, Hello World&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Fakultät | Fakultät]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Schleifen&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | Daniel (2009), &lt;br /&gt;
 |  &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/Pythagoras-Triplet | Pythagoras-Triplet]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Schleifen &amp;lt;br&amp;gt; if-Bedingungen&lt;br /&gt;
 | Gabriel P.&lt;br /&gt;
 | seba(2010)&lt;br /&gt;
 | [[Ckurs2010/Pythagoras-Triplet/Musterloesung | Pythagoras-Triplet]] &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Fibonacci-Folge|Fibonacci-Folge]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Funktionen &amp;lt;br&amp;gt; Rekursion&lt;br /&gt;
 | Paul B.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2010)&lt;br /&gt;
 | [[Ckurs2009/Fibonacci-Folge/Musterlösung | Fibonacci-Folge]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/digitalesSchloesserKnacken|digitales Schloesser knacken]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Kontrollstrukturen &amp;lt;br&amp;gt;Bitweise Operatoren&lt;br /&gt;
 | Paul B.&lt;br /&gt;
 | Eugen R. (2010)&lt;br /&gt;
 | [[Ckurs2009/digitalesSchloesserKnacken/Musterlösung | digitales Schloesser knacken]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Rekursives_arbeiten|Rekursives Arbeiten]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3-5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Bekannte Operatoren wie + durch Funktionen succ und neg nachbilden&lt;br /&gt;
 | Eugen R.&lt;br /&gt;
 | Paul B.(2010)&lt;br /&gt;
 | [[Ckurs2009/Rekursives_arbeiten/Musterlösung | Rekursives Arbeiten]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Base64 | Base64]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Operatoren&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | Paul B.(2010)&lt;br /&gt;
 | [[Ckurs2009/Base64/Musterlösung | Base64]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe | Ein- und Ausgabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Ausgabe derselben&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (2009), &lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe/Musterlösung | Ein- und Ausgabe]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner | Taschenrechner]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Eingabe+Ausgabe&amp;lt;br&amp;gt;Mathematische Operatoren&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2009), &lt;br /&gt;
 | [[Ckurs2009/Taschenrechner/Musterlösung | Taschenrechner]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/VerschachtelteSchleifen | Verschachtelte Schleifen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Umgang mit mehreren verschachtelten Schleifen&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK (2009), &lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Glückspiel | Glücksspiel]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Anwenden von Fallunterscheidungen und Einlesen von Werten aus der Konsole&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK (2009), &lt;br /&gt;
 | [[Ckurs2009/Glückspiel/Musterlösung | Glückspiel]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs/Buchstaben_zählen | Buchstaben zählen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Array, Dateien lesen&lt;br /&gt;
 | Alex K.&lt;br /&gt;
 | Gabriel (2010)&lt;br /&gt;
 | vorhanden bitte reinstellen&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Wochentag | Wochentagsrechnung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Mathematikverständniss&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (Musterlösung noch nicht vorhanden)  (2009), &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0 | Taschenrechner ''2.0'']]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Knobeln&amp;lt;br&amp;gt;Komplexes Aufgaben lösen&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | Martin K. (2009), &lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0/Musterlösung | Taschenrechner ''2.0'']]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Call by reference | Call by reference]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Einfache Anwendung von &amp;amp;/*&lt;br /&gt;
 | sping&lt;br /&gt;
 | nion (2009), Alex K. (2010)&lt;br /&gt;
 | [[Ckurs2009/Call by reference/Musterlösung | Call by reference]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/String to Double | String to Double]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Original-Dokumentation anwenden (Opengroup, man pages)&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Const correctness&amp;lt;br&amp;gt;Strings&lt;br /&gt;
 | sping&lt;br /&gt;
 | Eugen R. (2010)&lt;br /&gt;
 | vorhanden bitte reinstellen&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Text processing | Text processing]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4, 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Strings&amp;lt;br&amp;gt;Pointer-Arithmetik&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Refactoring&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | [[Ckurs2009/Text processing/Musterlösung | Text processing]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Palindrome | Palindrome]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Pointer und Strings&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | nion (2009), &lt;br /&gt;
 | [[Ckurs2009/Palindrome/Musterlösung | Palindrome ]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/(Pointer) Swapping | (Pointer) Swapping]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Pointer und Arrays benutzen, generisches swap&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | Katrin (2010)&lt;br /&gt;
 | [[Ckurs2009/(Pointer) Swapping/Musterlösung | (Pointer) Swapping]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation | Matrizenmultiplikation]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mehrdimensionale Arrays&amp;lt;br&amp;gt;const correctness&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation/Musterlösung | Matrizenmultiplikation]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/DreiD | 3D mit C]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mathematische Rechenoperationen, Algorithmik&lt;br /&gt;
 | AndreasF&lt;br /&gt;
 | Mario (2010)&lt;br /&gt;
 | [[Ckurs/DreiD/Musterloesung | 3D]] &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe | Arrayuebergabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4/5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Pointer und Pointerarithmetik&lt;br /&gt;
 | nion&lt;br /&gt;
 | Martin K. (2009), &lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe/Musterlösung | Arrayuebergabe]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank | Studentendatenbank]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | struct, Pointer, Arrays&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 | Gabriel (2010)&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank/Musterlösung | Studentendatenbank]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/Punktstrukturen| Punktstrukturen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2-3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Structs, Unions, Pointer&lt;br /&gt;
 | [[Benutzer:Mutax|Florian]] (2010)&lt;br /&gt;
 | Alex K. (2010)&lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Sammelbestellung | Sammelbestellung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2-5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Listen, Pointer, Speicherverwaltung&lt;br /&gt;
 | [[Benutzer:Mutax|Florian]]&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | [[Ckurs2009/Sammelbestellung/Musterlösung | Sammelbestellung]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Zahlen_sagen | Zahlen sagen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Umgang mit Zeichenketten&lt;br /&gt;
 | Martin K.&lt;br /&gt;
 | Paul B. (w.i.p.)&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs/DTMF-Encoder | DTMF-Encoder]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Pointer, Arrays, Umgang mit Audiodaten&lt;br /&gt;
 | Alexander K.&lt;br /&gt;
 | &lt;br /&gt;
 | [[Ckurs/DTMF-Encoder/Musterlösung | DTMF-Encoder]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Compiler, Präprozessor, Header Files | Compiler, Präprozessor, Header Files]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5. VL&lt;br /&gt;
 | Arbeiten mit mehreren Quellcode-Dateien, Kompilieren und Linken, Header-Dateien und #include, debugging-Makro verwenden&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | AndyF (2010)&lt;br /&gt;
 | [https://wiki.freitagsrunde.org/Ckurs2009/Vortrag05 siehe Folien]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Bus Error | Bus Error]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5. VL&lt;br /&gt;
 | Pointer, wie entsteht ein bus error&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2010)&lt;br /&gt;
 | [[Ckurs2009/Bus Error/Musterlösung | Bus Error]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/BubbleSortDebug | BubbleSort Debugging]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Debuggen eines Programmes mit gdb&lt;br /&gt;
 | aeichner&lt;br /&gt;
 |&lt;br /&gt;
 | [[Ckurs2009/BubbleSortDebug/Musterlösung | BubbleSort Debugging]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Debug | Debugging]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1-8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Debuggen einer Anwendung nach Wahl&lt;br /&gt;
 | aeichner&lt;br /&gt;
 |&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;greenyellow&amp;quot;&lt;br /&gt;
 | [[Ckurs/ckdu | CKDU]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3-10&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7. VL&lt;br /&gt;
 | '''Vorlesungsaufgabe der 7. Vorlesung''' &lt;br /&gt;
 | Sping&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Code Layout | Code Layout]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7. VL&lt;br /&gt;
 | Kleinere Codeschipsel mit kleinen Unsauberkeiten&lt;br /&gt;
 | Daniel&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Code Layout/Musterlösung | Code Layout]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Refactoring | Refactoring]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7. VL&lt;br /&gt;
 | Wie verbessere ich den Quellcode eines Programmes.&lt;br /&gt;
 | Daniel&lt;br /&gt;
 | &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Refactoring/Musterlösung | Refactoring]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Cat | Cat]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Arbeiten mit Dateien&amp;lt;br&amp;gt;Kommandozeilenparameter&lt;br /&gt;
 | nion&lt;br /&gt;
 | sping (2009), &lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Pong | Pong]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9.VL (eigentlich 2.VL)&lt;br /&gt;
 | allgemeiner Programmablauf, fortgeschrittene Konsolenausgaben/eingaben&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 | seba(2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden  --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Buchhaltung | Buchhaltung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5.VL&lt;br /&gt;
 | Lesen aus Dateien&lt;br /&gt;
 | reiner&lt;br /&gt;
 | AndyF (2010)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/StringArraySortieren | StringArraySortieren]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Konsolparameter, Funktionspointer&lt;br /&gt;
 | reiner&lt;br /&gt;
 | martin (2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/integral | integral]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Funktionspointer&lt;br /&gt;
 | reiner&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs/integral/Musterlösung | Musterloesung]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs/forschleife | forschleife]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Bug (zum Knobeln)&lt;br /&gt;
 | reiner&lt;br /&gt;
 | nion (2009), [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/libgdsl | GDSL]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | Anwendung der Generic Data Structures Library&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/StdLib | Standard C Library]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | Recherche in der Standard C Bibliothek&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/Tron | Tron]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | SDL (Simple Directmedia Layer) kennen lernen, graphische Ausgabe&lt;br /&gt;
 | seba&lt;br /&gt;
 |&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/TicTacToe | TicTacToe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | SDL (Simple Directmedia Layer) kennen lernen, graphische Ausgabe&lt;br /&gt;
 | Martin&lt;br /&gt;
 | sdyroff (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2010/TicTacToe/Musterlösung | TicTacToe]] --&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Kleine und große Probleme ==&lt;br /&gt;
&lt;br /&gt;
* Die Tubit-Accounts haben nicht /bin/bash als shell, so dass die &amp;lt;strong&amp;gt;Cursortasten&amp;lt;/strong&amp;gt; nicht funktionieren. Workaround: als erstes Kommando 'bash' eingeben, man sieht dann auch in welchem Verzeichnis man gerade ist.&lt;br /&gt;
* wenn man nur den Promt 'bash-0.12' oder so erhält, also ohne das Verzeichnis in dem man ist, folgendes Kommando eingeben: &amp;lt;tt&amp;gt;export PS1='\u@\h:\w$ '&amp;lt;/tt&amp;gt; oder zum dauerhaften Speichern: &amp;lt;tt&amp;gt; echo &amp;quot;export PS1='\u@\h:\w$ '&amp;quot; &amp;gt;&amp;gt; ~/.bashrc &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Musterlösungen ==&lt;br /&gt;
Die Lösungen zu den Aufgaben werden nach den jeweiligen Übungen hier veröffentlicht. Falls dies nicht geschieht, bitte den zuständigen Tutor fragen.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Ckurs2009/Feedback|Feedback zum Kurs 2009]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/DTMF-Encoder/Musterl%C3%B6sung&amp;diff=14975</id>
		<title>C-Kurs/DTMF-Encoder/Musterlösung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/DTMF-Encoder/Musterl%C3%B6sung&amp;diff=14975"/>
		<updated>2010-09-20T10:22:23Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Die Seite wurde neu angelegt: „&amp;lt;pre&amp;gt; #include &amp;lt;stdlib.h&amp;gt; #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;math.h&amp;gt;  unsigned char* generateSine(int ms, int freq, float amplitude, int *numSamples) {     /* calculate...“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned char* generateSine(int ms, int freq, float amplitude, int *numSamples) {&lt;br /&gt;
    /* calculate number of samples and factor for the sine function */&lt;br /&gt;
    *numSamples = ms * 8; // 8000 Hz sampling rate means 8 samples per millisecond&lt;br /&gt;
    double numPeriodic = 8000.0 / freq;&lt;br /&gt;
    double sinFac = 2 * M_PI / numPeriodic;&lt;br /&gt;
&lt;br /&gt;
    unsigned char *sine = malloc(*numSamples * sizeof(unsigned char));&lt;br /&gt;
&lt;br /&gt;
    /* generate samples */&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i = 0; i &amp;lt; *numSamples; i++) {&lt;br /&gt;
        double sineVal = sin(i * sinFac);  // between -1 and 1&lt;br /&gt;
        unsigned char sample = (unsigned char) ((amplitude * sineVal + 1) * 0x7f);&lt;br /&gt;
        sine[i] = sample;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return sine;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char* mixPcm(unsigned char *a, unsigned char *b, int numSamples) {&lt;br /&gt;
    unsigned char *result = malloc(numSamples * sizeof(unsigned char));&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i = 0; i &amp;lt; numSamples; i++) {&lt;br /&gt;
        int aVal = a[i] - 127;&lt;br /&gt;
        int bVal = b[i] - 127;&lt;br /&gt;
        int rVal = aVal + bVal;&lt;br /&gt;
        result[i] = (unsigned char)(rVal + 127);&lt;br /&gt;
    }&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char* generateDtmfTone(int number, int ms, int *numSamples) {&lt;br /&gt;
    unsigned char *a;&lt;br /&gt;
    unsigned char *b;&lt;br /&gt;
    unsigned char *result;&lt;br /&gt;
    switch (number) {&lt;br /&gt;
        case 0:&lt;br /&gt;
            a = generateSine(ms, 941, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1336, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 1:&lt;br /&gt;
            a = generateSine(ms, 697, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1209, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            a = generateSine(ms, 697, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1336, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 3:&lt;br /&gt;
            a = generateSine(ms, 697, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1477, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 4:&lt;br /&gt;
            a = generateSine(ms, 770, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1209, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 5:&lt;br /&gt;
            a = generateSine(ms, 770, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1336, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 6:&lt;br /&gt;
            a = generateSine(ms, 770, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1477, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 7:&lt;br /&gt;
            a = generateSine(ms, 852, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1209, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 8:&lt;br /&gt;
            a = generateSine(ms, 852, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1336, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
        case 9:&lt;br /&gt;
            a = generateSine(ms, 852, 0.45, numSamples);&lt;br /&gt;
            b = generateSine(ms, 1477, 0.45, numSamples);&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    result = mixPcm(a, b, *numSamples);&lt;br /&gt;
    free(a);&lt;br /&gt;
    free(b);&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
unsigned char *generateSilence(int ms, int *numSamples) {&lt;br /&gt;
    *numSamples = ms * 8; // 8000 Hz sampling rate means 8 samples per millisecond&lt;br /&gt;
    unsigned char *result = malloc(*numSamples * sizeof(unsigned char));&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i = 0; i &amp;lt; *numSamples; i++) {&lt;br /&gt;
        result[i] = 127;&lt;br /&gt;
    }&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        fprintf(stderr, &amp;quot;no number given\n&amp;quot;);&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    int number;&lt;br /&gt;
    if (1 != sscanf(argv[1], &amp;quot;%u&amp;quot;, &amp;amp;number)) {&lt;br /&gt;
        fprintf(stderr, &amp;quot;given argument is not a number\n&amp;quot;);&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    FILE *f = fopen(argv[1], &amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    char *curNum = argv[1];&lt;br /&gt;
    while (*curNum != '\0') {&lt;br /&gt;
        int digit = *curNum++ - '0';&lt;br /&gt;
&lt;br /&gt;
        int numSamples;&lt;br /&gt;
        unsigned char *tone = generateDtmfTone(digit, 800, &amp;amp;numSamples);&lt;br /&gt;
        fwrite(tone, sizeof(unsigned char), numSamples, f);&lt;br /&gt;
        free(tone);&lt;br /&gt;
        tone = generateSilence(300, &amp;amp;numSamples);&lt;br /&gt;
        fwrite(tone, sizeof(unsigned char), numSamples, f);&lt;br /&gt;
        free(tone);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    fclose(f);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/DTMF-Encoder&amp;diff=14913</id>
		<title>C-Kurs/DTMF-Encoder</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/DTMF-Encoder&amp;diff=14913"/>
		<updated>2010-09-16T16:01:57Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Sinuswellen generieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll ein Generator für DTMF-Töne erstellt werden. DTMF steht für &amp;lt;i&amp;gt;Dual-tone multi-frequency&amp;lt;/i&amp;gt; und ist auch als [http://de.wikipedia.org/wiki/Mehrfrequenzwahlverfahren Mehrfrequenzwahlverfahren] bekannt.&lt;br /&gt;
&lt;br /&gt;
Wenn du diese Aufgabe in den Rechnerräumen bearbeitest, benutze bei dem Abspielen der Töne bitte Kopfhörer, um andere nicht zu stören.&lt;br /&gt;
&lt;br /&gt;
=== Was ist DTMF? ===&lt;br /&gt;
Kurz gesagt: ein DTMF-Ton besteht aus zwei überlagerten Sinuswellen. Für jede Taste auf dem Telefon ist eine bestimmte Frequenzkombination dieser beiden Wellen festgelegt. Genaueres sowie die Frequenzen für die Tasten finden sich [http://de.wikipedia.org/wiki/Mehrfrequenzwahlverfahren hier].&lt;br /&gt;
&lt;br /&gt;
=== Wie werden Töne im Rechner dargestellt? ===&lt;br /&gt;
Töne lassen sich als [http://de.wikipedia.org/wiki/Puls-Code-Modulation PCM]-Daten speichnern. Unser Programm soll solche PCM-Daten generieren. Ausreichend sind hier 8 Bit pro Sample, sodass sich die Tondaten in einem Array aus &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; ablegen lassen. Die Samples sind dann vorzeichenlos, was bedeutet, dass bei 127 der Mittelwert ist. Als Samplerate reichen für uns auch recht niedrige 8 kHz, das heißt für jede Sekunde Ton werden 8000 Samples benötigt.&lt;br /&gt;
&lt;br /&gt;
== Aufgabenstellung ==&lt;br /&gt;
Jetzt soll Schritt für Schritt der Tongenerator implementiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Sinuswellen generieren ===&lt;br /&gt;
Schreibe eine Funktion, die Sinuswellen als Mono-8Bit-8kHz-PCM-Daten erzeugt. Der Funktion soll die gewünschte Länge des Tons, die Frequenz des Tons, und die Amplitude, sowie einen Pointer auf ein &amp;lt;i&amp;gt;int&amp;lt;/i&amp;gt;, in dem die Anzahl der generierten Samples abgelegt werden kann. Die Funktion soll dann ausreichend Speicher für die Daten allokieren und jedes Sample mit den passenden Sinuswerten befüllen und sie am Ende zurückgeben. Der Prototyp der Funktion sollte also etwa so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;unsigned char* generateSine(int ms, int freq, float amplitude, int *numSamples)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rufe nun in der main-Funktion die Generierungsfunktion auf und speichere die Daten mit &amp;lt;tt&amp;gt;fwrite&amp;lt;/tt&amp;gt; in eine Datei. Die Datei kann jetzt auf einem Linux-System auf einfache Weise abgespielt mit dem Kommando &amp;lt;tt&amp;gt;cat &amp;lt;i&amp;gt;audiofile&amp;lt;/i&amp;gt; &amp;gt; /dev/dsp&amp;lt;/tt&amp;gt; werden. Sie kann aber auch z.B. mit &amp;lt;i&amp;gt;mplayer&amp;lt;/i&amp;gt; abgespielt werden:&lt;br /&gt;
&amp;lt;tt&amp;gt;mplayer -rawaudio samplesize=1:channels=1:rate=8000 -demuxer rawaudio &amp;lt;i&amp;gt;audiofile&amp;lt;/i&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Hinweis zum Debuggen ====&lt;br /&gt;
Um sich die Audiodaten anzusehen, kann das Programm [http://audacity.sourceforge.net/?lang=de Audacity] verwendet werden. Öffnen lassen sie sich dort über &amp;lt;i&amp;gt;Datei&amp;lt;/i&amp;gt; -&amp;gt; &amp;lt;i&amp;gt;Importieren&amp;lt;/i&amp;gt; -&amp;gt; &amp;lt;i&amp;gt;Rohdaten&amp;lt;/i&amp;gt;, dann die Datei auswählen, dann bei &amp;lt;i&amp;gt;Codec&amp;lt;/i&amp;gt; Unsigned 8 bit PCM, bei &amp;lt;i&amp;gt;Kanäle&amp;lt;/i&amp;gt; 1, bei &amp;lt;i&amp;gt;Samplefrequenz&amp;lt;/i&amp;gt; 8000 Hz auswählen. Nun kann man in die Samples reinzoomen (Button mit Lupe und Plus) und sehen, ob der Sinuswellen ordentlich sind. Mit &amp;lt;i&amp;gt;Analyse&amp;lt;/i&amp;gt; -&amp;gt; &amp;lt;i&amp;gt;Frequenzanalyse&amp;lt;/i&amp;gt; kann überprüft werden, ob die Sinuswelle die richtige Frequenz hat.&lt;br /&gt;
&lt;br /&gt;
=== Sinuswellen überlagern ===&lt;br /&gt;
Schreibe jetzt eine Funktion, die zwei Sinuswellen gleicher Länge überlagern kann. Die von ihr erstellte Samples sollen durch Addition der beiden Samples der Sinusdaten gebildet werden. Doch Vorsicht: da die Daten vorzeichenlos sind, müssen sie temporär vorzeichenbehaftet werden, so dass der Mittelwert 0 (also Wertebereich -128 bis 127) wird, dann können sie addiert werden und dann wieder vorzeichenlos abgespeichert werden (mit dem Mittelwert 127, Wertebereich 0 bis 255). Der Prototyp der Funktion sollte etwa so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;unsigned char* mixPcm(unsigned char *a, unsigned char *b, int numSamples)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teste nun die Funktion wieder, indem du zwei Sinuswellen unterschiedlicher Frequenz erzeugst und sie mit der neuen Funktion überlagerst. Als Amplitude sollte jeweils etwas weniger als die Hälfte gewählt werden, um bei der Addition [http://de.wikipedia.org/wiki/Clipping_%28Signalverarbeitung%29 Clipping] zu vermeiden. Untersuche das Ergebnis wieder, wie in der ersten Teilaufgabe.&lt;br /&gt;
&lt;br /&gt;
=== DTMF-Töne ===&lt;br /&gt;
Schreibe eine Funktion, die für eine Ziffer zwischen 0 und 9 den passenden DTMF-Ton mithilfe der beiden vorigen Funktionen generieren kann. Ihr Prototyp kann etwa so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;unsigned char* generateDtmfTone(int number, int ms, int *numSamples)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teste wieder. Zum Vergleich der Töne kannst du jetzt ein Telefon benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Nummernsequenzen generieren ===&lt;br /&gt;
Benutze jetzt die Generierungsfunktion, um eine Folge von Ziffern in eine Datei zu schreiben. Die Töne sollten durch Stille getrennt sein. Du brauchst also noch eine Funktion, die Samples generiert, die alle den Wert 127 haben. Die Nummer soll als Kommandozeilenparameter oder Benutzereingabe eingegeben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn du jetzt ein analoges Telefon zur Hand hast, kannst du die Töne ins Mikrofon des Hörers anspeilen und damit Nummern wählen.&lt;br /&gt;
&lt;br /&gt;
==== Hinweis ====&lt;br /&gt;
Vergesse nicht, alle Tondaten, die du nicht mehr brauchst, mit &amp;lt;tt&amp;gt;free&amp;lt;/tt&amp;gt; wieder freizugeben.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
&lt;br /&gt;
==== Robert ====&lt;br /&gt;
Na mal schauen, ob irgendjemand diese Funktion wirklich benutzt. Ich fände es jedenfalls toll.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs_Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/DTMF-Encoder&amp;diff=14903</id>
		<title>C-Kurs/DTMF-Encoder</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/DTMF-Encoder&amp;diff=14903"/>
		<updated>2010-09-16T13:28:57Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Die Seite wurde neu angelegt: „In dieser Aufgabe soll ein Generator für DTMF-Töne erstellt werden. DTMF steht für &amp;lt;i&amp;gt;Dual-tone multi-frequency&amp;lt;/i&amp;gt; und ist auch als [http://de.wikipedia.org/w...“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll ein Generator für DTMF-Töne erstellt werden. DTMF steht für &amp;lt;i&amp;gt;Dual-tone multi-frequency&amp;lt;/i&amp;gt; und ist auch als [http://de.wikipedia.org/wiki/Mehrfrequenzwahlverfahren Mehrfrequenzwahlverfahren] bekannt.&lt;br /&gt;
&lt;br /&gt;
Wenn du diese Aufgabe in den Rechnerräumen bearbeitest, benutze bei dem Abspielen der Töne bitte Kopfhörer, um andere nicht zu stören.&lt;br /&gt;
&lt;br /&gt;
=== Was ist DTMF? ===&lt;br /&gt;
Kurz gesagt: ein DTMF-Ton besteht aus zwei überlagerten Sinuswellen. Für jede Taste auf dem Telefon ist eine bestimmte Frequenzkombination dieser beiden Wellen festgelegt. Genaueres sowie die Frequenzen für die Tasten finden sich [http://de.wikipedia.org/wiki/Mehrfrequenzwahlverfahren hier].&lt;br /&gt;
&lt;br /&gt;
=== Wie werden Töne im Rechner dargestellt? ===&lt;br /&gt;
Töne lassen sich als [http://de.wikipedia.org/wiki/Puls-Code-Modulation PCM]-Daten speichnern. Unser Programm soll solche PCM-Daten generieren. Ausreichend sind hier 8 Bit pro Sample, sodass sich die Tondaten in einem Array aus &amp;lt;tt&amp;gt;unsigned char&amp;lt;/tt&amp;gt; ablegen lassen. Die Samples sind dann vorzeichenlos, was bedeutet, dass bei 127 der Mittelwert ist. Als Samplerate reichen für uns auch recht niedrige 8 kHz, das heißt für jede Sekunde Ton werden 8000 Samples benötigt.&lt;br /&gt;
&lt;br /&gt;
== Aufgabenstellung ==&lt;br /&gt;
Jetzt soll Schritt für Schritt der Tongenerator implementiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Sinuswellen generieren ===&lt;br /&gt;
Schreibe eine Funktion, die Sinuswellen als Mono-8Bit-8kHz-PCM-Daten erzeugt. Der Funktion soll die gewünschte Länge des Tons, die Frequenz des Tons, und die Amplitude, sowie einen Pointer auf ein &amp;lt;i&amp;gt;int&amp;lt;/i&amp;gt;, in dem die Anzahl der generierten Samples abgelegt werden kann. Die Funktion soll dann ausreichend Speicher für die Daten allokieren und sie mit den passenden Sinuswerten befüllen und sie am Ende zurückgeben. Der Prototyp der Funktion sieht sollte also etwa so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;unsigned char* generateSine(int ms, int freq, float amplitude, int *numSamples)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Rufe nun in der main-Funktion die Generierungsfunktion auf und speichere die Daten mit &amp;lt;tt&amp;gt;fwrite&amp;lt;/tt&amp;gt; in eine Datei. Die Datei kann jetzt auf einem Linux-System auf einfache Weise abgespielt mit dem Kommando &amp;lt;tt&amp;gt;cat &amp;lt;i&amp;gt;audiofile&amp;lt;/i&amp;gt; &amp;gt; /dev/dsp&amp;lt;/tt&amp;gt; werden. Sie kann aber auch z.B. mit &amp;lt;i&amp;gt;mplayer&amp;lt;/i&amp;gt; abgespielt werden:&lt;br /&gt;
&amp;lt;tt&amp;gt;mplayer -rawaudio samplesize=1:channels=1:rate=8000 -demuxer &amp;lt;i&amp;gt;audiofile&amp;lt;/i&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Hinweis zum Debuggen ====&lt;br /&gt;
Um sich die Audiodaten anzusehen, kann das Programm [http://audacity.sourceforge.net/?lang=de Audacity] verwendet werden. Öffnen lassen sie sich dort über &amp;lt;i&amp;gt;Datei&amp;lt;/i&amp;gt; -&amp;gt; &amp;lt;i&amp;gt;Importieren&amp;lt;/i&amp;gt; -&amp;gt; &amp;lt;i&amp;gt;Rohdaten&amp;lt;/i&amp;gt;, dann die Datei auswählen, dann bei &amp;lt;i&amp;gt;Codec&amp;lt;/i&amp;gt; Unsigned 8 bit PCM, bei &amp;lt;i&amp;gt;Kanäle&amp;lt;/i&amp;gt; 1, bei &amp;lt;i&amp;gt;Samplefrequenz&amp;lt;/i&amp;gt; 8000 Hz auswählen. Nun kann man in die Samples reinzoomen (Button mit Lupe und Plus) und sehen, ob der Sinuswellen ordentlich sind. Mit &amp;lt;i&amp;gt;Analyse&amp;lt;/i&amp;gt; -&amp;gt; &amp;lt;i&amp;gt;Frequenzanalyse&amp;lt;/i&amp;gt; kann überprüft werden, ob die Sinuswelle die richtige Frequenz hat.&lt;br /&gt;
&lt;br /&gt;
=== Sinuswellen überlagern ===&lt;br /&gt;
Schreibe jetzt eine Funktion, die zwei Sinuswellen gleicher Länge überlagern kann. Die von ihr erstellte Samples sollen durch Addition der beiden Samples der Sinusdaten gebildet werden. Doch Vorsicht: da die Daten vorzeichenlos sind, müssen sie temporär vorzeichenbehaftet werden, so dass der Mittelwert 0 wird, dann können sie addiert werden und dann wieder vorzeichenlos abgespeichert werden (mit dem Mittelwert 127). Der Prototyp der Funktion sollte etwa so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;unsigned char* mixPcm(unsigned char *a, unsigned char *b, int numSamples)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test nun die Funktion wieder, indem du zwei Sinuswellen unterschiedlicher Frequenz erzeugst und sie mit der neuen Funktion überlagerst. Als Amplitude sollte jeweils etwas weniger als die Hälfte gewählt werden, um bei der Addition [http://de.wikipedia.org/wiki/Clipping_%28Signalverarbeitung%29 Clipping] zu vermeiden. Untersuche das Ergebnis wieder, wie in der ersten Teilaufgabe.&lt;br /&gt;
&lt;br /&gt;
=== DTMF-Töne ===&lt;br /&gt;
Schreibe eine Funktion, die für eine Ziffer zwischen 0 und 9 den passenden DTMF-Ton mithilfe der beiden vorigen Funktionen generieren kann. Ihr Prototyp kann etwa so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;unsigned char* generateDtmfTone(int number, int ms, int *numSamples)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Teste wieder. Zum Vergleich der Töne kannst du jetzt ein Telefon benutzen.&lt;br /&gt;
&lt;br /&gt;
=== Nummernsequenzen generieren ===&lt;br /&gt;
Benutze jetzt die Generierungsfunktion, um eine Folge von Ziffern in eine Datei zu schreiben. Die Töne sollten durch Stille getrennt sein. Du brauchst also noch eine Funktion, die Samples generiert, die alle den Wert 127 haben. Die Nummer soll als Kommandozeilenparameter oder Benutzereingabe eingegeben werden.&lt;br /&gt;
&lt;br /&gt;
Wenn du jetzt ein analoges Telefon zur Hand hast, kannst du die Töne ins Mikrofon des Hörers anspeilen und damit Nummern wählen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
&lt;br /&gt;
==== Robert ====&lt;br /&gt;
Na mal schauen, ob irgendjemand diese Funktion wirklich benutzt. Ich fände es jedenfalls toll.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs_Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs_2010/Vortrag01&amp;diff=14883</id>
		<title>C-Kurs 2010/Vortrag01</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs_2010/Vortrag01&amp;diff=14883"/>
		<updated>2010-09-15T16:47:28Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Einführung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Einführung =&lt;br /&gt;
&lt;br /&gt;
Vortragende: '''Paul''' &amp;lt;email&amp;gt;p.brodmann@gmx.de&amp;lt;/email&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Themen ===&lt;br /&gt;
* Organisatorisches&lt;br /&gt;
* Konzept von C&lt;br /&gt;
** Syntax&lt;br /&gt;
** Operatoren&lt;br /&gt;
* Hello World&lt;br /&gt;
* Compilereinführung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Folien ===&lt;br /&gt;
* [http://docs.freitagsrunde.org/Veranstaltungen/ckurs_2010/vortraege/01/Ckurs2010%20Vortrag1.pdf Folien]&lt;br /&gt;
&lt;br /&gt;
=== Mitschnitt ===&lt;br /&gt;
&lt;br /&gt;
==== Mittschnitt 2010 ====&lt;br /&gt;
[http://freitagsrunde.org/~jungnickel/PaulMaster.mov HighQuality] 1,1 GB&lt;br /&gt;
&lt;br /&gt;
Flash Version folgt&lt;br /&gt;
&lt;br /&gt;
==== Mittschnitt 2010 ====&lt;br /&gt;
&amp;lt;dhflashplayer&amp;gt;filepath=http://stan.freitagsrunde.org/c0/LE01.mp4|width=720|height=576&amp;lt;/dhflashplayer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Mittschnitt 2009 ====&lt;br /&gt;
* Audio: http://podcasts.freitagsrunde.org/C-Kurs-2009/ckurs_vl01.mp3&lt;br /&gt;
* [http://stan.freitagsrunde.org/c9/LE01.mp4 High Quality] (204MB &amp;lt;i&amp;gt;x264&amp;lt;/i&amp;gt;|ada2ce460c64fa15867ebf7b53a0db2c)&lt;br /&gt;
* [http://stan.freitagsrunde.org/c9/1-VL.mp3 Audio Podcast] (22MB &amp;lt;i&amp;gt;mp3&amp;lt;/i&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=14880</id>
		<title>C-Kurs/Übungsaufgaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=14880"/>
		<updated>2010-09-15T13:39:25Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Die Aufgaben */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wir haben jeder Aufgabe eine Einschätzung ihrer Schwierigkeit auf einer Skala von 1 bis 10 vorangestellt. Bei dieser Einschätzung sind wir von einem Gehirn ausgegangen, für welches das jeweilige Themengebiet völlig neu ist, das jedoch schon ein ganz gutes Verständnis dafür hat wie eine Programmiersprache denn so funktioniert. &lt;br /&gt;
Entsprechend kann eine schwer bewertete Aufgabe aus einem frühen Themengebiet für manch einen sehr einfach oder eine leicht bewertete aus einem späten Themengebiet für einen anderen sehr schwer sein. Es ist nur ein Wert, der euch helfen soll eure nächste Aufgabe zu wählen. &lt;br /&gt;
&lt;br /&gt;
Falls ihr Anmerkungen zu den Aufgaben habt, könnt ihr die Diskussionsseiten der jeweiligen Aufgaben nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeitsgrade ==&lt;br /&gt;
&lt;br /&gt;
#  Reines Tutorial. Man muss nicht viel selbst denken&lt;br /&gt;
#  ...&lt;br /&gt;
#  Leichte Übungsaufgabe. Studies, die noch eher unsicher sind werden hier gut begleitet.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Typische Aufgabe. Man muss den Kopf benutzen, bekommt an schwierigen Stellen aber Hilfestellungen.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Herausfordernd, eher etwas für Studies die etwas fitter sind.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Auch erfahrene Programmierer werden hier ein bis zwei Übungen beschäftigt sein&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#  Tja, die Idee war da. Wir finden sie auch gut, aber es könnte wirklich anstrengend werden.&lt;br /&gt;
&lt;br /&gt;
== Die Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;2&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
 |- bgcolor=&amp;quot;#D8D8D8&amp;quot;&lt;br /&gt;
 !Aufgabe&lt;br /&gt;
 !Schwierigkeit&lt;br /&gt;
 !Vorwissen&lt;br /&gt;
 !Lerneffekte&lt;br /&gt;
 !Bearbeiter&lt;br /&gt;
 !Korrektur gelesen&lt;br /&gt;
 !Musterlösung&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Von der Konsole zum HelloWorld | Von der Konsole zum HelloWorld]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Konsole benutzen, Hello World&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Fakultät | Fakultät]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Schleifen&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | Daniel (2009), &lt;br /&gt;
 |  &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/Pythagoras-Triplet | Pythagoras-Triplet]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Schleifen &amp;lt;br&amp;gt; if-Bedingungen&lt;br /&gt;
 | Gabriel P.&lt;br /&gt;
 | seba(2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2010/Pythagoras-Triplet/Musterloesung | Pythagoras-Triplet]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Fibonacci-Folge|Fibonacci-Folge]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Funktionen &amp;lt;br&amp;gt; Rekursion&lt;br /&gt;
 | Paul B.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2010)&lt;br /&gt;
 | &amp;lt;!--  [[Ckurs2009/Fibonacci-Folge/Musterlösung | Fibonacci-Folge]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/digitalesSchloesserKnacken|digitales Schloesser knacken]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Kontrollstrukturen &amp;lt;br&amp;gt;Bitweise Operatoren&lt;br /&gt;
 | Paul B.&lt;br /&gt;
 | Eugen R. (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/digitalesSchloesserKnacken/Musterlösung | digitales Schloesser knacken]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Rekursives_arbeiten|Rekursives Arbeiten]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3-5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Bekannte Operatoren wie + durch Funktionen succ und neg nachbilden&lt;br /&gt;
 | Eugen R.&lt;br /&gt;
 | Paul B.(2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Rekursives_arbeiten/Musterlösung | Rekursives Arbeiten]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Base64 | Base64]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Operatoren&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | Paul B.(2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Base64/Musterlösung | Base64]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe | Ein- und Ausgabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Ausgabe derselben&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/EingabeAusgabe/Musterlösung | Ein- und Ausgabe]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner | Taschenrechner]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Eingabe+Ausgabe&amp;lt;br&amp;gt;Mathematische Operatoren&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Taschenrechner/Musterlösung | Taschenrechner]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/VerschachtelteSchleifen | Verschachtelte Schleifen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Umgang mit mehreren verschachtelten Schleifen&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK (2009), &lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Glückspiel | Glücksspiel]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Anwenden von Fallunterscheidungen und Einlesen von Werten aus der Konsole&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Glückspiel/Musterlösung | Glückspiel]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs/Buchstaben_zählen | Buchstaben zählen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Array, Dateien lesen&lt;br /&gt;
 | Alex K.&lt;br /&gt;
 | Gabriel (2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Wochentag | Wochentagsrechnung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Mathematikverständniss&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (Musterlösung noch nicht vorhanden)  (2009), &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0 | Taschenrechner ''2.0'']]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Knobeln&amp;lt;br&amp;gt;Komplexes Aufgaben lösen&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | Martin K. (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Taschenrechner2.0/Musterlösung | Taschenrechner ''2.0'']] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Call by reference | Call by reference]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Einfache Anwendung von &amp;amp;/*&lt;br /&gt;
 | sping&lt;br /&gt;
 | nion (2009), Alex K. (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Call by reference/Musterlösung | Call by reference]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/String to Double | String to Double]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Original-Dokumentation anwenden (Opengroup, man pages)&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Const correctness&amp;lt;br&amp;gt;Strings&lt;br /&gt;
 | sping&lt;br /&gt;
 | Eugen R. (2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Text processing | Text processing]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4, 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Strings&amp;lt;br&amp;gt;Pointer-Arithmetik&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Refactoring&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Text processing/Musterlösung | Text processing]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Palindrome | Palindrome]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Pointer und Strings&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | nion (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Palindrome/Musterlösung | Palindrome ]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/(Pointer) Swapping | (Pointer) Swapping]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Pointer und Arrays benutzen, generisches swap&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | Katrin (2010, wird nochmal überarbeitet bzw. mit mehr erklärendem Text versehen)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/(Pointer) Swapping/Musterlösung | (Pointer) Swapping]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation | Matrizenmultiplikation]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mehrdimensionale Arrays&amp;lt;br&amp;gt;const correctness&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Matrizenmultiplikation/Musterlösung | Matrizenmultiplikation]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/DreiD | 3D mit C]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mathematische Rechenoperationen, Algorithmik&lt;br /&gt;
 | AndreasF&lt;br /&gt;
 | &lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe | Arrayuebergabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4/5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Pointer und Pointerarithmetik&lt;br /&gt;
 | nion&lt;br /&gt;
 | Martin K. (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Arrayuebergabe/Musterlösung | Arrayuebergabe]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank | Studentendatenbank]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | struct, Pointer, Arrays&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 | Gabriel (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Studentendatenbank/Musterlösung | Studentendatenbank]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/Punktstrukturen| Punktstrukturen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2-3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Structs, Unions, Pointer&lt;br /&gt;
 | [[Benutzer:Mutax|Florian]] (2010)&lt;br /&gt;
 | Alex K. (2010)&lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Sammelbestellung | Sammelbestellung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2-5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Listen, Pointer, Speicherverwaltung&lt;br /&gt;
 | [[Benutzer:Mutax|Florian]]&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Sammelbestellung/Musterlösung | Sammelbestellung]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Zahlen_sagen | Zahlen sagen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Umgang mit Zeichenketten&lt;br /&gt;
 | Martin K.&lt;br /&gt;
 | Paul B. (w.i.p.)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Zahlen_sagen/Musterlösung | Zahlen sagen]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Compiler, Präprozessor, Header Files | Compiler, Präprozessor, Header Files]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5. VL&lt;br /&gt;
 | Arbeiten mit mehreren Quellcode-Dateien, Kompilieren und Linken, Header-Dateien und #include, debugging-Makro verwenden&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | AndyF (2010)&lt;br /&gt;
 | &amp;lt;!-- [https://wiki.freitagsrunde.org/Ckurs2009/Vortrag05 siehe Folien] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Bus Error | Bus Error]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5. VL&lt;br /&gt;
 | Pointer, wie entsteht ein bus error&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Bus Error/Musterlösung | Bus Error]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/BubbleSortDebug | BubbleSort Debugging]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Debuggen eines Programmes mit gdb&lt;br /&gt;
 | aeichner&lt;br /&gt;
 |&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/BubbleSortDebug/Musterlösung | BubbleSort Debugging]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Debug | Debugging]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1-8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Debuggen einer Anwendung nach Wahl&lt;br /&gt;
 | aeichner&lt;br /&gt;
 |&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Code Layout | Code Layout]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7. VL&lt;br /&gt;
 | Kleinere Codeschipsel mit kleinen Unsauberkeiten&lt;br /&gt;
 | Daniel&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Code Layout/Musterlösung | Code Layout]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Refactoring | Refactoring]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7. VL&lt;br /&gt;
 | Wie verbessere ich den Quellcode eines Programmes.&lt;br /&gt;
 | Daniel&lt;br /&gt;
 | &lt;br /&gt;
 | &amp;lt;!-- [[Ckurs2009/Refactoring/Musterlösung | Refactoring]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Cat | Cat]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Arbeiten mit Dateien&amp;lt;br&amp;gt;Kommandozeilenparameter&lt;br /&gt;
 | nion&lt;br /&gt;
 | sping (2009), &lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Pong | Pong]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9.VL (eigentlich 2.VL)&lt;br /&gt;
 | allgemeiner Programmablauf, fortgeschrittene Konsolenausgaben/eingaben&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 | seba(2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden  --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Buchhaltung | Buchhaltung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5.VL&lt;br /&gt;
 | Lesen aus Dateien&lt;br /&gt;
 | reiner&lt;br /&gt;
 | AndyF (2010)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/StringArraySortieren | StringArraySortieren]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Konsolparameter, Funktionspointer, stdlib&lt;br /&gt;
 | reiner&lt;br /&gt;
 | martin (2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/integral | integral]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Funktionspointer&lt;br /&gt;
 | reiner&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | &amp;lt;!-- [[Ckurs/integral/Musterlösung | Musterloesung]] --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs/forschleife | forschleife]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Bug (zum Knobeln)&lt;br /&gt;
 | reiner&lt;br /&gt;
 | nion (2009), [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/libgdsl | GDSL]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | Anwendung der Generic Data Structures Library&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/StdLib | Standard C Library]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | Recherche in der Standard C Bibliothek&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/Tron | Tron]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | SDL (Simple Directmedia Layer) kennen lernen, graphische Ausgabe&lt;br /&gt;
 | seba&lt;br /&gt;
 |&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/TicTacToe | TicTacToe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | SDL (Simple Directmedia Layer) kennen lernen, graphische Ausgabe&lt;br /&gt;
 | Martin&lt;br /&gt;
 |&lt;br /&gt;
 | &amp;lt;!-- vorhanden --&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Kleine und große Probleme ==&lt;br /&gt;
&lt;br /&gt;
* Die Tubit-Accounts haben nicht /bin/bash als shell, so dass die &amp;lt;strong&amp;gt;Cursortasten&amp;lt;/strong&amp;gt; nicht funktionieren. Workaround: als erstes Kommando 'bash' eingeben, man sieht dann auch in welchem Verzeichnis man gerade ist.&lt;br /&gt;
* wenn man nur den Promt 'bash-0.12' oder so erhält, also ohne das Verzeichnis in dem man ist, folgendes Kommando eingeben: &amp;lt;tt&amp;gt;export PS1='\u@\h:\w$ '&amp;lt;/tt&amp;gt; oder zum dauerhaften Speichern: &amp;lt;tt&amp;gt; echo &amp;quot;export PS1='\u@\h:\w$ '&amp;quot; &amp;gt;&amp;gt; ~/.bashrc &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Musterlösungen ==&lt;br /&gt;
Die Lösungen zu den Aufgaben werden nach den jeweiligen Übungen hier veröffentlicht. Falls dies nicht geschieht, bitte den zuständigen Tutor fragen.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Ckurs2009/Feedback|Feedback zum Kurs 2009]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Punktstrukturen&amp;diff=14853</id>
		<title>C-Kurs/Punktstrukturen</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Punktstrukturen&amp;diff=14853"/>
		<updated>2010-09-14T17:17:46Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll eine Programm erstellt werden, dass Punkte in verschiedenen Koordinatensystemen 'verwalten' und beim Rechnen automatisch konvertieren kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
=== Teil a ===&lt;br /&gt;
&lt;br /&gt;
Schreibe je eine &amp;lt;i&amp;gt;struct&amp;lt;/i&amp;gt; &amp;lt;tt&amp;gt;punkt_cart&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;punkt_polar&amp;lt;/tt&amp;gt;, die einen Punkt in Kartesischen bzw. Polarkoordinaten beschreibt sowie Hilfsfunktionen, um solche Punkte zu erzeugen und die Entfernung zwischen Punkten desselben Koordinatensystems zu berechnen.&lt;br /&gt;
&lt;br /&gt;
=== Teil b ===&lt;br /&gt;
&lt;br /&gt;
Schreibe Hilfsfunktionen, die die Punkte von einem Typ in einen anderen konvertieren. Dabei soll die bei C typische Vorgehensweise beachtet werden:&lt;br /&gt;
&lt;br /&gt;
Zunächst wird für den neuen Punkt Speicher alloziiert, dann wird die Hilfsfunktion mit zwei Pointern aufgerufen - dem vorhandenen Punkt und dem Speicherplatz für den umgewandelten Punkt. Der Rückgabewert der Hilfsfunktion soll angeben, ob die Konvertierung erfolgreich war.&lt;br /&gt;
&lt;br /&gt;
=== Teil c ===&lt;br /&gt;
&lt;br /&gt;
Schreibe das Programm nun so um, dass es nur noch eine Art von Punkten gibt. Diese soll intern eine &amp;lt;i&amp;gt;union&amp;lt;/i&amp;gt; enthalten, um beide Arten von Koordinatensystemen verarbeiten zu können. In der umgebenden &amp;lt;i&amp;gt;struct&amp;lt;/i&amp;gt; soll in einem &amp;lt;i&amp;gt;enum&amp;lt;/i&amp;gt; der Typ des Koordinatensystems gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
Die Hilfsfunkion zum Berechnen der Entfernungen zwischen Punkten soll nun mit unterschiedlichen Punkten aufgerufen werden können und die korrekte Entfernung der Punkte zueinander ausgeben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe ===&lt;br /&gt;
Schreibe ein Programm, dass die Koordinaten und Farben von Punkten auf der Standardeingabe entgegennimmt. Anhand der Eingabe soll das Koordinatensystem erkannt werden (float, int) rrggbb  oder (int,int) rrggbb.&lt;br /&gt;
&lt;br /&gt;
Das Programm soll dann die Entfernung aller Punkte zueinander berechnen und die Punkte grafisch darstellen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=14852</id>
		<title>C-Kurs/Übungsaufgaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=14852"/>
		<updated>2010-09-14T17:08:17Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Die Aufgaben */ zwei Reviews für mich&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wir haben jeder Aufgabe eine Einschätzung ihrer Schwierigkeit auf einer Skala von 1 bis 10 vorangestellt. Bei dieser Einschätzung sind wir von einem Gehirn ausgegangen, für welches das jeweilige Themengebiet völlig neu ist, das jedoch schon ein ganz gutes Verständnis dafür hat wie eine Programmiersprache denn so funktioniert. &lt;br /&gt;
Entsprechend kann eine schwer bewertete Aufgabe aus einem frühen Themengebiet für manch einen sehr einfach oder eine leicht bewertete aus einem späten Themengebiet für einen anderen sehr schwer sein. Es ist nur ein Wert, der euch helfen soll eure nächste Aufgabe zu wählen. &lt;br /&gt;
&lt;br /&gt;
Falls ihr Anmerkungen zu den Aufgaben habt, könnt ihr die Diskussionsseiten der jeweiligen Aufgaben nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeitsgrade ==&lt;br /&gt;
&lt;br /&gt;
#  Reines Tutorial. Man muss nicht viel selbst denken&lt;br /&gt;
#  ...&lt;br /&gt;
#  Leichte Übungsaufgabe. Studies, die noch eher unsicher sind werden hier gut begleitet.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Typische Aufgabe. Man muss den Kopf benutzen, bekommt an schwierigen Stellen aber Hilfestellungen.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Herausfordernd, eher etwas für Studies die etwas fitter sind.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Auch erfahrene Programmierer werden hier ein bis zwei Übungen beschäftigt sein&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#  Tja, die Idee war da. Wir finden sie auch gut, aber es könnte wirklich anstrengend werden.&lt;br /&gt;
&lt;br /&gt;
== Die Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;2&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
 |- bgcolor=&amp;quot;#D8D8D8&amp;quot;&lt;br /&gt;
 !Aufgabe&lt;br /&gt;
 !Schwierigkeit&lt;br /&gt;
 !Vorwissen&lt;br /&gt;
 !Lerneffekte&lt;br /&gt;
 !Bearbeiter&lt;br /&gt;
 !Korrektur gelesen&lt;br /&gt;
 !Musterlösung&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Von der Konsole zum HelloWorld | Von der Konsole zum HelloWorld]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Konsole benutzen, Hello World&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Fakultät | Fakultät]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Schleifen&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | Daniel (2009), &lt;br /&gt;
 |  &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/Pythagoras-Triplet | Pythagoras-Triplet]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Schleifen &amp;lt;br&amp;gt; if-Bedingungen&lt;br /&gt;
 | Gabriel P.&lt;br /&gt;
 | seba(in arbeit)&lt;br /&gt;
 | [[Ckurs2010/Pythagoras-Triplet/Musterloesung | Pythagoras-Triplet]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Fibonacci-Folge|Fibonacci-Folge]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Funktionen &amp;lt;br&amp;gt; Rekursion&lt;br /&gt;
 | Paul B.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2010)&lt;br /&gt;
 | [[Ckurs2009/Fibonacci-Folge/Musterlösung | Fibonacci-Folge]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/digitalesSchloesserKnacken|digitales Schloesser knacken]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Kontrollstrukturen &amp;lt;br&amp;gt;Bitweise Operatoren&lt;br /&gt;
 | Paul B.&lt;br /&gt;
 | Eugen R. (2010)&lt;br /&gt;
 | [[Ckurs2009/digitalesSchloesserKnacken/Musterlösung | digitales Schloesser knacken]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Rekursives_arbeiten|Rekursives Arbeiten]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3-5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Bekannte Operatoren wie + durch Funktionen succ und neg nachbilden&lt;br /&gt;
 | Eugen R.&lt;br /&gt;
 | Paul B.(2010)&lt;br /&gt;
 | [[Ckurs2009/Rekursives_arbeiten/Musterlösung | Rekursives Arbeiten]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Base64 | Base64]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Operatoren&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | Paul B.(2010)&lt;br /&gt;
 | [[Ckurs2009/Base64/Musterlösung | Base64]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe | Ein- und Ausgabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Ausgabe derselben&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (2009), &lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe/Musterlösung | Ein- und Ausgabe]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner | Taschenrechner]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Eingabe+Ausgabe&amp;lt;br&amp;gt;Mathematische Operatoren&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2009), &lt;br /&gt;
 | [[Ckurs2009/Taschenrechner/Musterlösung | Taschenrechner]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/VerschachtelteSchleifen | Verschachtelte Schleifen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Umgang mit mehreren verschachtelten Schleifen&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK (2009), &lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Glückspiel | Glücksspiel]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Anwenden von Fallunterscheidungen und Einlesen von Werten aus der Konsole&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK (2009), &lt;br /&gt;
 | [[Ckurs2009/Glückspiel/Musterlösung | Glückspiel]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Wochentag | Wochentagsrechnung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Mathematikverständniss&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (Musterlösung noch nicht vorhanden)  (2009), &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0 | Taschenrechner ''2.0'']]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Knobeln&amp;lt;br&amp;gt;Komplexes Aufgaben lösen&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | Martin K. (2009), &lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0/Musterlösung | Taschenrechner ''2.0'']]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Call by reference | Call by reference]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Einfache Anwendung von &amp;amp;/*&lt;br /&gt;
 | sping&lt;br /&gt;
 | nion (2009), Alex K. (2010)&lt;br /&gt;
 | [[Ckurs2009/Call by reference/Musterlösung | Call by reference]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/String to Double | String to Double]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Original-Dokumentation anwenden (Opengroup, man pages)&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Const correctness&amp;lt;br&amp;gt;Strings&lt;br /&gt;
 | sping&lt;br /&gt;
 | Eugen R. (2010)&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Text processing | Text processing]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4, 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Strings&amp;lt;br&amp;gt;Pointer-Arithmetik&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Refactoring&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | [[Ckurs2009/Text processing/Musterlösung | Text processing]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Palindrome | Palindrome]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Pointer und Strings&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | nion (2009), &lt;br /&gt;
 | [[Ckurs2009/Palindrome/Musterlösung | Palindrome ]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs/Buchstaben_zählen | Buchstaben zählen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Array, Dateien lesen&lt;br /&gt;
 | Alex K.&lt;br /&gt;
 | Gabriel (2010)&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/(Pointer) Swapping | (Pointer) Swapping]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Pointer und Arrays benutzen, generisches swap&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | Katrin (2010, wird nochmal überarbeitet bzw. mit mehr erklärendem Text versehen)&lt;br /&gt;
 | [[Ckurs2009/(Pointer) Swapping/Musterlösung | (Pointer) Swapping]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation | Matrizenmultiplikation]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mehrdimensionale Arrays&amp;lt;br&amp;gt;const correctness&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation/Musterlösung | Matrizenmultiplikation]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/DreiD | 3D mit C]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mathematische Rechenoperationen, Algorithmik&lt;br /&gt;
 | AndreasF&lt;br /&gt;
 | &lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe | Arrayuebergabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4/5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Pointer und Pointerarithmetik&lt;br /&gt;
 | nion&lt;br /&gt;
 | Martin K. (2009), &lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe/Musterlösung | Arrayuebergabe]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank | Studentendatenbank]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | struct, Pointer, Arrays&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 | Gabriel (2010)&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank/Musterlösung | Studentendatenbank]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2010/Punktstrukturen| Punktstrukturen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2-3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Structs, Unions, Pointer&lt;br /&gt;
 | [[Benutzer:Mutax|Florian]] (2010)&lt;br /&gt;
 | Alex K. (2010)&lt;br /&gt;
 |  -&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Sammelbestellung | Sammelbestellung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2-5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Listen, Pointer, Speicherverwaltung&lt;br /&gt;
 | [[Benutzer:Mutax|Florian]]&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2009), &lt;br /&gt;
 |  [[Ckurs2009/Sammelbestellung/Musterlösung | Sammelbestellung]] &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Zahlen_sagen | Zahlen sagen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | Umgang mit Zeichenketten&lt;br /&gt;
 | Martin K.&lt;br /&gt;
 | Paul B. (w.i.p.)&lt;br /&gt;
 | [[Ckurs2009/Zahlen_sagen/Musterlösung | Zahlen sagen]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Compiler, Präprozessor, Header Files | Compiler, Präprozessor, Header Files]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5. VL&lt;br /&gt;
 | Arbeiten mit mehreren Quellcode-Dateien, Kompilieren und Linken, Header-Dateien und #include, debugging-Makro verwenden&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | AndyF (2010)&lt;br /&gt;
 | [https://wiki.freitagsrunde.org/Ckurs2009/Vortrag05 siehe Folien]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Bus Error | Bus Error]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5. VL&lt;br /&gt;
 | Pointer, wie entsteht ein bus error&lt;br /&gt;
 | Katrin&lt;br /&gt;
 | [[Benutzer:Mario|Mario]] (2010)&lt;br /&gt;
 | [[Ckurs2009/Bus Error/Musterlösung | Bus Error]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/BubbleSortDebug | BubbleSort Debugging]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Debuggen eines Programmes mit gdb&lt;br /&gt;
 | aeichner&lt;br /&gt;
 |&lt;br /&gt;
 | [[Ckurs2009/BubbleSortDebug/Musterlösung | BubbleSort Debugging]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Debug | Debugging]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1-8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Debuggen einer Anwendung nach Wahl&lt;br /&gt;
 | aeichner&lt;br /&gt;
 |&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Code Layout | Code Layout]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7. VL&lt;br /&gt;
 | Kleinere Codeschipsel mit kleinen Unsauberkeiten&lt;br /&gt;
 | Daniel&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | [[Ckurs2009/Code Layout/Musterlösung | Code Layout]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Refactoring | Refactoring]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-9&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7. VL&lt;br /&gt;
 | Wie verbessere ich den Quellcode eines Programmes.&lt;br /&gt;
 | Daniel&lt;br /&gt;
 | &lt;br /&gt;
 | [[Ckurs2009/Refactoring/Musterlösung | Refactoring]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Cat | Cat]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Arbeiten mit Dateien&amp;lt;br&amp;gt;Kommandozeilenparameter&lt;br /&gt;
 | nion&lt;br /&gt;
 | sping (2009), &lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Pong | Pong]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9.VL (eigentlich 2.VL)&lt;br /&gt;
 | allgemeiner Programmablauf, fortgeschrittene Konsolenausgaben/eingaben&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 | seba(2010)&lt;br /&gt;
 | vorhanden &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Buchhaltung | Buchhaltung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5.VL&lt;br /&gt;
 | Lesen aus Dateien&lt;br /&gt;
 | reiner&lt;br /&gt;
 | AndyF (2010)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/StringArraySortieren | StringArraySortieren]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Konsolparameter, Funktionspointer, stdlib&lt;br /&gt;
 | reiner&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/integral | integral]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Funktionspointer&lt;br /&gt;
 | reiner&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | [[Ckurs/integral/Musterlösung | Musterloesung]]&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs/forschleife | forschleife]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6. VL&lt;br /&gt;
 | Bug (zum Knobeln)&lt;br /&gt;
 | reiner&lt;br /&gt;
 | nion (2009), [[Benutzer:Tkroenert|TKroenert]] (2010)&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/libgdsl | GDSL]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5-7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | Anwendung der Generic Data Structures Library&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/StdLib | Standard C Library]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |9. VL&lt;br /&gt;
 | Recherche in der Standard C Bibliothek&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs/Tron | Tron]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |7-8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4. VL&lt;br /&gt;
 | SDL (Simple Directmedia Layer) kennen lernen, graphische Ausgabe&lt;br /&gt;
 | seba&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Kleine und große Probleme ==&lt;br /&gt;
&lt;br /&gt;
* Die Tubit-Accounts haben nicht /bin/bash als shell, so dass die &amp;lt;strong&amp;gt;Cursortasten&amp;lt;/strong&amp;gt; nicht funktionieren. Workaround: als erstes Kommando 'bash' eingeben, man sieht dann auch in welchem Verzeichnis man gerade ist.&lt;br /&gt;
* wenn man nur den Promt 'bash-0.12' oder so erhält, also ohne das Verzeichnis in dem man ist, folgendes Kommando eingeben: &amp;lt;tt&amp;gt;export PS1='\u@\h:\w$ '&amp;lt;/tt&amp;gt; oder zum dauerhaften Speichern: &amp;lt;tt&amp;gt; echo &amp;quot;export PS1='\u@\h:\w$ '&amp;quot; &amp;gt;&amp;gt; ~/.bashrc &amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Musterlösungen ==&lt;br /&gt;
Die Lösungen zu den Aufgaben werden nach den jeweiligen Übungen hier veröffentlicht. Falls dies nicht geschieht, bitte den zuständigen Tutor fragen.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Ckurs2009/Feedback|Feedback zum Kurs 2009]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Buchstaben_z%C3%A4hlen/Musterl%C3%B6sung&amp;diff=14835</id>
		<title>C-Kurs/Buchstaben zählen/Musterlösung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Buchstaben_z%C3%A4hlen/Musterl%C3%B6sung&amp;diff=14835"/>
		<updated>2010-09-13T11:30:07Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Die Seite wurde neu angelegt: „&amp;lt;pre&amp;gt; #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;stdlib.h&amp;gt;  void printBar(int length) {     int i;     for (i = 0; i &amp;lt; length; i++) {         printf(&amp;quot;#&amp;quot;);     } }  int main(int...“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void printBar(int length) {&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i = 0; i &amp;lt; length; i++) {&lt;br /&gt;
        printf(&amp;quot;#&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv) {&lt;br /&gt;
    if (argc != 2) {&lt;br /&gt;
        printf(&amp;quot;missing filename\n&amp;quot;);&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // open file&lt;br /&gt;
    FILE *file = fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
    if (file == NULL) {&lt;br /&gt;
        printf(&amp;quot;cannot open file\n&amp;quot;);&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // initialize counting array&lt;br /&gt;
    int counts[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};&lt;br /&gt;
    int allCount = 0;&lt;br /&gt;
&lt;br /&gt;
    // read every character in the file and count if it's a letter&lt;br /&gt;
    while (1) {&lt;br /&gt;
        int character = fgetc(file);&lt;br /&gt;
        if (character &amp;lt; 0) {&lt;br /&gt;
            // we reached end of file&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        if (character &amp;gt;= 'A' &amp;amp;&amp;amp; character &amp;lt;= 'Z') {&lt;br /&gt;
            // we found a capital letter&lt;br /&gt;
            counts[character - 'A']++;&lt;br /&gt;
            allCount++;&lt;br /&gt;
        } else if (character &amp;gt;= 'a' &amp;amp;&amp;amp; character &amp;lt;= 'z') {&lt;br /&gt;
            // we found a letter&lt;br /&gt;
            counts[character - 'a']++;&lt;br /&gt;
            allCount++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // close the file&lt;br /&gt;
    fclose(file);&lt;br /&gt;
&lt;br /&gt;
    // print the results&lt;br /&gt;
    int i;&lt;br /&gt;
    for (i = 0; i &amp;lt; 26; i++) {&lt;br /&gt;
        printf(&amp;quot;%c : %3d  &amp;quot;, (char)(i + 'A'), counts[i]);&lt;br /&gt;
        printBar((counts[i] * 300) / allCount);&lt;br /&gt;
        printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Buchstaben_z%C3%A4hlen&amp;diff=14834</id>
		<title>C-Kurs/Buchstaben zählen</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Buchstaben_z%C3%A4hlen&amp;diff=14834"/>
		<updated>2010-09-13T11:27:53Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Aufgabenstellung präzisiert und Zusatzaufgabe&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Aufgabenstellung ==&lt;br /&gt;
&lt;br /&gt;
Schreibe ein Programm, das die Vorkommnisse aller Buchstaben in einer Datei zählt und anschließend ausgibt. Dabei sollen Groß- und Kleinbuchstaben zusammengefasst werden. Verwende die folgende Vorgabe:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
     if (argc != 2) {&lt;br /&gt;
         printf(&amp;quot;missing filename\n&amp;quot;);&lt;br /&gt;
         return 0;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     // open file&lt;br /&gt;
     FILE *file = fopen(argv[1], &amp;quot;r&amp;quot;);&lt;br /&gt;
     if (file == NULL) {&lt;br /&gt;
         printf(&amp;quot;cannot open file\n&amp;quot;);&lt;br /&gt;
         return 0;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     // TODO your code here&lt;br /&gt;
 &lt;br /&gt;
     // close the file&lt;br /&gt;
     fclose(file);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Hinweis zum Dateienlesen ==&lt;br /&gt;
Für diese Aufgabe werden folgende File-IO-Funktionen benötigt. Die ersten beiden sind in der Vorgabe schon vorhanden.&lt;br /&gt;
* &amp;lt;tt&amp;gt;fopen(filename, &amp;quot;r&amp;quot;)&amp;lt;/tt&amp;gt; öffnet die Datei unter dem angegebenen Dateinamen im Nur-Lese-Modus und gibt einen FILE-Pointer zurück, mit dem im Folgenden auf die Datei zugegriffen werden kann.&lt;br /&gt;
* &amp;lt;tt&amp;gt;fclose(file)&amp;lt;/tt&amp;gt; schließt die Datei.&lt;br /&gt;
* &amp;lt;tt&amp;gt;fgetc(file)&amp;lt;/tt&amp;gt; liest ein Zeichen der Datei. Ist die Datei zuende, gibt die Funktion &amp;lt;tt&amp;gt;-1&amp;lt;/tt&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
== Hinweis zum Umgang mit chars ==&lt;br /&gt;
Mit &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; kann man genauso rechnen, wie mit &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Die Berechnung &amp;lt;tt&amp;gt;character-'a'&amp;lt;/tt&amp;gt; ergibt also die Position des Buchstaben im Alphabet, wenn &amp;lt;tt&amp;gt;character&amp;lt;/tt&amp;gt; zwischen &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;z&amp;lt;/tt&amp;gt; in der [http://de.wikipedia.org/wiki/ASCII-Tabelle ASCII-Tabelle] liegt.&lt;br /&gt;
&lt;br /&gt;
== Zusatzaufgabe ==&lt;br /&gt;
Verschönere die Ausgabe so, dass für jede Buchstabenhäufigkeit eine visuelle Ausgabe (z.B. in Form eines Balkens aus &amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;) angezeigt wird, die den relativen Anteil des Buchstabens darstellt.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
&lt;br /&gt;
==== Robert ====&lt;br /&gt;
Na mal schauen, ob irgendjemand diese Funktion wirklich benutzt. Ich fände es jedenfalls toll.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs_Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=Freitagsrunde:Mitglieder&amp;diff=13157</id>
		<title>Freitagsrunde:Mitglieder</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=Freitagsrunde:Mitglieder&amp;diff=13157"/>
		<updated>2009-12-10T18:14:44Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''Mitglieder'' ist vielleicht nicht das richtige Wort, denn es gibt bei uns keine feste Mitgliedschaft, jeder der mitmachen möchte, ist herzlich willkommen und niemand ist zu irgendetwas gezwungen. Auf dieser Seite möchten wir, die Leute die hinter der [[Freitagsrunde]] stehen, uns Euch kurz vorstellen.&lt;br /&gt;
&lt;br /&gt;
(zu den [[Freitagsrunde:Ehemalige_Mitglieder|ehemaligen Mitgliedern]].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Dirk Babendererde (&amp;lt;email&amp;gt;dirk@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:DirkBabendererde.jpg|thumb|150px|Dirk Babendererde]]&lt;br /&gt;
Hallo, ich bin der Dirk und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mario Bodemann ([mailto:mario@freitagsrunde.org mario@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Mario.jpg|thumb|150px|Mario Bodemann]]&lt;br /&gt;
Seitdem ich im Sommer 2004 mein Abi abgeschlossen habe, studiere ich hier an der TU B Informatik auf Diplom. &lt;br /&gt;
&lt;br /&gt;
Ich engagiere mich für Belange, die es rund um das Studium gibt. So bin ich&lt;br /&gt;
aktiv in der Ausbildungskommision, der Einführungswoche, dem Eclipsekurs 2008 und dem was sonst noch so anfällt. Als Studienschwerpunkte habe ich Computer Graphics und Software Technik, von denen ich erwarte, dass Sie eine gute Kombination ergeben könnten ...&lt;br /&gt;
&lt;br /&gt;
Und falls jemand T-Shirts oder&lt;br /&gt;
sonstige Fanartikel von der Freitagsrunde haben will, dann bin ich euer Ansprechpartner :-)&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Robert Buchholz ([mailto:rbu@freitagsrunde.org rbu@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Foto-Robert-Buchholz.jpg|thumb|150px|Robert Buchholz]]&lt;br /&gt;
Ich studiere an der TU Berlin seit dem Sommer 2004 und werde bald mit dem Informatik-Diplom abschließen. In der Freitagsrunde bin ich erst seit 2006 mit dabei, konnte mich aber seitdem an vielen Projekten beteiligen. Neben den Java- und Eclipsekursen habe ich großen Spaß an [[Linux-Installationsparty]]s und Ähnlichem. Ich habe im letzten Jahr [[Opalix 2006]] erstellt, und hoffe bald mal mit der [[AG Rechnerinstallation]] aus dem Knick zu kommen.&lt;br /&gt;
&lt;br /&gt;
Was ich innerhalb und außerhalb der Freitagsrunde sonst so organisiere, erfahrt ihr über [[Benutzer:Buchholz|meine Benutzerseite]].&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kai Dietrich ([mailto:kai@freitagsrunde.org kai@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Foto-Kai-Dietrich.jpg|thumb|150px|Kai Dietrich]]&lt;br /&gt;
Ich studiere seit dem WS2003/04 Informatik an der TU Berlin. Obwohl ich der Freitagsrunde (natuerlich) schon in der Einfuehrungswoche begegnet bin, habe ich erst im WS2006/07 hier her gefunden und festgestellt, dass studieren viel mehr Spass macht, wenn man es gemeinsam tut.&lt;br /&gt;
Im uebrigen bin ich, als Verfechter des amerikanischen Tastaturlayouts, gegen Umlaute.&lt;br /&gt;
[[Benutzer:Cleeus|...read more]]&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Michael Dietzel ([mailto:michael.dietzel(_A.T_)mailbox.tu-berlin.de michael.dietzel-_A.T_)mailbox.tu-berlin.de]) ==&lt;br /&gt;
[[Bild:Foto-Michael-Dietzel.jpg|thumb|150px|Michael Dietzel]]&lt;br /&gt;
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut consectetuer, tortor ac pretium laoreet, enim lectus iaculis ante, sit amet aliquet nisl diam tempus magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam orci. Quisque egestas. Donec ullamcorper, pede ac ultricies venenatis, leo nisi rutrum sem, id congue nibh nisl vel nulla. Praesent id mi. Vivamus enim neque, elementum vel, elementum sed, pretium et, arcu. Curabitur leo. Etiam tristique orci viverra ligula. Nam ultricies. Donec aliquet varius elit. Maecenas massa. Nullam justo. Donec sagittis magna id lectus ultrices semper. Etiam laoreet lorem quis purus. Nam justo purus, euismod ut, porta a, eleifend id, pede. Sed tincidunt ipsum a arcu. &lt;br /&gt;
[[Benutzer:mimos|...read more]]&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sebastian Drews (&amp;lt;email&amp;gt;sdrews@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:SebastianDrews.jpg|thumb|150px|Sebastian Drews]]&lt;br /&gt;
Hallo, ich bin der Sebastian und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sebastian Dyroff ([mailto:sdyroff@freitagsrunde.org sdyroff@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:SebastianDyroff.jpg|thumb|150px|Sebastian Dyroff]]&lt;br /&gt;
Ich studiere Informatik seit dem Wintersemester 2005/06. Zur Freitagsrunde kam ich erst etwas später: nämlich im Wintersemester 2006/07. Als erstes wurde ich damals in die Wahlliste der Freitagsrunde eingetragen. Dadurch konnte ich mich während den letzten 2 Jahren aktiv an der Unipolitik beteiligen. Natürlich habe ich mich auch an vielen anderen Aktivitäten der Freitagsrunde beteiligt. Seit 2008 bin ich Tutor des [http://www.kbs.tu-berlin.de/menue/lehre/wintersemester_200809/rechnersicherheit Praktikums Rechnersicherheit].&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alexander Eichner ([mailto:alex@freitagsrunde.org alex@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Alexander.jpg|thumb|150px|Alexander Eichner]]&lt;br /&gt;
&lt;br /&gt;
Ich studiere seit dem Wintersemester 07/08 technische Informatik im Bachelor-Studiengang an der TU-Berlin. In der Freitagsrunde beteilige ich mich an Opalix, um auch den armen Windows-Usern das Leben im ersten Semester so einfach wie möglich zu machen ;-) und war im Wintersemester Tutor in der Einführungswoche.&lt;br /&gt;
Ausserdem versuche ich durch das Mitwirken in der AK den TI-Studiengang zu verbessern. Nebenbei noch als Entwickler arbeite und engagiere mich auch im Technischen Hilfswerk  ([http://www.thw-oelgruppe.de]). Wenn es die Zeit erlaubt spiele ich auch Volleyball.&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Jannes Eilers (&amp;lt;email&amp;gt;eilers@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:JannesEilers.jpg|thumb|150px|Jannes Eilers]]&lt;br /&gt;
Hallo, ich bin der Jannes und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Jörg Ferdinand (&amp;lt;email&amp;gt;joerg@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:JörgFerdinand.jpg|thumb|150px|Jörg Ferdinand]]&lt;br /&gt;
Hallo, ich bin der Jörg und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Timo Glaser ([mailto:timo@freitagsrunde.org timo@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Foto-timo.jpeg|framed|Timo Glaser]]&lt;br /&gt;
&lt;br /&gt;
Im Wintersemester 2001/02 begann mein Studium der Informatik und somit meine Zeit an der TU Berlin. Damals gab es keine politische Liste an der Fakultät, die meinen Vorstellungen politischen Engagements entsprach, so dass ich mich mit einigen anderen interessierten Studierenden zusammenschloss - die Freitagsrunde war geboren ...&lt;br /&gt;
&lt;br /&gt;
Jedoch konnte ich mich für zwei Jahre nicht so an der Universitätspolitik beteiligen, wie ich es gerne gewollt hätte. Nach Beendigung meines Grundstudiums nahm ich am [[Doppeldiplom SJTU | Doppeldiplomprogramm]] mit der Shanghai Jiao Tong University teil. Dies ist meiner Meinung nach eine der größten Errungenschaften der Fakultät - eine großartige Chance, die man sich nicht entgehen lassen sollte.&lt;br /&gt;
&lt;br /&gt;
Im Sommer 2005 gründete ich mit vier anderen Studenten ein Unternehmen mit Fokus Wissensmanagement, die [http://www.peritor.com/ Peritor Wissensmanagement GmbH]. Da ich jedoch weiterhin wissenschaftlich arbeiten wollte und ein Thema fand, welches mich sehr faszinierte, habe ich nach Abschluss meines Studiums (Silvester 2006 ;) eine Promotion bei Professor Lutterbeck, [http://www.ig.cs.tu-berlin.de/ Informatik und Gesellschaft], begonnen. Hier, sowie in der [http://www.sysedv.tu-berlin.de/Homepage/SYSEDV.nsf?Open&amp;amp;Key=56QJT8&amp;amp;Sel&amp;amp;ID=3B9F9B7F8A9427A4C12570B30075790F  Information Security Management Forschungsgruppe] des Systemanalyse und EDV Lehrstuhls, halte ich auch vereinzelt Vorträge im Rahmen von Lehrveranstaltungen.&lt;br /&gt;
&lt;br /&gt;
Ich vertrete somit die Sichtweise der Promotionsstudierenden bzw. externen Doktoranden.&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Andreas Gunschl ([mailto:agunschl@mailbox.tu-berlin.de]) ==&lt;br /&gt;
[[Bild:AndreasGunschl.jpg|thumb|150px|Andreas Gunschl]]&lt;br /&gt;
Hai, ich studiere wie viele hier Informatik und interessiere mich sehr für Programmiersprachen wie Java und Groovy. Ich bin seit 7 Jahren in Berlin und eigentlich ein gebürtiger Österreicher^^. Ich bin zur Freitagsrunde gekommen weil es eine nette Bande von Leuten ist mit denen ich gerne abhänge, wissen austausche und Kicker zocke^^. Nebenbei geh ich gerne Schifahren, Radfahren und spiele manchmal Eishockey. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Daniel Käs ([mailto:dkaes@cs.tu-berlin.de dkaes@cs.tu-berlin.de]) ==&lt;br /&gt;
[[Bild:Foto-DanielKaes.jpg|thumb|150px|Daniel Käs]]&lt;br /&gt;
Ich studiere Informatik seit dem WS03/04. Ich bin vor allem bei der Freitagsrunde, um anderen Studenten bei ihrem Studium zu helfen ohne mich dabei einer bestimmten politischen Gesinnung unterordnen zu müssen. Außerdem habe ich Spaß dabei andere Menschen für Informatikthemen zu begeistern, weshalb ich nicht nur bei den Javakursen, sondern auch Informationsveranstaltungen wie [[Linux-Installationsparty_2007|LIPs]] oder [[Distro-Bash_2007|Distro-Bashs]] gerne mithelfe. Neuerdings organisiere ich auch den Freitagsrunden [[TechTalk|TechTalk]].&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Thomas Kaschwig ([mailto:thomas@freitagsrunde.org thomas@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Foto-thomas.jpeg|framed|Thomas Kaschwig]]&lt;br /&gt;
Ich habe an der [[TU Berlin]] [[Informatik]] studiert und arbeite nun nach Abschluss meines Studiums als [[Wissenschaftlicher Mitarbeiter]] an der [[Fakultät IV]]. Im Jahr 2002 habe ich zusammen mit einigen Kommilitonen die [[Freitagsrunde]] gegründet, da wir uns hochschulpolitisch engagieren wollten und mit den bisherigen studentischen Vertretern nicht zufrieden waren. Nach unserem Wahlsieg bei den [[Gremienwahlen 2003]] war ich für zwei Jahre Mitglied im [[Fakultätsrat]] und der [[Ausbildungskommission]]. Die letzten sechs Jahre war ich als [[Tutor]] in der [[Einführungswoche]] aktiv, die ich auch in einigen Jahre mit organisiert habe.&lt;br /&gt;
&lt;br /&gt;
Seit mehr als vier Jahren bin ich Mitglied im CCT e.V. - Berlins studentischer Unternehmensberatung - und leite seit 2005 die IT-Sparte [[Juniter]]. Im Jahr 2005 habe ich mit einigen anderen Mitstreitern bei Juniter [[MeinProf.de]] gegründet, welches mittlerweile von einem eigenen Verein, dem MeinProf e.V. betrieben wird, dessen 1. Vorsitzender ich zur Zeit bin.&lt;br /&gt;
&lt;br /&gt;
Erreichen könnt Ihr mich per E-Mail unter [mailto:thomas@freitagsrunde.org thomas@freitagsrunde.org].&lt;br /&gt;
&lt;br /&gt;
Mails an mich kannst und solltest Du per PGP/GnuPG verschlüsseln:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GnuPG-KeyID: 1024D/3D68D63A&lt;br /&gt;
Fingerprint: 274A 4CB8 B362 D593 39D6 0989 8FC3 725F 3D68 D63A&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Michael Klum (michael.klum (at) mailbox.tu-berlin.de) ==&lt;br /&gt;
[[Bild:Foto-Michael-Klum.jpg|thumb|150px|Michael Klum]]&lt;br /&gt;
Ich bin sozusagen schon mein Leben lang &amp;quot;Vollblutbastler&amp;quot; und verbrenn mir auch mal gern die Finger an einem Lötkolben. Das hat mich zum Studiengang Elektrotechnik bewegt.&lt;br /&gt;
In der Einführungswoche für &amp;quot;Erstis&amp;quot; zum Wintersemester 2008/09 habe ich in den Raum gefragt, ob die Uni eine Möglichkeit hat zu basteln. Mir wurde gesagt ich soll mal zur Freitagsrunde kommen, und hier bin ich. Offenbar hat man die Möglichkeit von hier aus einiges ins Rollen zu bringen!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Michael Kunze (&amp;lt;email&amp;gt;JaegerMFK@gmx.de&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:MichaelKunze.jpg|thumb|150px|Michael Kunze]]&lt;br /&gt;
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut consectetuer, tortor ac pretium laoreet, enim lectus iaculis ante, sit amet aliquet nisl diam tempus magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam orci. Quisque egestas. Donec ullamcorper, pede ac ultricies venenatis, leo nisi rutrum sem, id congue nibh nisl vel nulla. Praesent id mi. Vivamus enim neque, elementum vel, elementum sed, pretium et, arcu. Curabitur leo. Etiam tristique orci viverra ligula. Nam ultricies. Donec aliquet varius elit. Maecenas massa. Nullam justo. Donec sagittis magna id lectus ultrices semper. Etiam laoreet lorem quis purus. Nam justo purus, euismod ut, porta a, eleifend id, pede. Sed tincidunt ipsum a arcu. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Manuela (&amp;lt;email&amp;gt;m_h_in@gmx.de&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:Manuela.jpg|thumb|150px|Manuela]]&lt;br /&gt;
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut consectetuer, tortor ac pretium laoreet, enim lectus iaculis ante, sit amet aliquet nisl diam tempus magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam orci. Quisque egestas. Donec ullamcorper, pede ac ultricies venenatis, leo nisi rutrum sem, id congue nibh nisl vel nulla. Praesent id mi. Vivamus enim neque, elementum vel, elementum sed, pretium et, arcu. Curabitur leo. Etiam tristique orci viverra ligula. Nam ultricies. Donec aliquet varius elit. Maecenas massa. Nullam justo. Donec sagittis magna id lectus ultrices semper. Etiam laoreet lorem quis purus. Nam justo purus, euismod ut, porta a, eleifend id, pede. Sed tincidunt ipsum a arcu. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sebastian Koch ([mailto:skoch@freitagsrunde.org skoch@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:skoch.jpg|thumb|150px|Sebastian Koch]]&lt;br /&gt;
Seit dem Wintersemester 2006/07 studiere ich Technische Informatik an der TU Berlin. Zur Freitagsrunde bin ich erst Ende des Sommersemesters 2007 gekommen. Seither habe ich an Opalix07 und Opalix08 mitgearbeitet, bei der Einführungswoche für die Studienanfänger 2007 eine Kleingruppe mit Infos versorgt und beim Eclipsekurs08 als Tutor mitgeholfen. Zudem sitze ich im Prüfungsausschuss für Technische Informatik. Für das Studium der technischen Informatik habe ich mich entschieden, da man hier das Beste aus beiden Welten (ET und Info) mitnehmen kann ;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Thaddäus Krönert ([mailto:tkroenert@freitagsrunde.org tkroenert@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Thaddaeus_Kroenert.jpg|thumb|150px|Thaddäus Krönert]]&lt;br /&gt;
Ich bin [[Technische Informatik]]-Student seit 2007 und bin auch seit dem in der Freitagsrunde.&lt;br /&gt;
Ich engagiere mich fuer all das, was studieren besser macht. Auch wenn ich nicht direkt davon profitiere, so profitiere ich doch von den Ergebnissen Gleichgesinnter.&lt;br /&gt;
&amp;lt;!--Zusammenklautes:--&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Im uebrigen bin ich auch, als Verfechter des amerikanischen Tastaturlayouts, gegen Umlaute!&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Was ich innerhalb und außerhalb der Freitagsrunde sonst so organisiere, erfahrt ihr über [[Benutzer:Tkroenert|meine Benutzerseite]]. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alexander Kührmann (&amp;lt;email&amp;gt;akuehrmann@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:11.png|thumb|150px|Alexander Kührmann]]&lt;br /&gt;
Hallo, ich bin der Alexander und studiere an der TUB Informatik seit dem Wintersemester 2006/2007, mittlerweile sogar schon im Master. Seit einigen Semestern versuche ich mich auch in der Freitagsrunde zu engagieren. Außerdem habe ich Spaß dabei, anderen Studis Dinge zu erklären, weshalb ich als Tutor beim Javakurs, C-Kurs und der Einführungswoche aktiv bin.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sebastian Kührmann (sebastian kuehrmann com) ==&lt;br /&gt;
[[Bild:SebastianKuehrmann.jpg|thumb|150px|Sebastian Kührmann]]&lt;br /&gt;
Hallo, ich bin der Sebastian und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sebastian Lange (bastla -at- freitagsrunde.org) ==&lt;br /&gt;
[[Bild:Bastla.jpg|thumb|150px|Sebastian Lange]]&lt;br /&gt;
&lt;br /&gt;
Sebastian aka bastla studiert seit dem WS2007/08 ''Technische Informatik'' an der TU-Berlin. Durch Kontakte zur Freitagsrunde nahm er schon vor Beginn des ersten Semsters an dieser Sonderform des universitären Lebens teil.&lt;br /&gt;
&lt;br /&gt;
Anteil am Gesamtexperiment ''Freitagsrunde'' hat er durch die mitadministation des Freitagsrundenservers und in vertretender Stellung durch Fakultäts-politisches Engagement.&lt;br /&gt;
&lt;br /&gt;
Ansonsten liegt sein Hauptengagement in der Renaissance der Amateurfunkgruppe der TU-Berlin, kurz ''AfuTUB''. Unter dem ehemals sehr bekannten Rufzeichen ''[http://dk0tu.de DK0TU]'' soll neuer studentischer Nachwuchs das Shack im obersten Stock des Hauptgebäudes betreiben.&lt;br /&gt;
&lt;br /&gt;
OT Informationen auf der [[Benutzer:bastla|Benutzerseite]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Daniel Levin (dlevin (at) cs.tu-berlin.de) ==&lt;br /&gt;
[[Bild:Foto-Daniel-Levin.jpg|thumb|150px|Daniel Levin]]&lt;br /&gt;
Hello World! Ich bin Dan, der super nett und freundliche Amerikaner der Freitagsrunde. Seit 2006 bin ich Masterstudent in der Informatikrichtung hier an der TU. Bisher habe ich in Philadelphia meine Bachelorstudium in Mathematik absolviert, und ich freue mich nun hier in Berlin zu wohnen/studieren/arbeiten. I'm a Gentoo and Mac user und ich spiele gerne mit *nix Services als Sysadmin Mitarbeiter der Freitagsrunde und ich spiele  gerne auch das Kartenspiel  &amp;quot;SET&amp;quot;. Sometimes I speak in a komische mischung von Deutsch und English.  Random Facts: I can juggle. Giovanni Sollima is Amazing.&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Brandon Llanque (&amp;lt;email&amp;gt;brandon@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:BrandonLlanque.jpg|thumb|150px|Brandon Llanque]]&lt;br /&gt;
Hallo, ich bin der Brandon und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bernd May ([mailto:bm@dv-team.de bm@dv-team.de]) ==&lt;br /&gt;
[[Bild:Foto-Bernd-May.jpg|thumb|150px|Bernd May]]&lt;br /&gt;
Ich studiere seit 2006 an der TU Informatik und hoffe, so ich das Grundstudium überstehe, mich schleunigst nach Abschluss des Bachelors an eine Vertiefung in Form des Masters of Science machen zu können.&lt;br /&gt;
Bei der Freitagsrunde bin ich seit Beginn meines Studiums, da ich es als wichtigen Bestandteil meiner Lehrnzeit sehe, selbst aktiv an der Gestaltung selbiger mitzuarbeiten.&lt;br /&gt;
&lt;br /&gt;
Mails an mich kannst und solltest Du per PGP/GnuPG verschlüsseln:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
GnuPG-KeyID: 6EC47F94&lt;br /&gt;
Fingerprint: 97C5 136A 5D44 3FEF FB9B 0633 D530 0C6B 6EC4 7F94&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tibor Pilz (&amp;lt;email&amp;gt;tibor@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:TiborPilz.jpg|thumb|150px|Tibor Pilz]]&lt;br /&gt;
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut consectetuer, tortor ac pretium laoreet, enim lectus iaculis ante, sit amet aliquet nisl diam tempus magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam orci. Quisque egestas. Donec ullamcorper, pede ac ultricies venenatis, leo nisi rutrum sem, id congue nibh nisl vel nulla. Praesent id mi. Vivamus enim neque, elementum vel, elementum sed, pretium et, arcu. Curabitur leo. Etiam tristique orci viverra ligula. Nam ultricies. Donec aliquet varius elit. Maecenas massa. Nullam justo. Donec sagittis magna id lectus ultrices semper. Etiam laoreet lorem quis purus. Nam justo purus, euismod ut, porta a, eleifend id, pede. Sed tincidunt ipsum a arcu. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Marcel Radke ([mailto:mradke@cs.tu-berlin.de mradke@cs.tu-berlin.de]) ==&lt;br /&gt;
[[Bild:MRadke.JPG|thumb|150px|Marcel Radke]]&lt;br /&gt;
Moin. &amp;lt;br&amp;gt;&lt;br /&gt;
Seit Beginn meines Studiums im WS 07/08 hänge ich schon in der Freitagsrunde rum. Ich bin begeistert vom Tatendrang vieler Freitagsrundler und versuche selbst ein wenig meiner Kraft für ein besseres Studium einzusetzen. So war ich als Kleingruppentutor in der Einführungswoche WS 08 mit dabei und besuche auch gerne mal die AK.&lt;br /&gt;
Wenn ich mich ansonsten nicht gerade mit Studieren beschäftige oder vor mich hinschweige, füttere ich mein kleines Interesse für Fremdsprachen.&amp;lt;br&amp;gt;&lt;br /&gt;
soweit, man sieht sich.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Xenia Spott (&amp;lt;email&amp;gt;xenia@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:XeniaSpott.jpg|thumb|150px|Xenia Spott]]&lt;br /&gt;
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut consectetuer, tortor ac pretium laoreet, enim lectus iaculis ante, sit amet aliquet nisl diam tempus magna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam orci. Quisque egestas. Donec ullamcorper, pede ac ultricies venenatis, leo nisi rutrum sem, id congue nibh nisl vel nulla. Praesent id mi. Vivamus enim neque, elementum vel, elementum sed, pretium et, arcu. Curabitur leo. Etiam tristique orci viverra ligula. Nam ultricies. Donec aliquet varius elit. Maecenas massa. Nullam justo. Donec sagittis magna id lectus ultrices semper. Etiam laoreet lorem quis purus. Nam justo purus, euismod ut, porta a, eleifend id, pede. Sed tincidunt ipsum a arcu. &lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Daniel Sturm ([mailto:freitagsrunde@DanielSturm.de freitagsrunde@DanielSturm.de]) ==&lt;br /&gt;
[[Bild:Foto_Daniel.jpg|framed|Daniel Sturm]]&lt;br /&gt;
Ich habe mit dem Studium im WS03/04 begonnen und scheine damit recht gut klarzukommen. Da ich auserdem eher der Typ bin, der leicht zufriedenzustellen ist und aus dem das Beste macht was er bekommt, ist es eher unwahrscheinlich, dass ich mich aus Unzufriedenheit bei einer Studenteninitiative wie der Freitagsrunde blicken lasse. Letzeres ist eher darauf zurückzuführen, dass ich dazu geneigt bin, was zum Wohle der Allgemeinheit zu tun, sofern die Zeit es zulässt.&lt;br /&gt;
&lt;br /&gt;
Alle weiteren Informationen gibts hier: http://www.dStulle.de/ oder hier: http://bog.dstulle.de/&lt;br /&gt;
&lt;br /&gt;
Ich war übrigens von 2006 bis 2008 in Shanghai und habe dort am [[Doppeldiplom_SJTU|Doppeldiplomabkommen]] mit der [http://www.sjtu.edu.cn/ Shanghai Jiao Tong Universität] teilgenommen. also wer fragen dazu hat schickt mir am besten eine [mailto:sjtu@DanielSturm.de eMail].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Florian Streibelt ([mailto:florian(a)freitagsrunde.org florian(a)freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:Foto-florian.jpeg|framed|Florian Streibelt]]&lt;br /&gt;
Mit meinem Studium habe ich 2001 begonnen, zunächst als Elektrotechniker. Im Verlauf&lt;br /&gt;
des 4.Semesters habe ich dann zur Informatik gewechselt.&lt;br /&gt;
&lt;br /&gt;
In der Freizeit beschäftige ich mich vor allem mit Linux, Programmieren, Netzwerk- und Computersicherheit, Elektronik und vielen anderen Themen aus dem Bereich Computer und Technik. &lt;br /&gt;
Ausserdem arbeite ich bei [http://www.kbs.tu-berlin.de/ KBS], mit Mitglied in der [http://www.agrs.tu-berlin.de/?id=37178 AG-Rechnersicherheit], Stellvertreter im Fakultätsrat und im AS. &lt;br /&gt;
&lt;br /&gt;
Und Krawatte trage ich nicht so häufig, wie das jetzt hier den Anschein hat ;)&lt;br /&gt;
&lt;br /&gt;
Mails an mich kannst und solltest Du per PGP/[http://www.gnupg.org/ GnuPG] verschlüsseln, siehe [[Benutzer:Mutax]].&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bernd Weiss (&amp;lt;email&amp;gt;bweiss@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:BerndWeiss.jpg|thumb|150px|Bernd Weiss]]&lt;br /&gt;
Hallo, ich bin der Bernd und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Karl Wessel ([mailto:karl@freitagsrunde.org karl@freitagsrunde.org]) ==&lt;br /&gt;
[[Bild:karl3.jpg|thumb|150px|Karl Wessel]]&lt;br /&gt;
Ich habe mein Informatikstudium hier an der TU im WS04/05 begonnen, mit der Hoffnung endlich das zu lernen was ich will und wie ich es will. &lt;br /&gt;
Pustekuchen. &lt;br /&gt;
Immernoch werden 50 Prozent der Studienzeit durch ineffektive Lehrmethoden (man stelle sich ein Flasche vor die gefüllt wird indem man einen Topf über ihr ausschüttet) und Lehr-/Lernzwänge sinnlos verplämpert.&lt;br /&gt;
Da ich hoffe daran etwas ändern zu können bin ich nun in der Freitagsrunde.&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Robert Wirski (&amp;lt;email&amp;gt;wirski@freitagsrunde.org&amp;lt;/email&amp;gt;) ==&lt;br /&gt;
[[Bild:RobertWirski.jpg|thumb|150px|Robert Wirski]]&lt;br /&gt;
Hallo, ich bin der Robert und möchte diesen sinnlosen Text demnächst gegen einen sinnvollen Text ersetzen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Das sind die Mitglieder der Freitagsrunde - Zurück zu unserer [[Freitagsrunde | Selbstdefinition]].'''&lt;br /&gt;
&lt;br /&gt;
(zu den [[Freitagsrunde:Ehemalige_Mitglieder|ehemaligen Mitgliedern]].)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Freitagsrunde]]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
__NOEDITSECTION__&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=Datei:11.png&amp;diff=13156</id>
		<title>Datei:11.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=Datei:11.png&amp;diff=13156"/>
		<updated>2009-12-10T18:12:41Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12609</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12609"/>
		<updated>2009-09-25T09:33:44Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         4                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert. im CS-Netz ist schon alles nötige installiert. Solltest du Linux benutzen, musst du das Entwicklerpacket von libncurses installieren (unter Debian/Ubuntu ''libncurses-dev'').&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;tt&amp;gt;initscr();&amp;lt;/tt&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;tt&amp;gt;noecho();&amp;lt;/tt&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;tt&amp;gt;cbreak();&amp;lt;/tt&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;tt&amp;gt;keypad(stdscr, TRUE);&amp;lt;/tt&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;tt&amp;gt;nodelay(stdscr, TRUE);&amp;lt;/tt&amp;gt; damit die Funktion, die später die Tastendrücke entgegennimmt, nicht blockiert, bis eine Taste gedrückt wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion. Sie enthält als ersten Aufruf unsere &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt;-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextdatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -o pong -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Define-Makros angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;void place_paddles()&amp;lt;/tt&amp;gt; soll die Schläger mittig platzieren. Die Funktion &amp;lt;tt&amp;gt;void place_ball()&amp;lt;/tt&amp;gt; soll den Ball in der Mitte platzieren. Die x- und y-Richtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion &amp;lt;tt&amp;gt;void print_field()&amp;lt;/tt&amp;gt; geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst &amp;lt;tt&amp;gt;clear()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; von curses statt &amp;lt;tt&amp;gt;printf()&amp;lt;/tt&amp;gt; verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt;, indem du es in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein &amp;lt;tt&amp;gt;sleep(10)&amp;lt;/tt&amp;gt; ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstes kommt die Funktion &amp;lt;tt&amp;gt;void key_processing()&amp;lt;/tt&amp;gt; dran. Darin fragen wir nun folgendermaßen einen Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante &amp;lt;tt&amp;gt;KEY_UP&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;KEY_DOWN&amp;lt;/tt&amp;gt; bzw. den Buchstaben &amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'s'&amp;lt;/tt&amp;gt; vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt; und einer 100-Millisekunden-Pause in eine Endlosschleife gepackt werden. Für Pausen eignen sich die Funktionen &amp;lt;tt&amp;gt;sleep&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;usleep&amp;lt;/tt&amp;gt; aus ''stdlib.h''. Erstere nimmt Sekunden, letztere Mikrosekunden an. (1 Sekunde = 1.000 Millisekunden = 1.000.000 Mikrosekunden)&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion &amp;lt;tt&amp;gt;void move_ball()&amp;lt;/tt&amp;gt;, die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion &amp;lt;tt&amp;gt;void detect_collision()&amp;lt;/tt&amp;gt; soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion &amp;lt;tt&amp;gt;int detect_ball_out()&amp;lt;/tt&amp;gt;. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; bzw. für die linke Seite &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; zurückgeben. Ansonsten gibt die Funktion &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion &amp;lt;tt&amp;gt;int play_round()&amp;lt;/tt&amp;gt; um. Der Rückgabewert soll der Wert sein, den &amp;lt;tt&amp;gt;detect_ball_out()&amp;lt;/tt&amp;gt; im Fall des Nichttreffens liefert. Bisher reagieren die Schläger noch recht langsam, weshalb wir die Pause in der Schleife auf 20 Millisekunden herabsetzen. Da nun aber der Ball viel zu schnell wird, sollte &amp;lt;tt&amp;gt;move_ball&amp;lt;/tt&amp;gt; nur jeden fünften Schleifendurchlauf aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
In der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser &amp;lt;tt&amp;gt;play_round()&amp;lt;/tt&amp;gt;; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfachste Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Schreibe dazu eine entsprechende Funktion &amp;lt;tt&amp;gt;ai_opponent&amp;lt;/tt&amp;gt;. Nun bewegt sich der Schläger genauso schnell, wie der Ball, womit die die KI unbesiegbar ist. Führe deswegen eine Funktion &amp;lt;tt&amp;gt;can_move&amp;lt;/tt&amp;gt; ein, von der abhängt, ob sich der Schläger bewegt. Die Funktion sollte mit einer gewissen Wahrscheinlichkeit ''wahr'' zurückliefern. Die Schwierigkeit besteht darin, einen ausgewogenen Gegner zu programmieren. Eine gute Idee ist es z.B., die Position des Balls mit in die Wahrscheinlichkeit einfließen zu lassen.&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong/Musterl%C3%B6sung&amp;diff=12608</id>
		<title>C-Kurs/Pong/Musterlösung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong/Musterl%C3%B6sung&amp;diff=12608"/>
		<updated>2009-09-25T09:28:00Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Zusatz-KI Müsterlösung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Musterlösung ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;curses.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* dimensions of the field */&lt;br /&gt;
#define WIDTH 40&lt;br /&gt;
#define HEIGHT 15&lt;br /&gt;
#define PADDLE_HEIGHT 3&lt;br /&gt;
&lt;br /&gt;
/* positions of play things */&lt;br /&gt;
int pos_p1_y;&lt;br /&gt;
int pos_p2_y;&lt;br /&gt;
int pos_ball_x;&lt;br /&gt;
int pos_ball_y;&lt;br /&gt;
int dir_ball_x;&lt;br /&gt;
int dir_ball_y;&lt;br /&gt;
&lt;br /&gt;
/* scores */&lt;br /&gt;
int score_p1 = 0;&lt;br /&gt;
int score_p2 = 0;&lt;br /&gt;
&lt;br /&gt;
void init() {&lt;br /&gt;
	initscr(); /* init for curses */&lt;br /&gt;
	noecho();  /* don't display typed chars */&lt;br /&gt;
	cbreak();  /* don't buffer terminal lines */&lt;br /&gt;
	keypad(stdscr, TRUE);  /* for special keys (e.g. arrow keys) */&lt;br /&gt;
	nodelay(stdscr, TRUE); /* don't block in getch() */ &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void place_paddles() {&lt;br /&gt;
	pos_p1_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;&lt;br /&gt;
	pos_p2_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void place_ball(int dir_x) {&lt;br /&gt;
	pos_ball_x = WIDTH / 2;&lt;br /&gt;
	pos_ball_y = HEIGHT / 2;&lt;br /&gt;
	dir_ball_x = dir_x;&lt;br /&gt;
	dir_ball_y = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void print_field() {&lt;br /&gt;
	clear();&lt;br /&gt;
	int x,y;&lt;br /&gt;
	&lt;br /&gt;
	/* print score */&lt;br /&gt;
	printw(&amp;quot;         %i                     %i\n&amp;quot;, score_p1, score_p2);&lt;br /&gt;
&lt;br /&gt;
	/* print upper frame */&lt;br /&gt;
	printw(&amp;quot;+&amp;quot;);&lt;br /&gt;
	for(x=0; x&amp;lt;WIDTH; x++) {&lt;br /&gt;
		printw(&amp;quot;-&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	printw(&amp;quot;+\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	for (y=0; y&amp;lt;HEIGHT; y++) {&lt;br /&gt;
		/* first column (x==0) is for player1's paddle */&lt;br /&gt;
		if (y &amp;gt;= pos_p1_y &amp;amp;&amp;amp; y &amp;lt; pos_p1_y+PADDLE_HEIGHT) {&lt;br /&gt;
			printw(&amp;quot;|#&amp;quot;);&lt;br /&gt;
		} else if (pos_ball_x == 0 &amp;amp;&amp;amp; pos_ball_y == y) {&lt;br /&gt;
			printw(&amp;quot;|*&amp;quot;);&lt;br /&gt;
		} else {&lt;br /&gt;
			printw(&amp;quot;| &amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		/* middle columns (0 &amp;lt; x &amp;lt; WIDTH-1) anywhere the ball can be */&lt;br /&gt;
		for (x=1; x&amp;lt;WIDTH-1; x++) {&lt;br /&gt;
			if (y == pos_ball_y &amp;amp;&amp;amp; x == pos_ball_x) {&lt;br /&gt;
				printw(&amp;quot;*&amp;quot;);&lt;br /&gt;
			} else {&lt;br /&gt;
				printw(&amp;quot; &amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		/* last column (x==WIDTH-1) is for player2's paddle */&lt;br /&gt;
		if (y &amp;gt;= pos_p2_y &amp;amp;&amp;amp; y &amp;lt; pos_p2_y+PADDLE_HEIGHT) {&lt;br /&gt;
			printw(&amp;quot;#|\n&amp;quot;);&lt;br /&gt;
		} else if (pos_ball_x == WIDTH-1 &amp;amp;&amp;amp; pos_ball_y == y) {&lt;br /&gt;
			printw(&amp;quot;*|\n&amp;quot;);&lt;br /&gt;
		} else {&lt;br /&gt;
			printw(&amp;quot; |\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* print lower frame */&lt;br /&gt;
	printw(&amp;quot;+&amp;quot;);&lt;br /&gt;
	for(x=0; x&amp;lt;WIDTH; x++) {&lt;br /&gt;
		printw(&amp;quot;-&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	printw(&amp;quot;+\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	refresh();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void key_processing() {&lt;br /&gt;
	int ch = getch();&lt;br /&gt;
	if (ch == KEY_UP) {&lt;br /&gt;
		if (pos_p1_y &amp;gt; 0) {&lt;br /&gt;
			pos_p1_y--;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == KEY_DOWN) {&lt;br /&gt;
		if (pos_p1_y &amp;lt; HEIGHT-PADDLE_HEIGHT) {&lt;br /&gt;
			pos_p1_y++;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == 'w') {&lt;br /&gt;
		if (pos_p2_y &amp;gt; 0) {&lt;br /&gt;
			pos_p2_y--;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == 's') {&lt;br /&gt;
		if (pos_p2_y &amp;lt; HEIGHT-PADDLE_HEIGHT) {&lt;br /&gt;
			pos_p2_y++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void detect_collision() {&lt;br /&gt;
	/* ball collides with upper/lower bounds */&lt;br /&gt;
	if (pos_ball_y &amp;lt;= 0 || pos_ball_y &amp;gt;= HEIGHT-1) {&lt;br /&gt;
		dir_ball_y *= -1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ball collides with player1's paddle */&lt;br /&gt;
	if (pos_ball_x == 1 &amp;amp;&amp;amp; pos_ball_y &amp;gt;= pos_p1_y &amp;amp;&amp;amp; pos_ball_y &amp;lt; pos_p1_y + PADDLE_HEIGHT) {&lt;br /&gt;
		dir_ball_x *= -1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ball collides with player2's paddle */&lt;br /&gt;
	if (pos_ball_x == WIDTH-2 &amp;amp;&amp;amp; pos_ball_y &amp;gt;= pos_p2_y &amp;amp;&amp;amp; pos_ball_y &amp;lt; pos_p2_y + PADDLE_HEIGHT) {&lt;br /&gt;
		dir_ball_x *= -1;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void move_ball() {&lt;br /&gt;
	pos_ball_x += dir_ball_x;&lt;br /&gt;
	pos_ball_y += dir_ball_y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int detect_ball_out() {&lt;br /&gt;
	/* ball is out on left side -&amp;gt; point for player2 */&lt;br /&gt;
	if (pos_ball_x &amp;lt;= 0) {&lt;br /&gt;
		return 2;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ball is out on right side -&amp;gt; point for player1 */&lt;br /&gt;
	if (pos_ball_x &amp;gt;= WIDTH-1) {&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int play_round() {&lt;br /&gt;
	int ball_out;&lt;br /&gt;
	int count = 0;&lt;br /&gt;
	while( !(ball_out = detect_ball_out()) ) {&lt;br /&gt;
		key_processing();&lt;br /&gt;
		if(count == 0) {&lt;br /&gt;
			move_ball();&lt;br /&gt;
			detect_collision();&lt;br /&gt;
		}&lt;br /&gt;
		print_field();&lt;br /&gt;
		count = (count + 1) % 5;&lt;br /&gt;
		usleep(20000);&lt;br /&gt;
	}&lt;br /&gt;
	return ball_out;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
	init();&lt;br /&gt;
	place_paddles();&lt;br /&gt;
	place_ball(1);&lt;br /&gt;
&lt;br /&gt;
	while(score_p1 &amp;lt; 10 &amp;amp;&amp;amp; score_p2 &amp;lt; 10) {&lt;br /&gt;
		int round_won = play_round();&lt;br /&gt;
		if (round_won == 1) {&lt;br /&gt;
			score_p1++;&lt;br /&gt;
			place_ball(1);&lt;br /&gt;
		} else if (round_won == 2) {&lt;br /&gt;
			score_p2++;&lt;br /&gt;
			place_ball(-1);&lt;br /&gt;
		}&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		flushinp(); /* keys could've been pressed during sleep -&amp;gt;  emty the input buffer */&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (score_p1 &amp;gt; score_p2) {&lt;br /&gt;
		printw(&amp;quot;Player 1 wins!\n&amp;quot;);&lt;br /&gt;
	} else {&lt;br /&gt;
		printw(&amp;quot;Player 2 wins!\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	refresh();&lt;br /&gt;
	sleep(3);&lt;br /&gt;
&lt;br /&gt;
	endwin();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Musterlösung KI ==&lt;br /&gt;
Einen halbwegs ausgeglichenen Gegner bringt die folgende Lösung. Die Funktion &amp;lt;tt&amp;gt;ai_opponent&amp;lt;/tt&amp;gt; muss dazu in der Schleife von &amp;lt;tt&amp;gt;play_round&amp;lt;/tt&amp;gt; am besten nach &amp;lt;tt&amp;gt;key_processing&amp;lt;/tt&amp;gt; aufgerufen werden.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int can_move() {&lt;br /&gt;
	if (dir_ball_x &amp;lt; 0) { /* we don't want to move when the ball departs from us */&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	int rnd = rand();&lt;br /&gt;
	if (pos_ball_x &amp;lt;= WIDTH / 4) {&lt;br /&gt;
		rnd &amp;amp;= 0x1f; /* zero with probability 1/32 */&lt;br /&gt;
	} else if (pos_ball_x &amp;lt;= WIDTH / 2) {&lt;br /&gt;
		rnd &amp;amp;= 0x0f; /* zero with probability 1/16 */&lt;br /&gt;
	} else if (pos_ball_x &amp;lt;= WIDTH * 3 / 4) {&lt;br /&gt;
		rnd &amp;amp;= 0x07; /* zero with probability 1/8 */&lt;br /&gt;
	} else {&lt;br /&gt;
		rnd &amp;amp;= 0x03; /* zero with probability 1/4 */&lt;br /&gt;
	}&lt;br /&gt;
	return !rnd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void ai_opponent() {&lt;br /&gt;
	if (can_move()) {&lt;br /&gt;
		int middle_pad_pos = pos_p2_y + 1;&lt;br /&gt;
		if (pos_ball_y &amp;lt; middle_pad_pos) {&lt;br /&gt;
			if (pos_p2_y &amp;gt; 0) {&lt;br /&gt;
				pos_p2_y--;&lt;br /&gt;
			}&lt;br /&gt;
		} else if (pos_ball_y &amp;gt; middle_pad_pos) {&lt;br /&gt;
			if (pos_p2_y &amp;lt; HEIGHT - PADDLE_HEIGHT) {&lt;br /&gt;
				pos_p2_y++;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12495</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12495"/>
		<updated>2009-09-22T08:49:51Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Zusatzaufgabe: KI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         4                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;tt&amp;gt;initscr();&amp;lt;/tt&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;tt&amp;gt;noecho();&amp;lt;/tt&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;tt&amp;gt;cbreak();&amp;lt;/tt&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;tt&amp;gt;keypad(stdscr, TRUE);&amp;lt;/tt&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;tt&amp;gt;nodelay(stdscr, TRUE);&amp;lt;/tt&amp;gt; damit die Funktion, die später die Tastendrücke entgegennimmt, nicht blockiert, bis eine Taste gedrückt wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion. Sie enthält als ersten Aufruf unsere &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt;-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextdatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Define-Makros angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;void place_paddles()&amp;lt;/tt&amp;gt; soll die Schläger mittig platzieren. Die Funktion &amp;lt;tt&amp;gt;void place_ball()&amp;lt;/tt&amp;gt; soll den Ball in der Mitte platzieren. Die x- und y-Richtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion &amp;lt;tt&amp;gt;void print_field()&amp;lt;/tt&amp;gt; geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst &amp;lt;tt&amp;gt;clear()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; von curses statt &amp;lt;tt&amp;gt;printf()&amp;lt;/tt&amp;gt; verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt;, indem du es in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein &amp;lt;tt&amp;gt;sleep(10)&amp;lt;/tt&amp;gt; ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstes kommt die Funktion &amp;lt;tt&amp;gt;void key_processing()&amp;lt;/tt&amp;gt; dran. Darin fragen wir nun folgendermaßen einen Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante &amp;lt;tt&amp;gt;KEY_UP&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;KEY_DOWN&amp;lt;/tt&amp;gt; bzw. den Buchstaben &amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'s'&amp;lt;/tt&amp;gt; vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt; und einer 100-Millisekunden-Pause in eine Endlosschleife gepackt werden. Für Pausen eignen sich die Funktionen &amp;lt;tt&amp;gt;sleep&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;usleep&amp;lt;/tt&amp;gt; aus ''stdlib.h''. Erstere nimmt Sekunden, letztere Mikrosekunden an. (1 Sekunde = 1.000 Millisekunden = 1.000.000 Mikrosekunden)&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion &amp;lt;tt&amp;gt;void move_ball()&amp;lt;/tt&amp;gt;, die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion &amp;lt;tt&amp;gt;void detect_collision()&amp;lt;/tt&amp;gt; soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion &amp;lt;tt&amp;gt;int detect_ball_out()&amp;lt;/tt&amp;gt;. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; bzw. für die linke Seite &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; zurückgeben. Ansonsten gibt die Funktion &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion &amp;lt;tt&amp;gt;int play_round()&amp;lt;/tt&amp;gt; um. Der Rückgabewert soll der Wert sein, den &amp;lt;tt&amp;gt;detect_ball_out()&amp;lt;/tt&amp;gt; im Fall des Nichttreffens liefert. Bisher reagieren die Schläger noch recht langsam, weshalb wir die Pause in der Schleife auf 20 Millisekunden herabsetzen. Da nun aber der Ball viel zu schnell wird, sollte &amp;lt;tt&amp;gt;move_ball&amp;lt;/tt&amp;gt; nur jeden fünften Schleifendurchlauf aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
In der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser &amp;lt;tt&amp;gt;play_round()&amp;lt;/tt&amp;gt;; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfachste Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Schreibe dazu eine entsprechende Funktion &amp;lt;tt&amp;gt;ai_opponent&amp;lt;/tt&amp;gt;. Nun bewegt sich der Schläger genauso schnell, wie der Ball, womit die die KI unbesiegbar ist. Führe deswegen eine Funktion &amp;lt;tt&amp;gt;can_move&amp;lt;/tt&amp;gt; ein, von der abhängt, ob sich der Schläger bewegt. Die Funktion sollte mit einer gewissen Wahrscheinlichkeit ''wahr'' zurückliefern. Die Schwierigkeit besteht darin, einen ausgewogenen Gegner zu programmieren. Eine gute Idee ist es z.B., die Position des Balls mit in die Wahrscheinlichkeit einfließen zu lassen.&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Sammelbestellung&amp;diff=12482</id>
		<title>C-Kurs/Sammelbestellung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Sammelbestellung&amp;diff=12482"/>
		<updated>2009-09-21T20:22:10Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Rechtschreibung gefixt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Aufgabenstellung ===&lt;br /&gt;
Diese Aufgabe soll möglichst viele Elemente der bisherigen Vorlesungen aufgreifen und verbinden. Die Teilaufgaben fangen leicht an und werden gegen Ende etwas komplexer, so dass Ihr selbst schauen könnt 'wie weit' ihr kommt. Bei Problemen nicht verzagen, Tutor fragen! &lt;br /&gt;
&lt;br /&gt;
Lest Euch die Aufgabe zunächst komplett durch und überlegt, welche Datenstrukturen ihr aufbauen müsst. Macht euch auf einem Blatt Papier einen Plan, welche Funktionalitäten ihr in Funktionen ausgliedern wollt, z.B. Datensatz einfügen, suchen, entfernen, Liste ausgeben, Datei einlesen, etc. damit ihr diese Funktionen in den späteren Aufgaben einfach wieder verwenden könnt. &lt;br /&gt;
&lt;br /&gt;
Die einzelnen Teilaufgaben bauen aufeinander auf und sollten daher in dieser Reihenfolge bearbeitet werden. Bearbeitet jede Teilaufgabe am besten in einem eigenen Unterverzeichnis, so dass ihr am Ende für jede Teilaufgabe eine einzelne Datei mit dem Quellcode habt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Folgendes Szenario soll mit Hilfe von elektronischer Datenverarbeitung (kurz [[wikipedia:EDV|EDV]]) gelöst werden:&lt;br /&gt;
&lt;br /&gt;
Eine Gruppe möchte zum Zweck des Sparens von Versandkosten gemeinsam bei einem Onlinehändler bestellen. Dabei soll von allen Bestellern&lt;br /&gt;
eine Bestellliste im CSV-Format entgegengenommen werden. Diese Einzellisten sollen dann zu einer Gesamtbestellliste zusammengeführt werden, die für jeden Artikel auflistet, wie oft er bestellt wurde. Bestellen mehrere Personen denselben Artikel, so soll dies anhand der Bestellnummer erkannt werden und dieser auf der Gesamtliste natürlich nur einmal, aber mit passender Menge, erscheinen.&lt;br /&gt;
&lt;br /&gt;
Neben dieser Bestellliste soll am Ende eine kurze Liste ausgegeben werden, die angibt wie viele Produkte jeder einzelne Teilnehmer bestellt hat und wie viel Geld er bezahlen muss. Vereinfachung: Die Versandkosten sollen anhand der Menge der Artikel aufgeteilt werden, nicht nach dem Gewicht.&lt;br /&gt;
&lt;br /&gt;
Im Vorfeld ist nicht bekannt, wie viele Personen insgesamt bestellen.&lt;br /&gt;
&lt;br /&gt;
Beachtet die Vorgaben zu dieser Aufgabe, welche ihr hier herunterladen könnt: ..... (TODO bis Dienstag!)&lt;br /&gt;
&lt;br /&gt;
=== Teil 1 ===&lt;br /&gt;
 &amp;lt;!-- meine Bearbeitungszeit: 20 Minuten --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Erweitere die untenstehende Vorgabe so, dass jeder Aufruf der &amp;lt;tt&amp;gt;addItem()&amp;lt;/tt&amp;gt;-Funktion den Artikel in einer einfach verketteten Liste speichert.&lt;br /&gt;
&lt;br /&gt;
Diese Liste soll am Ende des Programms auf dem Bildschirm formatiert ausgegeben werden, nachdem alle Artikel in der Liste gespeichert sind. Dabei spielt die Reihenfolge der Ausgabe keine Rolle, es kann also sowohl an den Anfang wie an das Ende der Liste angehangen werden.&lt;br /&gt;
&lt;br /&gt;
Dazu musst Du zunächst die struct-Definition der Listenelemente sinnvoll festlegen und einige Hilfsfunktionen zum Einfügen in die Liste und Ausgeben der Liste am Ende programmieren:&lt;br /&gt;
&lt;br /&gt;
  #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  typedef struct litem_t{&lt;br /&gt;
   ...&lt;br /&gt;
  } litem;&lt;br /&gt;
  &lt;br /&gt;
  typedef struct llist_t{&lt;br /&gt;
   struct litem_t *item;&lt;br /&gt;
   struct llist_t *next;&lt;br /&gt;
  } llist;&lt;br /&gt;
   &lt;br /&gt;
  llist* addItem(llist* alist, char* orderno, char* name, float price, int count, float sum){&lt;br /&gt;
   ...&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  ...weitere Hilfsfunktionen ...&lt;br /&gt;
   &lt;br /&gt;
  int main(int argc, char** argv){&lt;br /&gt;
  ...&lt;br /&gt;
  llist *alist; &lt;br /&gt;
  alist= addItem(NULL, &amp;quot;UT 2042 C&amp;quot;,&amp;quot;40 MHz-Digital-Speicher-Oszilloskop&amp;quot;,349.00, 1, 349.00);&lt;br /&gt;
  alist= addItem(alist, &amp;quot;AGF 2 SW&amp;quot;,&amp;quot;Hirschmann-Abgreifklemme 4mm schwarz&amp;quot;,5.10,1, 5.10);&lt;br /&gt;
  ...&lt;br /&gt;
  /* ausgeben der Liste: */&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ausgabe:&lt;br /&gt;
  Bestellnummer    Name                                  Einzelpreis  Menge Gesamtpreis&lt;br /&gt;
  UT 2042 C        40 MHz-Digital-Speicher-Oszilloskop	 349.00         1     349.00 &lt;br /&gt;
  AGF 2 SW         Hirschmann-Abgreifklemme 4mm schwarz	   5.10         1       5.10&lt;br /&gt;
&lt;br /&gt;
=== Teil 2 ===&lt;br /&gt;
&lt;br /&gt;
Schreibe ein Programm, dass eine CSV-Datei 'bestellung.csv' aus dem aktuellen Verzeichnis einliest und auf dem Bildschirm ausgibt, wie viele Artikel bestellt wurden und was diese insgesamt kosten. Das Einlesen der Datei befindet sich bereits ausprogrammiert in der Vorgabe.&lt;br /&gt;
&lt;br /&gt;
Die Artikel sollen dazu zunächst in einer einfach verketteten Liste unsortiert gespeichert werden, danach soll diese Liste vom Anfang durchlaufen werden und die Artikel gezählt sowie der Preis berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Die CSV-Datei hat folgendes Format (Beispiele in den Vorgaben):&lt;br /&gt;
&lt;br /&gt;
 Bestellnummer, Kurzbeschreibung, Einzelpreis, Anzahl, Preis&lt;br /&gt;
 UT 2042 C, 40 MHz-Digital-Speicher-Oszilloskop	349.00, 1, 349.00 &lt;br /&gt;
 AGF 2 SW, Hirschmann-Abgreifklemme 4mm schwarz	5.10,1, 5.10&lt;br /&gt;
 AK 2 RT, Hirschmann-Krokoklemme 4mm rot	1.80, 1, 1.80&lt;br /&gt;
&lt;br /&gt;
=== Teil 3 ===&lt;br /&gt;
&lt;br /&gt;
Stelle nun sicher, dass ein Artikel immer nur einmal in die Liste aufgenommen werden kann. Ist er bereits in der Liste vorhanden, so soll die Anzahl und der Preis angepasst werden. Stelle außerdem sicher, dass beim Einlesen der Liste der Preis jeweils das Produkt aus Anzahl und Einzelpreis ist, und sich keine Fehler in der Bestellliste eingeschlichen haben.&lt;br /&gt;
&lt;br /&gt;
Erweitere nun das Programm so, dass der Dateiname auf der Kommandozeile angegeben werden kann und so nacheinander mehrere Teilbestellungen bearbeitet werden können.&lt;br /&gt;
&lt;br /&gt;
=== Teil 4 ===&lt;br /&gt;
&lt;br /&gt;
Das Programm soll nun beliebig viele Dateinamen als Kommandozeilenparameter beim Start übergeben bekommen und für jeden einzelnen eine neue Liste führen. Am Ende soll dann in einem Block eine kurze, formatierte Tabelle ausgegeben werden, welche eine Spalte mit dem Dateinamen, dann die Anzahl der Produkte und den Endpreis aus der Bestellung enthält:&lt;br /&gt;
&lt;br /&gt;
 Dateiname      Produkte   Gesamtpreis&lt;br /&gt;
 florian.csv    51         123,51&lt;br /&gt;
 bastla.csv     12           4,12&lt;br /&gt;
 tannek.csv      6           1,80&lt;br /&gt;
 =====================================&lt;br /&gt;
 SUMME:         69         129,43&lt;br /&gt;
&lt;br /&gt;
Tipps: Nutze Liste von Listen, argv, argc, structs, printf, ...&lt;br /&gt;
&lt;br /&gt;
=== Teil 5 ===&lt;br /&gt;
&lt;br /&gt;
Erweitere das Programm jetzt schließlich so, dass nach dem kompletten Einlesen der einzelnen Listen die Gesamtbestellliste in eine Datei geschrieben wird. Dazu muss zunächst noch eine verkettete Liste angelegt werden, welche die Gesamtbestellung enthält.&lt;br /&gt;
&lt;br /&gt;
Am Ende soll dann die Tabelle aus Teil 3 auf dem Bildschirm ausgeben werden und eine Datei 'gesamt.csv' im aktuellen Verzeichnis angelegt werden, welche die Gesamtbestellung enthält. Das Dateiformat ist hier exakt wie bei den einzelnen Bestelllisten.&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe ===&lt;br /&gt;
&lt;br /&gt;
Sorge dafür, dass vor dem Beenden des Programms aller Speicher der Liste freigegeben wird. Was ist dabei zu beachten?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
&lt;br /&gt;
==== Robert ====&lt;br /&gt;
Na mal schauen, ob irgendjemand diese Funktion wirklich benutzt. Ich fände es jedenfalls toll.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs_Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/(Pointer)_Swapping&amp;diff=12481</id>
		<title>C-Kurs/(Pointer) Swapping</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/(Pointer)_Swapping&amp;diff=12481"/>
		<updated>2009-09-21T20:11:04Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Funktionsnamen formatiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# Schreibe eine Funtion &amp;lt;tt&amp;gt;swap&amp;lt;/tt&amp;gt;, die zwei Integers vertauscht. Hinweis: Du musst Zeiger auf die Integer-Variablen übergeben. Definiere zwei Integer-Variablen, gib sie auf dem Bildschirm aus, vertausche sie und gib sie erneut aus.&lt;br /&gt;
# Schreibe eine Funktion &amp;lt;tt&amp;gt;print_int_array&amp;lt;/tt&amp;gt;, die ein Integer-Array auf dem Bildschirm ausgibt. Vertausche die Elemente zweier gleichlanger Integer-Arrays elementweise. Benutze dazu die Funktion &amp;lt;tt&amp;gt;swap&amp;lt;/tt&amp;gt; aus der ersten Aufgabe. Gib die Arrays vor und nach dem Vertauschen mittels &amp;lt;tt&amp;gt;print_int_array&amp;lt;/tt&amp;gt; aus. &lt;br /&gt;
# Schreibe nun eine Funktion &amp;lt;tt&amp;gt;swap&amp;lt;/tt&amp;gt;, die zwei Integer-Pointer vertauscht.&lt;br /&gt;
# Benutze die Funktion &amp;lt;tt&amp;gt;swap&amp;lt;/tt&amp;gt; aus 3., um zwei Integer-Arrays (nicht deren Inhalte!) zu vertauschen.&lt;br /&gt;
# Mache die Funktion &amp;lt;tt&amp;gt;swap&amp;lt;/tt&amp;gt; aus 3. generisch, so dass sie für beliebige Typen funktioniert. Benutze hierzu void-Pointer. Teste sie zunächst mit Integer-Pointern, dann mit Integer- und Float-Arrays.&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Palindrome&amp;diff=12480</id>
		<title>C-Kurs/Palindrome</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Palindrome&amp;diff=12480"/>
		<updated>2009-09-21T20:07:51Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Aufgabenstellung */ Kommata&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
[[wikipedia:Palindrom|Palindrome]] sind Wörter, die rückwärts und vorwärts gleich sind, z.B. Rentner.&lt;br /&gt;
&lt;br /&gt;
Später brauchst du solche Palindrome als Eingabewerte für das Programm, das du schreiben sollst. In der Wikipedia gibt es dafür eine [[wikipedia:Palindrom#Wortpalindrome|Liste mit Palindromwörtern]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Aufgabenstellung ===&lt;br /&gt;
&lt;br /&gt;
* Schreibe eine Funktion, die das Wort umgedreht ausgibt. Groß-/Kleinschreibung soll dabei nicht betrachtet werden. Teste deine Funktion. (Hallo =&amp;gt; ollaH)&lt;br /&gt;
* Erweitere diese Funktion so, dass sie überprüft, ob ein Wort ein Palindrom ist. Teste die Funktion ausführlich.&lt;br /&gt;
* Schreibe nun ein Programm, welches ein Wort als Parameter von der Kommandozeile ausliest, überprüft ob dies ein Palindrom ist und eine entsprechende Meldung an den Benutzer ausgibt. Teste dein Programm ausgiebig.&lt;br /&gt;
* '''Für Fortgeschrittene:''' Leider kann das Programm Groß- und Kleinschreibung nicht handhaben. Am besten man konvertiert alle Zeichen zu Kleinbuchstaben. Zeichen innerhalb von Strings werden als Zahlenwerte dargestellt. 'a' hat den Wert 97 und 'A' den Wert 65, 'b' ist 98, 'B' ist 66 usw. Die Kodierung der Zeichen ist in der [http://de.wikipedia.org/wiki/Ascii#ASCII-Tabelle ASCII-Tabelle] festgehalten. Damit kann man auf den Datentyp char Rechenoperationen ausführen wie auf anderen Integertypen auch (char ist default-mäßig unsigned).&lt;br /&gt;
Schreibe nun eine Funktion, welche diese Kodierung nutzt, um alle Großbuchstaben in Kleinbuchstaben umzuwandeln.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 Um den ASCII-Code einer char Variable zu erhalten muss diese gecastet werden:&lt;br /&gt;
 char mychar = 'a';&lt;br /&gt;
 int code = (int) mychar;&lt;br /&gt;
Teste die Funktion ausführlich und baue sie in dein Programm ein.&lt;br /&gt;
--!&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
&lt;br /&gt;
==== Robert ====&lt;br /&gt;
Na mal schauen, ob irgendjemand diese Funktion wirklich benutzt. Ich fände es jedenfalls toll.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong/Musterl%C3%B6sung&amp;diff=12479</id>
		<title>C-Kurs/Pong/Musterlösung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong/Musterl%C3%B6sung&amp;diff=12479"/>
		<updated>2009-09-21T19:59:52Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Musterlösung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Musterlösung ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;curses.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* dimensions of the field */&lt;br /&gt;
#define WIDTH 40&lt;br /&gt;
#define HEIGHT 15&lt;br /&gt;
#define PADDLE_HEIGHT 3&lt;br /&gt;
&lt;br /&gt;
/* positions of play things */&lt;br /&gt;
int pos_p1_y;&lt;br /&gt;
int pos_p2_y;&lt;br /&gt;
int pos_ball_x;&lt;br /&gt;
int pos_ball_y;&lt;br /&gt;
int dir_ball_x;&lt;br /&gt;
int dir_ball_y;&lt;br /&gt;
&lt;br /&gt;
/* scores */&lt;br /&gt;
int score_p1 = 0;&lt;br /&gt;
int score_p2 = 0;&lt;br /&gt;
&lt;br /&gt;
void init() {&lt;br /&gt;
	initscr(); /* init for curses */&lt;br /&gt;
	noecho();  /* don't display typed chars */&lt;br /&gt;
	cbreak();  /* don't buffer terminal lines */&lt;br /&gt;
	keypad(stdscr, TRUE);  /* for special keys (e.g. arrow keys) */&lt;br /&gt;
	nodelay(stdscr, TRUE); /* don't block in getch() */ &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void place_paddles() {&lt;br /&gt;
	pos_p1_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;&lt;br /&gt;
	pos_p2_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void place_ball(int dir_x) {&lt;br /&gt;
	pos_ball_x = WIDTH / 2;&lt;br /&gt;
	pos_ball_y = HEIGHT / 2;&lt;br /&gt;
	dir_ball_x = dir_x;&lt;br /&gt;
	dir_ball_y = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void print_field() {&lt;br /&gt;
	clear();&lt;br /&gt;
	int x,y;&lt;br /&gt;
	&lt;br /&gt;
	/* print score */&lt;br /&gt;
	printw(&amp;quot;         %i                     %i\n&amp;quot;, score_p1, score_p2);&lt;br /&gt;
&lt;br /&gt;
	/* print upper frame */&lt;br /&gt;
	printw(&amp;quot;+&amp;quot;);&lt;br /&gt;
	for(x=0; x&amp;lt;WIDTH; x++) {&lt;br /&gt;
		printw(&amp;quot;-&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	printw(&amp;quot;+\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	for (y=0; y&amp;lt;HEIGHT; y++) {&lt;br /&gt;
		/* first column (x==0) is for player1's paddle */&lt;br /&gt;
		if (y &amp;gt;= pos_p1_y &amp;amp;&amp;amp; y &amp;lt; pos_p1_y+PADDLE_HEIGHT) {&lt;br /&gt;
			printw(&amp;quot;|#&amp;quot;);&lt;br /&gt;
		} else if (pos_ball_x == 0 &amp;amp;&amp;amp; pos_ball_y == y) {&lt;br /&gt;
			printw(&amp;quot;|*&amp;quot;);&lt;br /&gt;
		} else {&lt;br /&gt;
			printw(&amp;quot;| &amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		/* middle columns (0 &amp;lt; x &amp;lt; WIDTH-1) anywhere the ball can be */&lt;br /&gt;
		for (x=1; x&amp;lt;WIDTH-1; x++) {&lt;br /&gt;
			if (y == pos_ball_y &amp;amp;&amp;amp; x == pos_ball_x) {&lt;br /&gt;
				printw(&amp;quot;*&amp;quot;);&lt;br /&gt;
			} else {&lt;br /&gt;
				printw(&amp;quot; &amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		/* last column (x==WIDTH-1) is for player2's paddle */&lt;br /&gt;
		if (y &amp;gt;= pos_p2_y &amp;amp;&amp;amp; y &amp;lt; pos_p2_y+PADDLE_HEIGHT) {&lt;br /&gt;
			printw(&amp;quot;#|\n&amp;quot;);&lt;br /&gt;
		} else if (pos_ball_x == WIDTH-1 &amp;amp;&amp;amp; pos_ball_y == y) {&lt;br /&gt;
			printw(&amp;quot;*|\n&amp;quot;);&lt;br /&gt;
		} else {&lt;br /&gt;
			printw(&amp;quot; |\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* print lower frame */&lt;br /&gt;
	printw(&amp;quot;+&amp;quot;);&lt;br /&gt;
	for(x=0; x&amp;lt;WIDTH; x++) {&lt;br /&gt;
		printw(&amp;quot;-&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	printw(&amp;quot;+\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	refresh();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void key_processing() {&lt;br /&gt;
	int ch = getch();&lt;br /&gt;
	if (ch == KEY_UP) {&lt;br /&gt;
		if (pos_p1_y &amp;gt; 0) {&lt;br /&gt;
			pos_p1_y--;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == KEY_DOWN) {&lt;br /&gt;
		if (pos_p1_y &amp;lt; HEIGHT-PADDLE_HEIGHT) {&lt;br /&gt;
			pos_p1_y++;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == 'w') {&lt;br /&gt;
		if (pos_p2_y &amp;gt; 0) {&lt;br /&gt;
			pos_p2_y--;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == 's') {&lt;br /&gt;
		if (pos_p2_y &amp;lt; HEIGHT-PADDLE_HEIGHT) {&lt;br /&gt;
			pos_p2_y++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void detect_collision() {&lt;br /&gt;
	/* ball collides with upper/lower bounds */&lt;br /&gt;
	if (pos_ball_y &amp;lt;= 0 || pos_ball_y &amp;gt;= HEIGHT-1) {&lt;br /&gt;
		dir_ball_y *= -1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ball collides with player1's paddle */&lt;br /&gt;
	if (pos_ball_x == 1 &amp;amp;&amp;amp; pos_ball_y &amp;gt;= pos_p1_y &amp;amp;&amp;amp; pos_ball_y &amp;lt; pos_p1_y + PADDLE_HEIGHT) {&lt;br /&gt;
		dir_ball_x *= -1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ball collides with player2's paddle */&lt;br /&gt;
	if (pos_ball_x == WIDTH-2 &amp;amp;&amp;amp; pos_ball_y &amp;gt;= pos_p2_y &amp;amp;&amp;amp; pos_ball_y &amp;lt; pos_p2_y + PADDLE_HEIGHT) {&lt;br /&gt;
		dir_ball_x *= -1;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void move_ball() {&lt;br /&gt;
	pos_ball_x += dir_ball_x;&lt;br /&gt;
	pos_ball_y += dir_ball_y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int detect_ball_out() {&lt;br /&gt;
	/* ball is out on left side -&amp;gt; point for player2 */&lt;br /&gt;
	if (pos_ball_x &amp;lt;= 0) {&lt;br /&gt;
		return 2;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ball is out on right side -&amp;gt; point for player1 */&lt;br /&gt;
	if (pos_ball_x &amp;gt;= WIDTH-1) {&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int play_round() {&lt;br /&gt;
	int ball_out;&lt;br /&gt;
	int count = 0;&lt;br /&gt;
	while( !(ball_out = detect_ball_out()) ) {&lt;br /&gt;
		key_processing();&lt;br /&gt;
		if(count == 0) {&lt;br /&gt;
			move_ball();&lt;br /&gt;
			detect_collision();&lt;br /&gt;
		}&lt;br /&gt;
		print_field();&lt;br /&gt;
		count = (count + 1) % 5;&lt;br /&gt;
		usleep(20000);&lt;br /&gt;
	}&lt;br /&gt;
	return ball_out;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
	init();&lt;br /&gt;
	place_paddles();&lt;br /&gt;
	place_ball(1);&lt;br /&gt;
&lt;br /&gt;
	while(score_p1 &amp;lt; 10 &amp;amp;&amp;amp; score_p2 &amp;lt; 10) {&lt;br /&gt;
		int round_won = play_round();&lt;br /&gt;
		if (round_won == 1) {&lt;br /&gt;
			score_p1++;&lt;br /&gt;
			place_ball(1);&lt;br /&gt;
		} else if (round_won == 2) {&lt;br /&gt;
			score_p2++;&lt;br /&gt;
			place_ball(-1);&lt;br /&gt;
		}&lt;br /&gt;
		sleep(1);&lt;br /&gt;
		flushinp(); /* keys could've been pressed during sleep -&amp;gt;  emty the input buffer */&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (score_p1 &amp;gt; score_p2) {&lt;br /&gt;
		printw(&amp;quot;Player 1 wins!\n&amp;quot;);&lt;br /&gt;
	} else {&lt;br /&gt;
		printw(&amp;quot;Player 2 wins!\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	refresh();&lt;br /&gt;
	sleep(3);&lt;br /&gt;
&lt;br /&gt;
	endwin();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12478</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12478"/>
		<updated>2009-09-21T19:55:22Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         4                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;tt&amp;gt;initscr();&amp;lt;/tt&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;tt&amp;gt;noecho();&amp;lt;/tt&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;tt&amp;gt;cbreak();&amp;lt;/tt&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;tt&amp;gt;keypad(stdscr, TRUE);&amp;lt;/tt&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;tt&amp;gt;nodelay(stdscr, TRUE);&amp;lt;/tt&amp;gt; damit die Funktion, die später die Tastendrücke entgegennimmt, nicht blockiert, bis eine Taste gedrückt wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion. Sie enthält als ersten Aufruf unsere &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt;-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextdatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Define-Makros angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;void place_paddles()&amp;lt;/tt&amp;gt; soll die Schläger mittig platzieren. Die Funktion &amp;lt;tt&amp;gt;void place_ball()&amp;lt;/tt&amp;gt; soll den Ball in der Mitte platzieren. Die x- und y-Richtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion &amp;lt;tt&amp;gt;void print_field()&amp;lt;/tt&amp;gt; geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst &amp;lt;tt&amp;gt;clear()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; von curses statt &amp;lt;tt&amp;gt;printf()&amp;lt;/tt&amp;gt; verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt;, indem du es in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein &amp;lt;tt&amp;gt;sleep(10)&amp;lt;/tt&amp;gt; ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstes kommt die Funktion &amp;lt;tt&amp;gt;void key_processing()&amp;lt;/tt&amp;gt; dran. Darin fragen wir nun folgendermaßen einen Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante &amp;lt;tt&amp;gt;KEY_UP&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;KEY_DOWN&amp;lt;/tt&amp;gt; bzw. den Buchstaben &amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'s'&amp;lt;/tt&amp;gt; vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt; und einer 100-Millisekunden-Pause in eine Endlosschleife gepackt werden. Für Pausen eignen sich die Funktionen &amp;lt;tt&amp;gt;sleep&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;usleep&amp;lt;/tt&amp;gt; aus ''stdlib.h''. Erstere nimmt Sekunden, letztere Mikrosekunden an. (1 Sekunde = 1.000 Millisekunden = 1.000.000 Mikrosekunden)&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion &amp;lt;tt&amp;gt;void move_ball()&amp;lt;/tt&amp;gt;, die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion &amp;lt;tt&amp;gt;void detect_collision()&amp;lt;/tt&amp;gt; soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion &amp;lt;tt&amp;gt;int detect_ball_out()&amp;lt;/tt&amp;gt;. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; bzw. für die linke Seite &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; zurückgeben. Ansonsten gibt die Funktion &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion &amp;lt;tt&amp;gt;int play_round()&amp;lt;/tt&amp;gt; um. Der Rückgabewert soll der Wert sein, den &amp;lt;tt&amp;gt;detect_ball_out()&amp;lt;/tt&amp;gt; im Fall des Nichttreffens liefert. Bisher reagieren die Schläger noch recht langsam, weshalb wir die Pause in der Schleife auf 20 Millisekunden herabsetzen. Da nun aber der Ball viel zu schnell wird, sollte &amp;lt;tt&amp;gt;move_ball&amp;lt;/tt&amp;gt; nur jeden fünften Schleifendurchlauf aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
In der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser &amp;lt;tt&amp;gt;play_round()&amp;lt;/tt&amp;gt;; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfache Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Wenn sich der Schläger jetzt genauso schnell, wie der Ball, bewegen kann, wäre die KI aber nicht besiegbar. Deswegen sollte die Bewegung verlangsamt werden (z.B. indem der Schläger nur in jedem zweiten Schritt bewegt wird).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12477</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12477"/>
		<updated>2009-09-21T19:42:26Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         4                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;tt&amp;gt;initscr();&amp;lt;/tt&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;tt&amp;gt;noecho();&amp;lt;/tt&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;tt&amp;gt;cbreak();&amp;lt;/tt&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;tt&amp;gt;keypad(stdscr, TRUE);&amp;lt;/tt&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;tt&amp;gt;nodelay();&amp;lt;/tt&amp;gt; damit die Funktion, die später die Tastendrücke entgegennimmt, nicht blockiert, bis eine Taste gedrückt wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion. Sie enthält als ersten Aufruf unsere &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt;-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextdatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Define-Makros angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;void place_paddles()&amp;lt;/tt&amp;gt; soll die Schläger mittig platzieren. Die Funktion &amp;lt;tt&amp;gt;void place_ball()&amp;lt;/tt&amp;gt; soll den Ball in der Mitte platzieren. Die x- und y-Richtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion &amp;lt;tt&amp;gt;void print_field()&amp;lt;/tt&amp;gt; geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst &amp;lt;tt&amp;gt;clear()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; von curses statt &amp;lt;tt&amp;gt;printf()&amp;lt;/tt&amp;gt; verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt;, indem du es in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein &amp;lt;tt&amp;gt;sleep(10)&amp;lt;/tt&amp;gt; ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstes kommt die Funktion &amp;lt;tt&amp;gt;void key_processing()&amp;lt;/tt&amp;gt; dran. Darin fragen wir nun folgendermaßen einen Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante &amp;lt;tt&amp;gt;KEY_UP&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;KEY_DOWN&amp;lt;/tt&amp;gt; bzw. den Buchstaben &amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'s'&amp;lt;/tt&amp;gt; vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt; und einer 100-Millisekunden-Pause in eine Endlosschleife gepackt werden. Für Pausen eignen sich die Funktionen &amp;lt;tt&amp;gt;sleep&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;usleep&amp;lt;/tt&amp;gt; aus ''stdlib.h''. Erstere nimmt Sekunden, letztere Mikrosekunden an. (1 Sekunde = 1.000 Millisekunden = 1.000.000 Mikrosekunden)&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion &amp;lt;tt&amp;gt;void move_ball()&amp;lt;/tt&amp;gt;, die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion &amp;lt;tt&amp;gt;void detect_collision()&amp;lt;/tt&amp;gt; soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion &amp;lt;tt&amp;gt;int detect_ball_out()&amp;lt;/tt&amp;gt;. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; bzw. für die linke Seite &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; zurückgeben. Ansonsten gibt die Funktion &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion &amp;lt;tt&amp;gt;int play_round()&amp;lt;/tt&amp;gt; um. Der Rückgabewert soll der Wert sein, den &amp;lt;tt&amp;gt;detect_ball_out()&amp;lt;/tt&amp;gt; im Fall des Nichttreffens liefert. Bisher reagieren die Schläger noch recht langsam, weshalb wir die Pause in der Schleife auf 20 Millisekunden herabsetzen. Da nun aber der Ball viel zu schnell wird, sollte &amp;lt;tt&amp;gt;move_ball&amp;lt;/tt&amp;gt; nur jeden fünften Schleifendurchlauf aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
In der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser &amp;lt;tt&amp;gt;play_round()&amp;lt;/tt&amp;gt;; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfache Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Wenn sich der Schläger jetzt genauso schnell, wie der Ball, bewegen kann, wäre die KI aber nicht besiegbar. Deswegen sollte die Bewegung verlangsamt werden (z.B. indem der Schläger nur in jedem zweiten Schritt bewegt wird).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank/Musterl%C3%B6sung&amp;diff=12468</id>
		<title>C-Kurs/Studentendatenbank/Musterlösung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank/Musterl%C3%B6sung&amp;diff=12468"/>
		<updated>2009-09-21T18:00:56Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Musterlösung ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ANZAHL 10&lt;br /&gt;
#define NAME_LEN 25&lt;br /&gt;
&lt;br /&gt;
#define NAME_TO_LONG (-1)&lt;br /&gt;
#define MAT_NR_USED (-2)&lt;br /&gt;
#define DB_FULL (-3)&lt;br /&gt;
#define ADD_SUCCEED 1&lt;br /&gt;
#define NO_MAT_NR (-1)&lt;br /&gt;
#define DEL_SUCCEED 1&lt;br /&gt;
&lt;br /&gt;
/* Teil a */&lt;br /&gt;
typedef struct student_t {&lt;br /&gt;
	int mat_nr;&lt;br /&gt;
	char first_name[NAME_LEN];&lt;br /&gt;
	char last_name[NAME_LEN];&lt;br /&gt;
} student;&lt;br /&gt;
&lt;br /&gt;
/* Teil b */&lt;br /&gt;
void print_student(student *studi) {&lt;br /&gt;
	printf(&amp;quot;Matr.Nr.: %i, Vorname: %s, Nachname: %s\n&amp;quot;, studi-&amp;gt;mat_nr, studi-&amp;gt;first_name, studi-&amp;gt;last_name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Teil c */&lt;br /&gt;
void print_students_db(student **db) {&lt;br /&gt;
	printf(&amp;quot;===========================================================\n&amp;quot;);&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;ANZAHL; i++) {&lt;br /&gt;
		if (db[i] != NULL) {&lt;br /&gt;
			print_student(db[i]);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	printf(&amp;quot;===========================================================\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Teil e */&lt;br /&gt;
void clear_db(student **db) {&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;ANZAHL; i++) {&lt;br /&gt;
		if (db[i] != NULL) {&lt;br /&gt;
			free(db[i]);&lt;br /&gt;
			db[i] = NULL;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Teil f */&lt;br /&gt;
int get_student_index(int mat_nr, student **db) {&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;ANZAHL; i++) {&lt;br /&gt;
		if (db[i] != NULL) {&lt;br /&gt;
			if (mat_nr == db[i]-&amp;gt;mat_nr) {&lt;br /&gt;
				return i;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return -1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int add_student(int mat_nr, char *first_name, char *last_name, student **db) {&lt;br /&gt;
	if (strlen(first_name) &amp;gt;= NAME_LEN || strlen(last_name) &amp;gt;= NAME_LEN) {&lt;br /&gt;
		return NAME_TO_LONG;&lt;br /&gt;
	}&lt;br /&gt;
	if (get_student_index(mat_nr, db) &amp;gt;= 0) {&lt;br /&gt;
		return MAT_NR_USED;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;=ANZAHL; i++) {&lt;br /&gt;
		if (db[i] == NULL) {&lt;br /&gt;
			db[i] = malloc(sizeof(student));&lt;br /&gt;
			db[i]-&amp;gt;mat_nr = mat_nr;&lt;br /&gt;
			strcpy(db[i]-&amp;gt;first_name, first_name);&lt;br /&gt;
			strcpy(db[i]-&amp;gt;last_name, last_name);&lt;br /&gt;
			return ADD_SUCCEED;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return DB_FULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Teil g */&lt;br /&gt;
int del_student(int mat_nr, student **db) {&lt;br /&gt;
	int del_student_index = get_student_index(mat_nr, db);&lt;br /&gt;
	if (del_student_index &amp;lt; 0) {&lt;br /&gt;
		return NO_MAT_NR;&lt;br /&gt;
	}&lt;br /&gt;
	free(db[del_student_index]);&lt;br /&gt;
	db[del_student_index] = NULL;&lt;br /&gt;
	return DEL_SUCCEED;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
	/* Teil b*/ printf(&amp;quot;&amp;gt;&amp;gt;&amp;gt; Teil b\n&amp;quot;);&lt;br /&gt;
	student *one_student = malloc(sizeof(student));&lt;br /&gt;
	one_student-&amp;gt;mat_nr = 123456;&lt;br /&gt;
	strcpy(one_student-&amp;gt;first_name, &amp;quot;Max&amp;quot;);&lt;br /&gt;
	strcpy(one_student-&amp;gt;last_name, &amp;quot;Mustermann&amp;quot;);&lt;br /&gt;
	print_student(one_student);&lt;br /&gt;
&lt;br /&gt;
	/* Teil c */ printf(&amp;quot;&amp;gt;&amp;gt;&amp;gt; Teil c\n&amp;quot;);&lt;br /&gt;
	student *all_students[ANZAHL];&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;ANZAHL; i++) {&lt;br /&gt;
		all_students[i] = NULL;&lt;br /&gt;
	}&lt;br /&gt;
	all_students[0] = one_student;&lt;br /&gt;
	print_students_db(all_students);&lt;br /&gt;
&lt;br /&gt;
	/* Teil d */ printf(&amp;quot;&amp;gt;&amp;gt;&amp;gt; Teil d\n&amp;quot;);&lt;br /&gt;
	all_students[1] = malloc(sizeof(student));&lt;br /&gt;
	all_students[1]-&amp;gt;mat_nr=653321;&lt;br /&gt;
	strcpy(all_students[1]-&amp;gt;first_name, &amp;quot;Herbert&amp;quot;);&lt;br /&gt;
	strcpy(all_students[1]-&amp;gt;last_name, &amp;quot;Meier&amp;quot;);&lt;br /&gt;
	all_students[2] = malloc(sizeof(student));&lt;br /&gt;
	all_students[2]-&amp;gt;mat_nr=765431;&lt;br /&gt;
	strcpy(all_students[2]-&amp;gt;first_name, &amp;quot;Hubertine&amp;quot;);&lt;br /&gt;
	strcpy(all_students[2]-&amp;gt;last_name, &amp;quot;Schulze&amp;quot;);&lt;br /&gt;
	free(all_students[0]);&lt;br /&gt;
	all_students[0] = NULL;&lt;br /&gt;
	print_students_db(all_students);&lt;br /&gt;
&lt;br /&gt;
	/* Teil e */ printf(&amp;quot;&amp;gt;&amp;gt;&amp;gt; Teil e\n&amp;quot;);&lt;br /&gt;
	clear_db(all_students);&lt;br /&gt;
&lt;br /&gt;
	/* Teil f */ printf(&amp;quot;&amp;gt;&amp;gt;&amp;gt; Teil f\n&amp;quot;);&lt;br /&gt;
	if (add_student(123456, &amp;quot;Peter&amp;quot;, &amp;quot;Mueller&amp;quot;, all_students) == ADD_SUCCEED) {&lt;br /&gt;
		printf(&amp;quot;Student hinzugefuegt.\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	if (add_student(123456, &amp;quot;Hans&amp;quot;, &amp;quot;Wurst&amp;quot;, all_students) == MAT_NR_USED) {&lt;br /&gt;
		printf(&amp;quot;Student nicht hinzugefuegt, da Mat.nr. schon benutzt wird.\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	if (add_student(123457, &amp;quot;Hans&amp;quot;, &amp;quot;Wurst&amp;quot;, all_students) == ADD_SUCCEED) {&lt;br /&gt;
		printf(&amp;quot;Student hinzugefuegt..\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	print_students_db(all_students);&lt;br /&gt;
&lt;br /&gt;
	/* Teil g */ printf(&amp;quot;&amp;gt;&amp;gt;&amp;gt; Teil g\n&amp;quot;);&lt;br /&gt;
	if (del_student(123456, all_students) == DEL_SUCCEED) {&lt;br /&gt;
		printf(&amp;quot;Student entfernt.\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	print_students_db(all_students);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12467</id>
		<title>C-Kurs/Studentendatenbank</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12467"/>
		<updated>2009-09-21T17:53:44Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll eine kleine Studentendatenbank erstellt werden.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
=== Teil a ===&lt;br /&gt;
Schreibe eine Struktur &amp;lt;tt&amp;gt;student&amp;lt;/tt&amp;gt;, die eine Matrikelnummer, einen Vornamen und einen Nachnamen mit jeweils passenden Datentypen enthält.&lt;br /&gt;
&lt;br /&gt;
=== Teil b ===&lt;br /&gt;
Deklariere einen Pointer auf einen solchen Student und alloziere ihn passend. Initialisiere seine Martrikelnummer, seinen Vornamen und Nachnamen mit sinnvollen Werten.&lt;br /&gt;
Schreibe nun eine Funktion &amp;lt;tt&amp;gt;print_student&amp;lt;/tt&amp;gt;, die einen Pointer auf einen Studenten übergeben bekommt und seine Details in einer Zeile ausgeben soll. Teste diese Funktion jetzt mit dem zuvor angelegten Studenten.&lt;br /&gt;
&lt;br /&gt;
=== Teil c ===&lt;br /&gt;
Lege jetzt ein Array von Pointern auf Studenten der Größe 10 an. Initialisiere zunächst alle Elemente mit &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, damit sich darin unvorhersehbaren Studenten befinden. Weise nun dem ersten Element den aus Teil b angelegten Studenten zu.&lt;br /&gt;
Schreibe nun einen Funktion &amp;lt;tt&amp;gt;print_students_db&amp;lt;/tt&amp;gt;, die ein Pointer auf ein Array aus Studenten-Pointern übergeben bekommt, und alle Studenten ausgeben soll. Prüfe dabei, ob das jeweilige Element nicht &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; ist und benutzte dann die vorher geschriebene Funktion &amp;lt;tt&amp;gt;print_student&amp;lt;/tt&amp;gt;. Wende nun die Funktion auf die Studentendatenbank an.&lt;br /&gt;
&lt;br /&gt;
=== Teil d ===&lt;br /&gt;
Lege nun mindestens zwei weitere Studenten in der Datenbank an und lösche den ersten (dabei nicht vergessen, den Speicher wieder freizugeben). Gebe erneut die Studentendatenbank aus und überprüfe das Ergebnis.&lt;br /&gt;
&lt;br /&gt;
=== Teil e ===&lt;br /&gt;
Am Ende wollen wir wieder aufräumen. Schreibe dazu eine Funktion &amp;lt;tt&amp;gt;clear_db&amp;lt;/tt&amp;gt;, die die Studentendatenbank (wieder ein Pointer auf das Studenten-Pointer-Array) übergeben bekommt, und darin alle Einträge, die nicht &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; sind, löscht (also deren Speicher freigibt).&lt;br /&gt;
&lt;br /&gt;
=== Teil f ===&lt;br /&gt;
Schreibe eine Funktion &amp;lt;tt&amp;gt;get_student_index&amp;lt;/tt&amp;gt;, die eine Matrikelnummer und die Studentendatenbank übergeben bekommt. Sie soll die Indexposition im Array zurückgeben, an der der gesuchte Student zu finden ist. Falls es keinen Student gibt, der die Matrikelnummer hat, soll ''-1'' zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Schreibe anschließend eine Funktion &amp;lt;tt&amp;gt;add_student&amp;lt;/tt&amp;gt;, die Matrikelnummer, Vor- und Nachname des hinzuzufügenden Studenten und die Studentendatenbank übergeben bekommt. Benutzte darin die Funktion &amp;lt;tt&amp;gt;get_student_index&amp;lt;/tt&amp;gt;, um sicherzustellen, dass du nicht mehrere Studenten mit derselben Matrikelnummer in der Datenbank hast. Füge den neuen Studenten im Array an der ersten Position, die &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; enthält, ein. Überlege die auch einen passenden Rückgabewert, der angibt, ob der Student erfolgreich eingefügt werden soll.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du mindestens drei Studenten einfügst, von denen zwei die gleiche Matrikelnummer haben.&lt;br /&gt;
&lt;br /&gt;
=== Teil g ===&lt;br /&gt;
Schreibe eine Funktion &amp;lt;tt&amp;gt;del_student&amp;lt;/tt&amp;gt;, die eine Matrikelnummer und die Studentendatenbank übergeben bekommt. Sie soll den entsprechenden Studenten löschen. Verwende den Rückgabewert ebenfalls, um erfolgreichen Löschen anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du einen vorher eingefügten Studenten wieder löscht.&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe ===&lt;br /&gt;
Schreibe jetzt eine menügesteuerte Benutzerschnittstelle, die Hinzufügen und Löschen eines Studenten, und Ausgeben der kompletten Datenbank, ermöglicht.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12376</id>
		<title>C-Kurs/Studentendatenbank</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12376"/>
		<updated>2009-09-19T19:12:19Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll eine kleine Studentendatenbank erstellt werden.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
=== Teil a ===&lt;br /&gt;
Schreibe eine Struktur &amp;lt;tt&amp;gt;student&amp;lt;/tt&amp;gt;, die eine Matrikelnummer, einen Vornamen und einen Nachnamen mit jeweils passenden Datentypen enthält.&lt;br /&gt;
&lt;br /&gt;
=== Teil b ===&lt;br /&gt;
Deklariere einen Pointer auf einen solchen Student und alloziere ihn passend. Initialisiere seine Martrikelnummer, seinen Vornamen und Nachnamen mit sinnvollen Werten.&lt;br /&gt;
Schreibe nun eine Funktion &amp;lt;tt&amp;gt;print_student&amp;lt;/tt&amp;gt;, die einen Pointer auf einen Studenten übergeben bekommt und seine Details in einer Zeile ausgeben soll. Teste diese Funktion jetzt mit dem zuvor angelegten Studenten.&lt;br /&gt;
&lt;br /&gt;
=== Teil c ===&lt;br /&gt;
Lege jetzt ein Array von Pointern auf Studenten der Größe 10 an. Initialisiere zunächst alle Elemente mit &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, damit sich darin unvorhersehbaren Studenten befinden. Weise nun dem ersten Element den aus Teil b angelegten Studenten zu.&lt;br /&gt;
Schreibe nun einen Funktion &amp;lt;tt&amp;gt;print_studenten_db&amp;lt;/tt&amp;gt;, die ein Pointer auf ein Array aus Studenten-Pointern übergeben bekommt, und alle Studenten ausgeben soll. Prüfe dabei, ob das jeweilige Element nicht &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; ist und benutzte dann die vorher geschriebene Funktion &amp;lt;tt&amp;gt;print_student&amp;lt;/tt&amp;gt;. Wende nun die Funktion auf die Studentendatenbank an.&lt;br /&gt;
&lt;br /&gt;
=== Teil d ===&lt;br /&gt;
Lege nun mindestens zwei weitere Studenten in der Datenbank an und lösche den ersten (dabei nicht vergessen, den Speicher wieder freizugeben). Gebe erneut die Studentendatenbank aus und überprüfe das Ergebnis.&lt;br /&gt;
&lt;br /&gt;
=== Teil e ===&lt;br /&gt;
Am Ende wollen wir wieder aufräumen. Schreibe dazu eine Funktion &amp;lt;tt&amp;gt;clear_db&amp;lt;/tt&amp;gt;, die die Studentendatenbank (wieder ein Pointer auf das Studenten-Pointer-Array) übergeben bekommt, und darin alle Einträge, die nicht &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; sind, löscht (also deren Speicher freigibt).&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12375</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12375"/>
		<updated>2009-09-19T19:08:48Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. &amp;lt;tt&amp;gt;scanf&amp;lt;/tt&amp;gt; arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;tt&amp;gt;initscr();&amp;lt;/tt&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;tt&amp;gt;noecho();&amp;lt;/tt&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;tt&amp;gt;cbreak();&amp;lt;/tt&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;tt&amp;gt;keypad(stdscr, TRUE);&amp;lt;/tt&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;tt&amp;gt;halfdelay(1);&amp;lt;/tt&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion. Sie enthält als ersten Aufruf unsere &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt;-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextdatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;void place_paddles()&amp;lt;/tt&amp;gt; soll die Schläger mittig platzieren. Die Funktion &amp;lt;tt&amp;gt;void place_ball()&amp;lt;/tt&amp;gt; soll den Ball in der Mitte platzieren. Die x- und y-Richtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion &amp;lt;tt&amp;gt;void print_field()&amp;lt;/tt&amp;gt; geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst &amp;lt;tt&amp;gt;clear()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; von curses statt &amp;lt;tt&amp;gt;printf()&amp;lt;/tt&amp;gt; verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt;, indem du es in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein &amp;lt;tt&amp;gt;sleep(10)&amp;lt;/tt&amp;gt; ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstes kommt die Funktion &amp;lt;tt&amp;gt;void key_processing()&amp;lt;/tt&amp;gt; dran. Darin fragen wir nun folgendermaßen einen Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante &amp;lt;tt&amp;gt;KEY_UP&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;KEY_DOWN&amp;lt;/tt&amp;gt; bzw. den Buchstaben &amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;'s'&amp;lt;/tt&amp;gt; vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit &amp;lt;tt&amp;gt;print_field()&amp;lt;/tt&amp;gt; in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion &amp;lt;tt&amp;gt;void move_ball()&amp;lt;/tt&amp;gt;, die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion &amp;lt;tt&amp;gt;void detect_collision()&amp;lt;/tt&amp;gt; soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor &amp;lt;tt&amp;gt;move_ball&amp;lt;/tt&amp;gt;. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion &amp;lt;tt&amp;gt;int detect_ball_out()&amp;lt;/tt&amp;gt;. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; bzw. für die linke Seite &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; zurückgeben. Ansonsten gibt die Funktion &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion &amp;lt;tt&amp;gt;int play_round()&amp;lt;/tt&amp;gt; um. Der Rückgabewert soll der Wert sein, den &amp;lt;tt&amp;gt;detect_ball_out()&amp;lt;/tt&amp;gt; im Fall des Nichttreffens liefert.&lt;br /&gt;
&lt;br /&gt;
In der &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt;-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser &amp;lt;tt&amp;gt;play_round()&amp;lt;/tt&amp;gt;; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an &amp;lt;tt&amp;gt;place_ball&amp;lt;/tt&amp;gt; übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder &amp;lt;tt&amp;gt;printw()&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;refresh()&amp;lt;/tt&amp;gt; verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfache Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Wenn sich der Schläger jetzt genauso schnell, wie der Ball, bewegen kann, wäre die KI aber nicht besiegbar. Deswegen sollte die Bewegung verlangsamt werden (z.B. indem der Schläger nur in jedem zweiten Schritt bewegt wird).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als &amp;lt;tt&amp;gt;float&amp;lt;/tt&amp;gt; speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12374</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12374"/>
		<updated>2009-09-19T18:29:32Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Tippfehler&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextdatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Richtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstes kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen einen Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion ''void detect_collision()'' soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor ''move_ball''. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion ''int detect_ball_out()''. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite ''1'' bzw. für die linke Seite ''2'' zurückgeben. Ansonsten gibt die Funktion ''0'' zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion ''int play_round()'' um. Der Rückgabewert soll der Wert sein, den ''detect_ball_out()'' im Fall des Nichttreffens liefert.&lt;br /&gt;
&lt;br /&gt;
In der ''main''-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser ''play_round()''; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit ''place_ball'' neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an ''place_ball'' übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder ''printw()'' und ''refresh()'' verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfache Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Wenn sich der Schläger jetzt genauso schnell, wie der Ball, bewegen kann, wäre die KI aber nicht besiegbar. Deswegen sollte die Bewegung verlangsamt werden (z.B. indem der Schläger nur in jedem zweiten Schritt bewegt wird).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als ''float'' speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12373</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12373"/>
		<updated>2009-09-19T17:37:13Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Variablen für den Zustand des Spiels */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Richtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion ''void detect_collision()'' soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor ''move_ball''. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion ''int detect_ball_out()''. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite ''1'' bzw. für die linke Seite ''2'' zurückgeben. Ansonsten gibt die Funktion ''0'' zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion ''int play_round()'' um. Der Rückgabewert soll der Wert sein, den ''detect_ball_out()'' im Fall des Nichttreffens liefert.&lt;br /&gt;
&lt;br /&gt;
In der ''main''-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser ''play_round()''; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit ''place_ball'' neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an ''place_ball'' übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder ''printw()'' und ''refresh()'' verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfache Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Wenn sich der Schläger jetzt genauso schnell, wie der Ball bewegen kann, wäre die KI aber nicht besiegbar. Deswegen sollte die Bewegung verlangsamt werden (z.B. indem der Schläger nur in jedem zweiten Schritt bewegt wird).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als ''float'' speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12372</id>
		<title>C-Kurs/Übungsaufgaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12372"/>
		<updated>2009-09-19T17:32:25Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Die Aufgaben */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wir haben jeder Aufgabe eine Einschätzung ihrer Schwierigkeit auf einer Skala von 1 bis 10 vorangestellt. Bei dieser Einschätzung sind wir von einem Gehirn ausgegangen, für welches das jeweilige Themengebiet völlig neu ist, das jedoch schon ein ganz gutes Verständnis dafür hat wie eine Programmiersprache denn so funktioniert. &lt;br /&gt;
Entsprechend kann eine schwer bewertete Aufgabe aus einem frühen Themengebiet für manch einen sehr einfach oder eine leicht bewertete aus einem späten Themengebiet für einen anderen sehr schwer sein. Es ist nur ein Wert, der euch helfen soll eure nächste Aufgabe zu wählen. &lt;br /&gt;
&lt;br /&gt;
Falls ihr Anmerkungen zu den Aufgaben habt, könnt ihr die Diskussionsseiten der jeweiligen Aufgaben nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeitsgrade ==&lt;br /&gt;
&lt;br /&gt;
#  Reines Tutorial. Man muss nicht viel selbst denken&lt;br /&gt;
#  ...&lt;br /&gt;
#  Leichte Übungsaufgabe. Studies, die noch eher unsicher sind werden hier gut begleitet.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Typische Aufgabe. Man muss den Kopf benutzen, bekommt an schwierigen Stellen aber Hilfestellungen.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Herausfordernd, eher etwas für Studies die etwas fitter sind.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Auch erfahrene Programmierer werden hier ein bis zwei Übungen beschäftigt sein&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#  Tja, die Idee war da. Wir finden sie auch gut, aber es könnte wirklich anstrengend werden.&lt;br /&gt;
&lt;br /&gt;
== Die Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;2&amp;quot;&lt;br /&gt;
 |- bgcolor=&amp;quot;#D8D8D8&amp;quot;&lt;br /&gt;
 !Aufgabe&lt;br /&gt;
 !Schwierigkeit&lt;br /&gt;
 !Vorwissen&lt;br /&gt;
 !Lerneffekte&lt;br /&gt;
 !Bearbeiter&lt;br /&gt;
 !Korrektur gelesen&lt;br /&gt;
 !Musterlösung&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Von der Konsole zum HelloWorld | Von der Konsole zum HelloWorld]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Konsole benutzen, Hello World&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe | Ein- und Ausgabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Ausgabe derselben&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner | Taschenrechner]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Eingabe+Ausgabe&amp;lt;br&amp;gt;Mathematische Operatoren&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/VerschachtelteSchleifen | Verschachtelte Schleifen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Umgang mit mehreren verschachtelten Schleifen&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Glückspiel | Glücksspiel]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Anwenden von Fallunterscheidungen und Einlesen von Werten aus der Konsole&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Wochentag | Wochentagsrechnung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Mathematikverständniss&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (Musterlösung noch nicht vorhanden)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0 | Taschenrechner ''2.0'']]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Knobeln&amp;lt;br&amp;gt;Komplexes Aufgaben lösen&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Call by reference | Call by reference]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Einfache Anwendung von &amp;amp;/*&lt;br /&gt;
 | sping&lt;br /&gt;
 | nion&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Text processing | Text processing]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4, 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Strings&amp;lt;br&amp;gt;Pointer-Arithmetik&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Refactoring&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation | Matrizenmultiplikation]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mehrdimensionale Arrays&amp;lt;br&amp;gt;const correctness&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe | Arrayuebergabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4/5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Pointer und Pointerarithmetik&lt;br /&gt;
 | nion&lt;br /&gt;
 | martin&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank | Studentendatenbank]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | struct, Pointer, Arrays&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Cat | Cat]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | ....&lt;br /&gt;
 | Arbeiten mit Dateien&amp;lt;br&amp;gt;Kommandozeilenparameter&lt;br /&gt;
 | nion&lt;br /&gt;
 | sping&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Pong | Pong]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | ...&lt;br /&gt;
 | allgemeiner Programmablauf, fortgeschrittene Konsolenausgaben/eingaben&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Kleine und große Probleme ==&lt;br /&gt;
&lt;br /&gt;
* Die Tubit-Accounts haben nicht /bin/bash als shell, so dass die &amp;lt;strong&amp;gt;Cursortasten&amp;lt;/strong&amp;gt; nicht funktionieren. Workaround: als erstes Kommando 'bash' eingeben, man sieht dann auch in welchem Verzeichnis man gerade ist.&lt;br /&gt;
&lt;br /&gt;
== Musterlösungen ==&lt;br /&gt;
Die Lösungen zu den Aufgaben werden nach den jeweiligen Übungen hier veröffentlicht. Falls dies nicht geschiet, bitte den zuständigen Tutor fragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Ckurs2009/Feedback|Feedback zum Kurs 2009]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12371</id>
		<title>C-Kurs/Übungsaufgaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12371"/>
		<updated>2009-09-19T17:27:02Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Die Aufgaben */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wir haben jeder Aufgabe eine Einschätzung ihrer Schwierigkeit auf einer Skala von 1 bis 10 vorangestellt. Bei dieser Einschätzung sind wir von einem Gehirn ausgegangen, für welches das jeweilige Themengebiet völlig neu ist, das jedoch schon ein ganz gutes Verständnis dafür hat wie eine Programmiersprache denn so funktioniert. &lt;br /&gt;
Entsprechend kann eine schwer bewertete Aufgabe aus einem frühen Themengebiet für manch einen sehr einfach oder eine leicht bewertete aus einem späten Themengebiet für einen anderen sehr schwer sein. Es ist nur ein Wert, der euch helfen soll eure nächste Aufgabe zu wählen. &lt;br /&gt;
&lt;br /&gt;
Falls ihr Anmerkungen zu den Aufgaben habt, könnt ihr die Diskussionsseiten der jeweiligen Aufgaben nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeitsgrade ==&lt;br /&gt;
&lt;br /&gt;
#  Reines Tutorial. Man muss nicht viel selbst denken&lt;br /&gt;
#  ...&lt;br /&gt;
#  Leichte Übungsaufgabe. Studies, die noch eher unsicher sind werden hier gut begleitet.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Typische Aufgabe. Man muss den Kopf benutzen, bekommt an schwierigen Stellen aber Hilfestellungen.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Herausfordernd, eher etwas für Studies die etwas fitter sind.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Auch erfahrene Programmierer werden hier ein bis zwei Übungen beschäftigt sein&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#  Tja, die Idee war da. Wir finden sie auch gut, aber es könnte wirklich anstrengend werden.&lt;br /&gt;
&lt;br /&gt;
== Die Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;2&amp;quot;&lt;br /&gt;
 |- bgcolor=&amp;quot;#D8D8D8&amp;quot;&lt;br /&gt;
 !Aufgabe&lt;br /&gt;
 !Schwierigkeit&lt;br /&gt;
 !Vorwissen&lt;br /&gt;
 !Lerneffekte&lt;br /&gt;
 !Bearbeiter&lt;br /&gt;
 !Korrektur gelesen&lt;br /&gt;
 !Musterlösung&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Von der Konsole zum HelloWorld | Von der Konsole zum HelloWorld]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Konsole benutzen, Hello World&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe | Ein- und Ausgabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Ausgabe derselben&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner | Taschenrechner]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Eingabe+Ausgabe&amp;lt;br&amp;gt;Mathematische Operatoren&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/VerschachtelteSchleifen | Verschachtelte Schleifen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Umgang mit mehreren verschachtelten Schleifen&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Glückspiel | Glücksspiel]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Anwenden von Fallunterscheidungen und Einlesen von Werten aus der Konsole&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Wochentag | Wochentagsrechnung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Mathematikverständniss&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (Musterlösung noch nicht vorhanden)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0 | Taschenrechner ''2.0'']]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Knobeln&amp;lt;br&amp;gt;Komplexes Aufgaben lösen&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Call by reference | Call by reference]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Einfache Anwendung von &amp;amp;/*&lt;br /&gt;
 | sping&lt;br /&gt;
 | nion&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Text processing | Text processing]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4, 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Strings&amp;lt;br&amp;gt;Pointer-Arithmetik&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Refactoring&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation | Matrizenmultiplikation]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mehrdimensionale Arrays&amp;lt;br&amp;gt;const correctness&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe | Arrayuebergabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4/5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Pointer und Pointerarithmetik&lt;br /&gt;
 | nion&lt;br /&gt;
 | martin&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank | Studentendatenbank]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | struct, Pointer, Arrays&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Cat | Cat]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | ....&lt;br /&gt;
 | Arbeiten mit Dateien&amp;lt;br&amp;gt;Kommandozeilenparameter&lt;br /&gt;
 | nion&lt;br /&gt;
 | sping&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Pong | Pong]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | ...&lt;br /&gt;
 | allgemeiner Programmablauf, fortgeschrittene Konsolenausgaben/eingaben&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Kleine und große Probleme ==&lt;br /&gt;
&lt;br /&gt;
* Die Tubit-Accounts haben nicht /bin/bash als shell, so dass die &amp;lt;strong&amp;gt;Cursortasten&amp;lt;/strong&amp;gt; nicht funktionieren. Workaround: als erstes Kommando 'bash' eingeben, man sieht dann auch in welchem Verzeichnis man gerade ist.&lt;br /&gt;
&lt;br /&gt;
== Musterlösungen ==&lt;br /&gt;
Die Lösungen zu den Aufgaben werden nach den jeweiligen Übungen hier veröffentlicht. Falls dies nicht geschiet, bitte den zuständigen Tutor fragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Ckurs2009/Feedback|Feedback zum Kurs 2009]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12370</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12370"/>
		<updated>2009-09-19T17:21:51Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion ''void detect_collision()'' soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor ''move_ball''. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion ''int detect_ball_out()''. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite ''1'' bzw. für die linke Seite ''2'' zurückgeben. Ansonsten gibt die Funktion ''0'' zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion ''int play_round()'' um. Der Rückgabewert soll der Wert sein, den ''detect_ball_out()'' im Fall des Nichttreffens liefert.&lt;br /&gt;
&lt;br /&gt;
In der ''main''-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser ''play_round()''; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit ''place_ball'' neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an ''place_ball'' übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder ''printw()'' und ''refresh()'' verwenden).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: KI ===&lt;br /&gt;
Statt des zweiten Spielers soll nun ein Computergegner spielen. Eine einfache Lösung wäre, in jedem Schritt den die y-Position des Balls mit der des Schlägers zu vergleichen und ihn entsprechend nach oben/unten zu bewegen. Wenn sich der Schläger jetzt genauso schnell, wie der Ball bewegen kann, wäre die KI aber nicht besiegbar. Deswegen sollte die Bewegung verlangsamt werden (z.B. indem der Schläger nur in jedem zweiten Schritt bewegt wird).&lt;br /&gt;
&lt;br /&gt;
=== Zusatzaufgabe: andere Winkel des Balls ===&lt;br /&gt;
Bisher fliegt der Ball immer im 45°-Winkel. Beim originalen Pong verändert sich der Winkel jedoch bei jedem Aufschlag auf den Schläger zufällig. Man könnte jetzt die Ballpositionen und -richtungen intern als ''float'' speichern, um andere Winkel zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12369</id>
		<title>C-Kurs/Übungsaufgaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12369"/>
		<updated>2009-09-19T16:59:48Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Die Aufgaben */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wir haben jeder Aufgabe eine Einschätzung ihrer Schwierigkeit auf einer Skala von 1 bis 10 vorangestellt. Bei dieser Einschätzung sind wir von einem Gehirn ausgegangen, für welches das jeweilige Themengebiet völlig neu ist, das jedoch schon ein ganz gutes Verständnis dafür hat wie eine Programmiersprache denn so funktioniert. &lt;br /&gt;
Entsprechend kann eine schwer bewertete Aufgabe aus einem frühen Themengebiet für manch einen sehr einfach oder eine leicht bewertete aus einem späten Themengebiet für einen anderen sehr schwer sein. Es ist nur ein Wert, der euch helfen soll eure nächste Aufgabe zu wählen. &lt;br /&gt;
&lt;br /&gt;
Falls ihr Anmerkungen zu den Aufgaben habt, könnt ihr die Diskussionsseiten der jeweiligen Aufgaben nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeitsgrade ==&lt;br /&gt;
&lt;br /&gt;
#  Reines Tutorial. Man muss nicht viel selbst denken&lt;br /&gt;
#  ...&lt;br /&gt;
#  Leichte Übungsaufgabe. Studies, die noch eher unsicher sind werden hier gut begleitet.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Typische Aufgabe. Man muss den Kopf benutzen, bekommt an schwierigen Stellen aber Hilfestellungen.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Herausfordernd, eher etwas für Studies die etwas fitter sind.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Auch erfahrene Programmierer werden hier ein bis zwei Übungen beschäftigt sein&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#  Tja, die Idee war da. Wir finden sie auch gut, aber es könnte wirklich anstrengend werden.&lt;br /&gt;
&lt;br /&gt;
== Die Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;2&amp;quot;&lt;br /&gt;
 |- bgcolor=&amp;quot;#D8D8D8&amp;quot;&lt;br /&gt;
 !Aufgabe&lt;br /&gt;
 !Schwierigkeit&lt;br /&gt;
 !Vorwissen&lt;br /&gt;
 !Lerneffekte&lt;br /&gt;
 !Bearbeiter&lt;br /&gt;
 !Korrektur gelesen&lt;br /&gt;
 !Musterlösung&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Von der Konsole zum HelloWorld | Von der Konsole zum HelloWorld]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Konsole benutzen, Hello World&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe | Ein- und Ausgabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Ausgabe derselben&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner | Taschenrechner]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Eingabe+Ausgabe&amp;lt;br&amp;gt;Mathematische Operatoren&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/VerschachtelteSchleifen | Verschachtelte Schleifen]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Umgang mit mehreren verschachtelten Schleifen&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Glückspiel | Glücksspiel]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Anwenden von Fallunterscheidungen und Einlesen von Werten aus der Konsole&lt;br /&gt;
 | [[Benutzer:Dank|Daniel K.]]&lt;br /&gt;
 |&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Wochentag | Wochentagsrechnung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Mathematikverständniss&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (Musterlösung noch nicht vorhanden)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0 | Taschenrechner ''2.0'']]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Knobeln&amp;lt;br&amp;gt;Komplexes Aufgaben lösen&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | martin&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Call by reference | Call by reference]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Einfache Anwendung von &amp;amp;/*&lt;br /&gt;
 | sping&lt;br /&gt;
 | nion&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Text processing | Text processing]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4, 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Strings&amp;lt;br&amp;gt;Pointer-Arithmetik&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Refactoring&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation | Matrizenmultiplikation]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mehrdimensionale Arrays&amp;lt;br&amp;gt;const correctness&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe | Arrayuebergabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4/5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Pointer und Pointerarithmetik&lt;br /&gt;
 | nion&lt;br /&gt;
 | martin&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank | Studentendatenbank]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | struct, Pointer, Arrays&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Cat | Cat]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | ....&lt;br /&gt;
 | Arbeiten mit Dateien&amp;lt;br&amp;gt;Kommandozeilenparameter&lt;br /&gt;
 | nion&lt;br /&gt;
 | sping&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Pong | Pong]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 7&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | ...&lt;br /&gt;
 | allgemeiner Programmablauf, fortgeschrittene Konsolenausgaben/eingaben&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Kleine und große Probleme ==&lt;br /&gt;
&lt;br /&gt;
* Die Tubit-Accounts haben nicht /bin/bash als shell, so dass die &amp;lt;strong&amp;gt;Cursortasten&amp;lt;/strong&amp;gt; nicht funktionieren. Workaround: als erstes Kommando 'bash' eingeben, man sieht dann auch in welchem Verzeichnis man gerade ist.&lt;br /&gt;
&lt;br /&gt;
== Musterlösungen ==&lt;br /&gt;
Die Lösungen zu den Aufgaben werden nach den jeweiligen Übungen hier veröffentlicht. Falls dies nicht geschiet, bitte den zuständigen Tutor fragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Ckurs2009/Feedback|Feedback zum Kurs 2009]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong/Musterl%C3%B6sung&amp;diff=12368</id>
		<title>C-Kurs/Pong/Musterlösung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong/Musterl%C3%B6sung&amp;diff=12368"/>
		<updated>2009-09-19T16:52:59Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Die Seite wurde neu angelegt: „== Musterlösung == &amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt;  /* dimensions of the field */ #define WIDTH 40 #define HEIGHT 15 #define PADDLE_HEIGHT 3  /* positions of playing t...“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Musterlösung ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;curses.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* dimensions of the field */&lt;br /&gt;
#define WIDTH 40&lt;br /&gt;
#define HEIGHT 15&lt;br /&gt;
#define PADDLE_HEIGHT 3&lt;br /&gt;
&lt;br /&gt;
/* positions of playing things */&lt;br /&gt;
int pos_p1_y;&lt;br /&gt;
int pos_p2_y;&lt;br /&gt;
int pos_ball_x;&lt;br /&gt;
int pos_ball_y;&lt;br /&gt;
int dir_ball_x;&lt;br /&gt;
int dir_ball_y;&lt;br /&gt;
&lt;br /&gt;
/* scores */&lt;br /&gt;
int score_p1 = 0;&lt;br /&gt;
int score_p2 = 0;&lt;br /&gt;
&lt;br /&gt;
void init() {&lt;br /&gt;
	initscr(); // init for curses&lt;br /&gt;
	noecho();  // don't display typed chars&lt;br /&gt;
	cbreak();  // don't buffer terminal lines&lt;br /&gt;
	keypad(stdscr, TRUE);  // for special key (e.g. arrow keys)&lt;br /&gt;
	halfdelay(1); // wait only for 1/10 s in getch()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void place_paddles() {&lt;br /&gt;
	pos_p1_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;&lt;br /&gt;
	pos_p2_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void place_ball(int dir_x) {&lt;br /&gt;
	pos_ball_x = WIDTH / 2;&lt;br /&gt;
	pos_ball_y = HEIGHT / 2;&lt;br /&gt;
	dir_ball_x = dir_x;&lt;br /&gt;
	dir_ball_y = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void print_field() {&lt;br /&gt;
	clear();&lt;br /&gt;
	int x,y;&lt;br /&gt;
	&lt;br /&gt;
	// print score&lt;br /&gt;
	printw(&amp;quot;         %i                     %i\n&amp;quot;, score_p1, score_p2);&lt;br /&gt;
&lt;br /&gt;
	// print upper frame&lt;br /&gt;
	printw(&amp;quot;+&amp;quot;);&lt;br /&gt;
	for(x=0; x&amp;lt;WIDTH; x++) {&lt;br /&gt;
		printw(&amp;quot;-&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	printw(&amp;quot;+\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	for (y=0; y&amp;lt;HEIGHT; y++) {&lt;br /&gt;
		// first column (x==0) is for player1's paddle&lt;br /&gt;
		if (y &amp;gt;= pos_p1_y &amp;amp;&amp;amp; y &amp;lt; pos_p1_y+PADDLE_HEIGHT) {&lt;br /&gt;
			printw(&amp;quot;|#&amp;quot;);&lt;br /&gt;
		} else if (pos_ball_x == 0 &amp;amp;&amp;amp; pos_ball_y == y) {&lt;br /&gt;
			printw(&amp;quot;|*&amp;quot;);&lt;br /&gt;
		} else {&lt;br /&gt;
			printw(&amp;quot;| &amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// middle columns (0 &amp;lt; x &amp;lt; WIDTH-1) anywhere the ball can be&lt;br /&gt;
		for (x=1; x&amp;lt;WIDTH-1; x++) {&lt;br /&gt;
			if (y == pos_ball_y &amp;amp;&amp;amp; x == pos_ball_x) {&lt;br /&gt;
				printw(&amp;quot;*&amp;quot;);&lt;br /&gt;
			} else {&lt;br /&gt;
				printw(&amp;quot; &amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// last column (x==WIDTH-1) is for player2's paddle&lt;br /&gt;
		if (y &amp;gt;= pos_p2_y &amp;amp;&amp;amp; y &amp;lt; pos_p2_y+PADDLE_HEIGHT) {&lt;br /&gt;
			printw(&amp;quot;#|\n&amp;quot;);&lt;br /&gt;
		} else if (pos_ball_x == WIDTH-1 &amp;amp;&amp;amp; pos_ball_y == y) {&lt;br /&gt;
			printw(&amp;quot;*|\n&amp;quot;);&lt;br /&gt;
		} else {&lt;br /&gt;
			printw(&amp;quot; |\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// print lower frame&lt;br /&gt;
	printw(&amp;quot;+&amp;quot;);&lt;br /&gt;
	for(x=0; x&amp;lt;WIDTH; x++) {&lt;br /&gt;
		printw(&amp;quot;-&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	printw(&amp;quot;+\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	refresh();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void key_processing() {&lt;br /&gt;
	int ch = getch();&lt;br /&gt;
	if (ch == KEY_UP) {&lt;br /&gt;
		if (pos_p1_y &amp;gt; 0) {&lt;br /&gt;
			pos_p1_y--;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == KEY_DOWN) {&lt;br /&gt;
		if (pos_p1_y &amp;lt; HEIGHT-PADDLE_HEIGHT) {&lt;br /&gt;
			pos_p1_y++;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == 'w') {&lt;br /&gt;
		if (pos_p2_y &amp;gt; 0) {&lt;br /&gt;
			pos_p2_y--;&lt;br /&gt;
		}&lt;br /&gt;
	} else if (ch == 's') {&lt;br /&gt;
		if (pos_p2_y &amp;lt; HEIGHT-PADDLE_HEIGHT) {&lt;br /&gt;
			pos_p2_y++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void detect_collision() {&lt;br /&gt;
	// ball collides with upper/lower bounds&lt;br /&gt;
	if (pos_ball_y &amp;lt;= 0 || pos_ball_y &amp;gt;= HEIGHT-1) {&lt;br /&gt;
		dir_ball_y *= -1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// ball collides with player1's paddle&lt;br /&gt;
	if (pos_ball_x == 1 &amp;amp;&amp;amp; pos_ball_y &amp;gt;= pos_p1_y &amp;amp;&amp;amp; pos_ball_y &amp;lt; pos_p1_y + PADDLE_HEIGHT) {&lt;br /&gt;
		dir_ball_x *= -1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// ball collides with player2's paddle&lt;br /&gt;
	if (pos_ball_x == WIDTH-2 &amp;amp;&amp;amp; pos_ball_y &amp;gt;= pos_p2_y &amp;amp;&amp;amp; pos_ball_y &amp;lt; pos_p2_y + PADDLE_HEIGHT) {&lt;br /&gt;
		dir_ball_x *= -1;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void move_ball() {&lt;br /&gt;
	pos_ball_x += dir_ball_x;&lt;br /&gt;
	pos_ball_y += dir_ball_y;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int detect_ball_out() {&lt;br /&gt;
	// ball is out on left side -&amp;gt; point for player2&lt;br /&gt;
	if (pos_ball_x &amp;lt;= 0) {&lt;br /&gt;
		return 2;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// ball is out on right side -&amp;gt; point for player1	&lt;br /&gt;
	if (pos_ball_x &amp;gt;= WIDTH-1) {&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int play_round() {&lt;br /&gt;
	int ball_out;&lt;br /&gt;
	while( !(ball_out = detect_ball_out()) ) {&lt;br /&gt;
		key_processing();&lt;br /&gt;
		detect_collision();&lt;br /&gt;
		move_ball();&lt;br /&gt;
		print_field();&lt;br /&gt;
	}&lt;br /&gt;
	return ball_out;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
	init();&lt;br /&gt;
	place_paddles();&lt;br /&gt;
	place_ball(1);&lt;br /&gt;
&lt;br /&gt;
	while(score_p1 &amp;lt; 10 &amp;amp;&amp;amp; score_p2 &amp;lt; 10) {&lt;br /&gt;
		int round_won = play_round();&lt;br /&gt;
		if (round_won == 1) {&lt;br /&gt;
			score_p1++;&lt;br /&gt;
			place_ball(1);&lt;br /&gt;
		} else if (round_won == 2) {&lt;br /&gt;
			score_p2++;&lt;br /&gt;
			place_ball(-1);&lt;br /&gt;
		}&lt;br /&gt;
		sleep(1);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (score_p1 &amp;lt; score_p2) {&lt;br /&gt;
		printw(&amp;quot;Player 1 wins!\n&amp;quot;);&lt;br /&gt;
	} else {&lt;br /&gt;
		printw(&amp;quot;Player 2 wins!\n&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
	refresh();&lt;br /&gt;
	sleep(3);&lt;br /&gt;
&lt;br /&gt;
	endwin();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12367</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12367"/>
		<updated>2009-09-19T16:47:21Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* alles in ein rundenbasiertes Spiel stecken */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion ''void detect_collision()'' soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor ''move_ball''. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion ''int detect_ball_out()''. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite ''1'' bzw. für die linke Seite ''2'' zurückgeben. Ansonsten gibt die Funktion ''0'' zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion ''int play_round()'' um. Der Rückgabewert soll der Wert sein, den ''detect_ball_out()'' im Fall des Nichttreffens liefert.&lt;br /&gt;
&lt;br /&gt;
In der ''main''-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser ''play_round()''; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert. Dann wird der Ball mit ''place_ball'' neu platziert, bevor die nächste Runde beginnt. Hier ist es sinnvoll, die x-Richtung zum Spieler zu setzen, der zuletzt den Ball nicht getroffen hat (es muss also die Richtung noch an ''place_ball'' übergeben werden).&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder ''printw()'' und ''refresh()'' verwenden).&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12366</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12366"/>
		<updated>2009-09-19T16:41:51Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* alles in ein rundenbasiertes Spiel stecken */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion ''void detect_collision()'' soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor ''move_ball''. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion ''int detect_ball_out()''. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite ''1'' bzw. für die linke Seite ''2'' zurückgeben. Ansonsten gibt die Funktion ''0'' zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
Wir lagern nun die bisherige Testschleife in die neue Funktion ''int play_round()'' um. Der Rückgabewert soll der Wert sein, den ''detect_ball_out()'' im Fall des Nichttreffens liefert.&lt;br /&gt;
&lt;br /&gt;
In der ''main''-Funktion erstellen wir nun eine Schleife mit der Bedingung, dass beide Spieler noch weniger als 10 Punkte haben. In den Schleifenkörper kommt unser ''play_round()''; danach wird abhängig von dessen Ergebnis der Punktestand von Spieler 1 bzw. Spieler 2 inkrementiert.&lt;br /&gt;
&lt;br /&gt;
Wenn das Spiel zu Ende ist, soll noch ausgegeben werden, welcher Spieler gewonnen hat (wieder ''printw()'' und ''refresh()'' verwenden).&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12365</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12365"/>
		<updated>2009-09-19T16:32:30Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Erkennen, wenn der Ball nicht vom Schläger getroffen wurde */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion ''void detect_collision()'' soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor ''move_ball''. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
Dazu schreiben wir jetzt die Funktion ''int detect_ball_out()''. Der Rückgabewert soll angeben, für welchen Spieler es im weiteren Programmablauf den Punkt geben soll. Die Funktion muss prüfen, ob der Ball in der x-Position auf der Höhe eines Schlägers ist und für die rechte Seite ''1'' bzw. für die linke Seite ''2'' zurückgeben. Ansonsten gibt die Funktion ''0'' zurück.&lt;br /&gt;
&lt;br /&gt;
Getestet werden kann die Funktion jetzt, indem sie als negierte Bedingung für die bisherige Endlosschleife genutzt wird.&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12364</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12364"/>
		<updated>2009-09-19T16:25:39Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Kollisionen des Balls erkennen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
Die jetzt zu schreibende Funktion ''void detect_collision()'' soll Kollisionen mit der oberen/unteren Kante und den Schlägern erkennen und den Ball entsprechend reflektieren.&lt;br /&gt;
&lt;br /&gt;
Das lässt sich realisieren, indem man die y-Position mit der oberen und unteren Kantenposition vergleicht und bei Kollision die y-Richtung umkehrt. Bei den Schlägern geht das ähnlich mit der x-Position; hier muss aber noch geprüft werden, ob die y-Koordinate des Schlägers mit der y-Koordinate des Balls zusammenpasst (Schlägerhöhe beachten).&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion jetzt wieder in der Endlosschleife aufgerufen werden, und zwar praktischerweise vor ''move_ball''. Jetzt fliegt der Ball nur noch aus dem Spielfeld, wenn ihn kein Schläger getroffen hat.&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12362</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12362"/>
		<updated>2009-09-19T16:16:44Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
Schreibe jetzt die Funktion ''void move_ball()'', die die Positionsvariablen des Ball entsprechend der Werte der Richtungsvaraiblen inkrementiert bzw. dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Teste die Funktion, indem du sie in der Test-Endlosschleife aufrufst. Der Ball fliegt jetzt erstmal ziemlich schnell aus dem Spielfeld.&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12360</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12360"/>
		<updated>2009-09-19T16:11:12Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
Als nächstet kommt die Funktion ''void key_processing()'' dran. Darin fragen wir nun folgendermaßen eine Tastedruck ab:&lt;br /&gt;
&amp;lt;pre&amp;gt;int ch = getch();&amp;lt;/pre&amp;gt;&lt;br /&gt;
Durch unser bei der Initialisierung gesetztes Timeout, wird die Funktion spätestens nach 100 Millisekunden verlassen. Wir können das Ergebnis in ''ch'' nun z.B. mit der Konstante ''KEY_UP'' und ''KEY_DOWN'' bzw. den Buchstaben '' 'w' '' und '' 's' '' vergleichen und entsprechend die Positionsvariable der Schläger erhöhen oder veringern. Dabei sollte abgefangen werden, dass der Schläger außerhalb des Spielfelds landet. Wurde keine oder eine ungültige Taste gedrückt, können wir das hier stillschweigend ignorieren.&lt;br /&gt;
&lt;br /&gt;
Zum Testen kann die Funktion zusammen mit ''print_field()'' in eine Endlosschleife gepackt werden.&lt;br /&gt;
&lt;br /&gt;
=== Ball bewegen ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12353</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12353"/>
		<updated>2009-09-19T15:57:29Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
Jetzt soll die Funktion ''void print_field()'' geschrieben werden, die das komplette Spielfeld und den Punktestand anzeigen soll. Schaue dir dazu den obigen Screenshot an und überlege, wie du diesen zeilenweise aus den Positionsvariablen zusammenbauen kannst.&lt;br /&gt;
&lt;br /&gt;
In der Funktion sollte zuerst ''clear()'' von curses aufgerufen werden, was den bisherigen Terminalinhalt löscht. Wichtig ist, dass du ''printw()'' von curses statt ''printf()'' verwendest. Die Art und Weise der Verwendung ist aber identisch. Zum Schluss muss noch ''refresh()'' von curses aufgerufen werden, damit das eben ausgegebene erscheint.&lt;br /&gt;
&lt;br /&gt;
Teste nun dein ''print_field()'', indem du es in ''main'' aufrufst. Sollte das Bild gleich nach Starten des Programms wieder verschwinden, baue am Ende noch ein ''sleep(10)'' ein, damit das Programm noch 10 Sekunden läuft.&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12348</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12348"/>
		<updated>2009-09-19T15:38:51Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann. Ein Beispiel-Screenshot könnte so aussehen:&lt;br /&gt;
&amp;lt;pre&amp;gt;         1                     2&lt;br /&gt;
+----------------------------------------+&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|#                                       |&lt;br /&gt;
|            *                           |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                       #|&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
|                                        |&lt;br /&gt;
+----------------------------------------+&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
Zuerst überlegen wir uns, wie groß unser Spielfeld und die Schläger sein sollen. Diese Werte sollten als Präprozessor-Befehle angegeben werden. Ein kleines, aber feines Feld bekommt man z.B. mit einer Breite von 40, einer Höhe von 15 und einer Schlägerhöhe von 3.&lt;br /&gt;
&lt;br /&gt;
Jetzt führen wir die Variablen ein, die den Spielzustand repräsentieren sollen. Wir brauchen je eine y-Positionen für die beiden Schläger. Dazu kommt x- und y-Position des Balls. Diese Positionsvariablen sind vom Typ ''int''. Damit wir wissen, in welche Richtung sich der Ball gerade bewegt, brauchen wir x- und -y-Richtung. Dafür eignet sich auch ''int''; welche die Werte 1 und -1 annehmen können sollen, je nachdem, ob es nach rechts/links bzw. nach unten/oben gehen soll. Jetzt brauchen wir noch zwei Variablen für den Punktestand, die wir auch gleich mit 0 initialisieren können.&lt;br /&gt;
&lt;br /&gt;
Die Funktion ''void place_paddles()'' soll die Schläger mittig platzieren. Die Funktion ''void place_ball()'' soll den Ball in der Mitte platzieren. Die x- und y-Reichtung können wir erstmal mit 1 belegen. Beide Funktionen sollten jetzt in der ''main'' aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12345</id>
		<title>C-Kurs/Pong</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Pong&amp;diff=12345"/>
		<updated>2009-09-19T15:17:29Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Die Seite wurde neu angelegt: „Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in ein...“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier soll das Spiel Pong Schritt für Schritt implementiert werden. Die Anzeige des Spielfelds soll durch ASCII-Zeichen realisiert werden, sodass das Spiel in einem Terminal laufen kann.&lt;br /&gt;
&lt;br /&gt;
Leider ist es nicht ganz einfach, einzelne Tasten einzulesen, wie sie gebraucht werden, wenn der Benutzer den Schläger bewegen möchte. ''scanf'' arbeitet gepuffert und gibt die Eingabe erst nach Betätigung der Enter-Taste an das Programm. Wir verwenden deswegen die C-Programmbibliothek ''curses'', die uns entsprechende Funktionen zum Abfragen eines Tastendrucks liefert.&lt;br /&gt;
&lt;br /&gt;
== Aufgabe ==&lt;br /&gt;
=== curses initialisieren ===&lt;br /&gt;
Erstmal müssen wir das Headerfile für ''curses'' includen:&lt;br /&gt;
&amp;lt;pre&amp;gt; #include &amp;lt;curses.h&amp;gt; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schreibe jetzt eine Funktion ''void init()'', die für das Initialisieren von curses zuständig wird. Sie enthält folgende Befehle:&lt;br /&gt;
* &amp;lt;pre&amp;gt;initscr();&amp;lt;/pre&amp;gt; aktiviert curses&lt;br /&gt;
* &amp;lt;pre&amp;gt;noecho();&amp;lt;/pre&amp;gt; damit Buchstaben der getippten Tasten nicht im Terminal erscheinen&lt;br /&gt;
* &amp;lt;pre&amp;gt;cbreak();&amp;lt;/pre&amp;gt; deaktiviert das Puffern der Terminalzeile&lt;br /&gt;
* &amp;lt;pre&amp;gt;keypad(stdscr, TRUE);&amp;lt;/pre&amp;gt; aktiviert spezielle Tasten, wie die Pfeiltasten&lt;br /&gt;
* &amp;lt;pre&amp;gt;halfdelay(1);&amp;lt;/pre&amp;gt; damit die Funktion, die später auf einen Tastendruck wartet, nach einer Zehntel Sekunde beendet wird&lt;br /&gt;
&lt;br /&gt;
Jetzt folgt die ''main''-Funktion. Sie enthält als ersten Aufruf unsere ''init''-Funktion. Unser Programm sollte beim Beenden curses vernünftig deaktivieren, weswegen als letzter Aufruf in der ''main''-Funktion folgender sein sollte:&lt;br /&gt;
&amp;lt;pre&amp;gt; endwin(); &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Quelltextatei ''pong.c'' heißt, kann sie ab jetzt mit folgendem Befehl kompiliert werden:&lt;br /&gt;
&amp;lt;pre&amp;gt; gcc -lcurses pong.c &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variablen für den Zustand des Spiels ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ausgeben des Spielfelds ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Verarbeiten der Tastendrücke ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kollisionen des Balls erkennen ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Erkennen, wenn der Ball nicht vom Schläger getroffen wurde ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== alles in ein rundenbasiertes Spiel stecken ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12343</id>
		<title>C-Kurs/Studentendatenbank</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12343"/>
		<updated>2009-09-19T14:32:23Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Teil c */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll eine kleine Studentendatenbank erstellt werden.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
=== Teil a ===&lt;br /&gt;
Schreibe eine Struktur ''student'', die eine Matrikelnummer, einen Vornamen und einen Nachnamen mit jeweils passenden Datentypen enthält.&lt;br /&gt;
&lt;br /&gt;
=== Teil b ===&lt;br /&gt;
Deklariere einen Pointer auf einen solchen Student und alloziere ihn passend. Initialisiere seine Matrikelnummenr, seinen Vornamen und Nachnamen mit sinnvollen Werten.&lt;br /&gt;
Schreibe nun eine Funktion ''print_student'', die einen Pointer auf einen Studenten übergeben bekommt und seine Details in einer Zeile ausgeben soll. Teste diese Funktion jetzt mit dem zuvor angelegten Student.&lt;br /&gt;
&lt;br /&gt;
=== Teil c ===&lt;br /&gt;
Lege jetzt ein Array von Pointern auf Studenten der Größe 10 an. Initialisiere zunächst alle Elemente mit ''NULL'', damit sich darin unvorhersehbaren Studenten befinden. Weise nun dem ersten Element den aus Teil b angelegten Studenten zu.&lt;br /&gt;
Schreibe nun einen Funktion ''print_studenten_db'', die ein Pointer auf ein Array aus Studenten-Pointern übergeben bekommt, und alle Studenten ausgeben soll. Prüfe dabei, ob das jeweilige Element nicht ''NULL'' ist und benutzte dann die vorher geschriebene Funktion ''print_student''. Wende nun die Funktion auf die Studentendatenbank an.&lt;br /&gt;
&lt;br /&gt;
=== Teil d ===&lt;br /&gt;
Lege nun mindestens zwei weitere Studenten in der Datenbank an und lösche den ersten (dabei nicht vergessen, den Speicher wieder freizugeben). Gebe erneut die Studentendatenbank aus und überprüfe das Ergebnis.&lt;br /&gt;
&lt;br /&gt;
=== Teil e ===&lt;br /&gt;
Am Ende wollen wir wieder aufräumen. Schreibe dazu eine Funktion ''clear_db'', die die Studentendatenbank (wieder ein Pointer auf das Studenten-Pointer-Array) übergeben bekommt, und darin alle Einträge, die nicht ''NULL'' sind, löscht (also deren Speicher freigibt).&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12342</id>
		<title>C-Kurs/Übungsaufgaben</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/%C3%9Cbungsaufgaben&amp;diff=12342"/>
		<updated>2009-09-19T13:21:29Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: /* Die Aufgaben */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wir haben jeder Aufgabe eine Einschätzung ihrer Schwierigkeit auf einer Skala von 1 bis 10 vorangestellt. Bei dieser Einschätzung sind wir von einem Gehirn ausgegangen, für welches das jeweilige Themengebiet völlig neu ist, das jedoch schon ein ganz gutes Verständnis dafür hat wie eine Programmiersprache denn so funktioniert. &lt;br /&gt;
Entsprechend kann eine schwer bewertete Aufgabe aus einem frühen Themengebiet für manch einen sehr einfach oder eine leicht bewertete aus einem späten Themengebiet für einen anderen sehr schwer sein. Es ist nur ein Wert, der euch helfen soll eure nächste Aufgabe zu wählen. &lt;br /&gt;
&lt;br /&gt;
Falls ihr Anmerkungen zu den Aufgaben habt, könnt ihr die Diskussionsseiten der jeweiligen Aufgaben nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeitsgrade ==&lt;br /&gt;
&lt;br /&gt;
#  Reines Tutorial. Man muss nicht viel selbst denken&lt;br /&gt;
#  ...&lt;br /&gt;
#  Leichte Übungsaufgabe. Studies, die noch eher unsicher sind werden hier gut begleitet.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Typische Aufgabe. Man muss den Kopf benutzen, bekommt an schwierigen Stellen aber Hilfestellungen.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Herausfordernd, eher etwas für Studies die etwas fitter sind.&lt;br /&gt;
#  ...&lt;br /&gt;
#  Auch erfahrene Programmierer werden hier ein bis zwei Übungen beschäftigt sein&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
#  Tja, die Idee war da. Wir finden sie auch gut, aber es könnte wirklich anstrengend werden.&lt;br /&gt;
&lt;br /&gt;
== Die Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;2&amp;quot;&lt;br /&gt;
 |- bgcolor=&amp;quot;#D8D8D8&amp;quot;&lt;br /&gt;
 !Aufgabe&lt;br /&gt;
 !Schwierigkeit&lt;br /&gt;
 !Vorwissen&lt;br /&gt;
 !Lerneffekte&lt;br /&gt;
 !Bearbeiter&lt;br /&gt;
 !Korrektur gelesen&lt;br /&gt;
 !Musterlösung&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Von der Konsole zum HelloWorld | Von der Konsole zum HelloWorld]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1. VL&lt;br /&gt;
 | Konsole benutzen, Hello World&lt;br /&gt;
 | Sebastian D.&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/EingabeAusgabe | Ein- und Ausgabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |1&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Ausgabe derselben&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner | Taschenrechner]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Eingabe+Ausgabe&amp;lt;br&amp;gt;Mathematische Operatoren&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | [[Benutzer:Tkroenert|TKroenert]]&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Wochentag | Wochentagsrechnung]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Mathematikverständniss&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | nion (Musterlösung noch nicht vorhanden)&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Taschenrechner2.0 | Taschenrechner ''2.0'']]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |8&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |2. VL&lt;br /&gt;
 | Knobeln&amp;lt;br&amp;gt;Komplexes Aufgaben lösen&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 |&lt;br /&gt;
 | &lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Call by reference | Call by reference]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Einfache Anwendung von &amp;amp;/*&lt;br /&gt;
 | sping&lt;br /&gt;
 | nion&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Text processing | Text processing]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4, 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Strings&amp;lt;br&amp;gt;Pointer-Arithmetik&amp;lt;br&amp;gt;Pointer auf Pointer&amp;lt;br&amp;gt;Refactoring&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Matrizenmultiplikation | Matrizenmultiplikation]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |3. VL&lt;br /&gt;
 | Mehrdimensionale Arrays&amp;lt;br&amp;gt;const correctness&lt;br /&gt;
 | sping&lt;br /&gt;
 | [[Benutzer:Mario|Mario]]&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Arrayuebergabe | Arrayuebergabe]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4/5&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | Einlesen von Benutzereingaben&amp;lt;br&amp;gt;Pointer und Pointerarithmetik&lt;br /&gt;
 | nion&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#F5F5F5&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Studentendatenbank | Studentendatenbank]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; |4&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 4. VL&lt;br /&gt;
 | struct, Pointer, Arrays&lt;br /&gt;
 | AlexanderK&lt;br /&gt;
 |&lt;br /&gt;
 | vorhanden&lt;br /&gt;
 |- bgcolor=&amp;quot;#E8E8E8&amp;quot;&lt;br /&gt;
 | [[Ckurs2009/Cat | Cat]]&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | 6&lt;br /&gt;
 | align=&amp;quot;center&amp;quot; | ....&lt;br /&gt;
 | Arbeiten mit Dateien&amp;lt;br&amp;gt;Kommandozeilenparameter&lt;br /&gt;
 | nion&lt;br /&gt;
 | sping&lt;br /&gt;
 | vorhanden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Kleine und große Probleme ==&lt;br /&gt;
&lt;br /&gt;
* Die Tubit-Accounts haben nicht /bin/bash als shell, so dass die &amp;lt;strong&amp;gt;Cursortasten&amp;lt;/strong&amp;gt; nicht funktionieren. Workaround: als erstes Kommando 'bash' eingeben, man sieht dann auch in welchem Verzeichnis man gerade ist.&lt;br /&gt;
&lt;br /&gt;
== Musterlösungen ==&lt;br /&gt;
Die Lösungen zu den Aufgaben werden nach den jeweiligen Übungen hier veröffentlicht. Falls dies nicht geschiet, bitte den zuständigen Tutor fragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [[Ckurs2009/Feedback|Feedback zum Kurs 2009]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:CKurs]]&lt;br /&gt;
[[Kategorie:CKurs Aufgaben]]&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12341</id>
		<title>C-Kurs/Studentendatenbank</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12341"/>
		<updated>2009-09-19T13:15:35Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll eine kleine Studentendatenbank erstellt werden.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
=== Teil a ===&lt;br /&gt;
Schreibe eine Struktur ''student'', die eine Matrikelnummer, einen Vornamen und einen Nachnamen mit jeweils passenden Datentypen enthält.&lt;br /&gt;
&lt;br /&gt;
=== Teil b ===&lt;br /&gt;
Deklariere einen Pointer auf einen solchen Student und alloziere ihn passend. Initialisiere seine Matrikelnummenr, seinen Vornamen und Nachnamen mit sinnvollen Werten.&lt;br /&gt;
Schreibe nun eine Funktion ''print_student'', die einen Pointer auf einen Studenten übergeben bekommt und seine Details in einer Zeile ausgeben soll. Teste diese Funktion jetzt mit dem zuvor angelegten Student.&lt;br /&gt;
&lt;br /&gt;
=== Teil c ===&lt;br /&gt;
Lege jetzt ein Array von Pointern auf Studenten der Größe 10 an. Initialisiere zunächst alle Elemente mit ''NULL'', damit sich darin unvorhersehbaren Studenten befinden. Weise nun dem ersten Element den aus Teil b angelegten Studenten zu.&lt;br /&gt;
Schreibe nun einen Funktion ''print_studenten_db'', die ein Pointer auf ein Array aus Studenten-Pointern übergeben bekommt, und alle Studenten ausgeben soll. Prüfe dabei, ob das jeweilige Element nicht ''NULL'' ist und benutzte dann die vorher geschriebene Funktion 'print_student''. Wende nun die Funktion auf die Studentendatenbank an.&lt;br /&gt;
&lt;br /&gt;
=== Teil d ===&lt;br /&gt;
Lege nun mindestens zwei weitere Studenten in der Datenbank an und lösche den ersten (dabei nicht vergessen, den Speicher wieder freizugeben). Gebe erneut die Studentendatenbank aus und überprüfe das Ergebnis.&lt;br /&gt;
&lt;br /&gt;
=== Teil e ===&lt;br /&gt;
Am Ende wollen wir wieder aufräumen. Schreibe dazu eine Funktion ''clear_db'', die die Studentendatenbank (wieder ein Pointer auf das Studenten-Pointer-Array) übergeben bekommt, und darin alle Einträge, die nicht ''NULL'' sind, löscht (also deren Speicher freigibt).&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank/Musterl%C3%B6sung&amp;diff=12340</id>
		<title>C-Kurs/Studentendatenbank/Musterlösung</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank/Musterl%C3%B6sung&amp;diff=12340"/>
		<updated>2009-09-19T13:14:23Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Die Seite wurde neu angelegt: „=== Musterlösung ===  &amp;lt;pre&amp;gt; #include &amp;lt;stdlib.h&amp;gt; #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;string.h&amp;gt;  #define ANZAHL 10  /* Teil a */ struct student { 	int mat_nr; 	char vorna...“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Musterlösung ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ANZAHL 10&lt;br /&gt;
&lt;br /&gt;
/* Teil a */&lt;br /&gt;
struct student {&lt;br /&gt;
	int mat_nr;&lt;br /&gt;
	char vorname[25];&lt;br /&gt;
	char nachname[25];&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/* Teil b */&lt;br /&gt;
print_student(struct student *studi) {&lt;br /&gt;
	printf(&amp;quot;Matr.Nr.: %i, Vorname: %s, Nachname: %s\n&amp;quot;, studi-&amp;gt;mat_nr, studi-&amp;gt;vorname, studi-&amp;gt;nachname);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Teil c */&lt;br /&gt;
print_studenten_db(struct student **db) {&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;ANZAHL; i++) {&lt;br /&gt;
		if (db[i] != NULL) {&lt;br /&gt;
			print_student(db[i]);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Teil e */&lt;br /&gt;
clear_db(struct student **db) {&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;ANZAHL; i++) {&lt;br /&gt;
		if (db[i] != NULL) {&lt;br /&gt;
			free(db[i]);&lt;br /&gt;
			db[i] = NULL;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
	/* Teil b*/ printf(&amp;quot;Teil b\n&amp;quot;);&lt;br /&gt;
	struct student *ein_student = malloc(sizeof(struct student));&lt;br /&gt;
	ein_student-&amp;gt;mat_nr = 123456;&lt;br /&gt;
	strcpy(ein_student-&amp;gt;vorname, &amp;quot;Max&amp;quot;);&lt;br /&gt;
	strcpy(ein_student-&amp;gt;nachname, &amp;quot;Mustermann&amp;quot;);&lt;br /&gt;
	print_student(ein_student);&lt;br /&gt;
&lt;br /&gt;
	/* Teil c */ printf(&amp;quot;Teil c\n&amp;quot;);&lt;br /&gt;
	struct student *alle_studenten[ANZAHL];&lt;br /&gt;
	int i;&lt;br /&gt;
	for (i=0; i&amp;lt;ANZAHL; i++) {&lt;br /&gt;
		alle_studenten[i] = NULL;&lt;br /&gt;
	}&lt;br /&gt;
	alle_studenten[0] = ein_student;&lt;br /&gt;
	print_studenten_db(alle_studenten);&lt;br /&gt;
&lt;br /&gt;
	/* Teil d */ printf(&amp;quot;Teil d\n&amp;quot;);&lt;br /&gt;
	alle_studenten[1] = malloc(sizeof(struct student));&lt;br /&gt;
	alle_studenten[1]-&amp;gt;mat_nr=653321;&lt;br /&gt;
	strcpy(alle_studenten[1]-&amp;gt;vorname, &amp;quot;Herbert&amp;quot;);&lt;br /&gt;
	strcpy(alle_studenten[1]-&amp;gt;nachname, &amp;quot;Meier&amp;quot;);&lt;br /&gt;
	alle_studenten[2] = malloc(sizeof(struct student));&lt;br /&gt;
	alle_studenten[2]-&amp;gt;mat_nr=765431;&lt;br /&gt;
	strcpy(alle_studenten[2]-&amp;gt;vorname, &amp;quot;Hubertine&amp;quot;);&lt;br /&gt;
	strcpy(alle_studenten[2]-&amp;gt;nachname, &amp;quot;Schulze&amp;quot;);&lt;br /&gt;
	free(alle_studenten[0]);&lt;br /&gt;
	alle_studenten[0] = NULL;&lt;br /&gt;
	print_studenten_db(alle_studenten);&lt;br /&gt;
&lt;br /&gt;
	/* Teil e */&lt;br /&gt;
	clear_db(alle_studenten);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf &amp;quot;bearbeiten&amp;quot; und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Als kleine Starthilfe folgt ein Beispiel, wie so ein Kommentar formatiert sein könnte. Mit &amp;quot;Vorschau zeigen&amp;quot; kannst du dir ansehen, was deine Änderung bewirken würde, ohne wirklich etwas zu ändern.&lt;br /&gt;
Du musst übrigens außerhalb dieses auskommentieren Bereichs schreiben ;)&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12339</id>
		<title>C-Kurs/Studentendatenbank</title>
		<link rel="alternate" type="text/html" href="https://wiki.freitagsrunde.org/index.php?title=C-Kurs/Studentendatenbank&amp;diff=12339"/>
		<updated>2009-09-19T13:10:49Z</updated>

		<summary type="html">&lt;p&gt;Alexander Kührmann: Die Seite wurde neu angelegt: „In dieser Aufgabe soll eine kleine Studentendatenbank erstellt werden.  == Aufgaben ==  === Teil a === Schreibe eine Struktur ''student'', die eine Matrikelnummer...“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Aufgabe soll eine kleine Studentendatenbank erstellt werden.&lt;br /&gt;
&lt;br /&gt;
== Aufgaben ==&lt;br /&gt;
&lt;br /&gt;
=== Teil a ===&lt;br /&gt;
Schreibe eine Struktur ''student'', die eine Matrikelnummer, einen Vornamen und einen Nachnamen mit jeweils passenden Datentypen enthält.&lt;br /&gt;
&lt;br /&gt;
=== Teil b ===&lt;br /&gt;
Deklariere einen Pointer auf einen solchen Student und alloziere ihn passend. Initialisiere seine Matrikelnummenr, seinen Vornamen und Nachnamen mit sinnvollen Werten.&lt;br /&gt;
Schreibe nun eine Funktion ''print_student'', die einen Pointer auf einen Studenten übergeben bekommt und seine Details in einer Zeile ausgeben soll. Teste diese Funktion jetzt mit dem zuvor angelegten Student.&lt;br /&gt;
&lt;br /&gt;
=== Teil c ===&lt;br /&gt;
Lege jetzt ein Array von Pointern auf Studenten der Größe 10 an. Initialisiere zunächst alle Elemente mit ''NULL'', damit sich darin unvorhersehbaren Studenten befinden. Weise nun dem ersten Element den aus Teil b angelegten Studenten zu.&lt;br /&gt;
Schreibe nun einen Funktion ''print_studenten_db'', die ein Pointer auf ein Array aus Studenten-Pointern übergeben bekommt, und alle Studenten ausgeben soll. Prüfe dabei, ob das jeweilige Element nicht ''NULL'' ist und benutzte dann die vorher geschriebene Funktion 'print_student''. Wende nun die Funktion auf die Studentendatenbank an.&lt;br /&gt;
&lt;br /&gt;
=== Teil d ===&lt;br /&gt;
Lege nun mindestens zwei weitere Studenten in der Datenbank an und lösche den ersten (dabei nicht vergessen, den Speicher wieder freizugeben). Gebe erneut die Studentendatenbank aus und überprüfe das Ergebnis.&lt;br /&gt;
&lt;br /&gt;
=== Teil e ===&lt;br /&gt;
Am Ende wollen wir wieder aufräumen. Schreibe dazu eine Funktion ''clear_db'', die die Studentendatenbank (wieder ein Pointer auf das Studenten-Pointer-Array) übergeben bekommt, und darin alle Einträge, die nicht ''NULL'' sind, löscht (also deren Speicher freigibt).&lt;/div&gt;</summary>
		<author><name>Alexander Kührmann</name></author>
		
	</entry>
</feed>