Servus, ich muss als Prüfungsaufgabe die Türme von Hanoi programmieren. Nun habe ich ein Menü erstellt wo ich einstellen kann wie viele Scheiben ich verwenden will. jetzt fehlt mir aber irgendwie der Weg vom Code in die Grafik. Irgendwie kann ich mir vorstellen das ganze mit nem array zu lösen ala: int RingeTurmA [Ringe eingestellt] = Ringe eingestellt. Nur wenn ich das ganze dann ausgebe und durchzähle zeigt er mir beim aufzählen immer noch 13 und beim abzählen -1 an. ebenso will ich halt wenn ein überlauf is von 12 auf 0 zb dass die arrays dann auch wieder 0 gesetzt werden nur wie kann ich dass bei allen auf einmal machen bzw wenn ich ein überlauf von 0 auf 12 habe sollen ja auch die zahlen dann drinn stehen. Hab hier mal meinen Code is aber nur ein testcode. am richtigen arbeite ich weiter wenn ich dass hinbekommen habe. Kann mir da mal jemand bischen unterstützung geben? #include <stdlib.h> #include <conio.h> #include <stdio.h> #include "Utilities.h" #define Max 12 void Ausgabe (struct Konfiguration Ausgabe); int Auswahl (struct Konfiguration* Ringe); struct Konfiguration { int iAnzahlRinge; int iModus; int iProgrammbeenden; int iRingeTurmA[Max]; }; void main (void) { struct Konfiguration sKonfig; sKonfig.iAnzahlRinge = 0; sKonfig.iProgrammbeenden = 0; sKonfig.iRingeTurmA[sKonfig.iAnzahlRinge] = sKonfig.iAnzahlRinge; while (sKonfig.iProgrammbeenden != 'q') { Ausgabe(sKonfig); sKonfig.iProgrammbeenden = Auswahl(&sKonfig.iAnzahlRinge); } } void Ausgabe (struct Konfiguration Ausgabe) { _gotoxy (15,22); //Ausgabe Ringe if ( Ausgabe.iAnzahlRinge < 10) { printf("0%d", Ausgabe.iAnzahlRinge); } else { printf("%d", Ausgabe.iAnzahlRinge); } } int Auswahl(struct Konfiguration* Konfig) //Funktionen { int i = 0; Konfig->iAnzahlRinge; Konfig->iModus; Konfig->iProgrammbeenden = _getch(); if ( Konfig->iProgrammbeenden == '+') //ab hier werden die Ringe aufgezählt { (Konfig->iAnzahlRinge)++; Konfig->iRingeTurmA[Konfig->iAnzahlRinge] = Konfig->iAnzahlRinge; _gotoxy(10,16 - Konfig->iAnzahlRinge); printf("%d", Konfig->iRingeTurmA[Konfig->iAnzahlRinge]); if (Konfig->iAnzahlRinge > Max) { Konfig->iAnzahlRinge = 0; } } if ( Konfig->iProgrammbeenden == '-') //ab hier werden die Ringe abgezählt { (Konfig->iAnzahlRinge)--; Konfig->iRingeTurmA[Konfig->iAnzahlRinge] = Konfig->iAnzahlRinge; _gotoxy(10,16 - Konfig->iAnzahlRinge); printf("%d", Konfig->iRingeTurmA[Konfig->iAnzahlRinge]); if (Konfig->iAnzahlRinge < 0) { Konfig->iAnzahlRinge = Max; } } return Konfig->iProgrammbeenden; }
Matthias Knab schrieb: > Servus, > ich muss als Prüfungsaufgabe die Türme von Hanoi programmieren. Was genau musst du progammieren? Brauchst du eine grafische Repräsentierung damit der Benutzer das Rätsel lösen kann oder brauchst du ein Programm welches dir sagt, welche Scheibe wohin verfrachtet werden muss. Das ist ein Unterschied. Eine rekursive Lösung für Hanoi ist ein 7-Zeiler > struct Konfiguration > { > int iAnzahlRinge; > int iModus; > int iProgrammbeenden; > int iRingeTurmA[Max]; > }; Sieht schon gut aus. > sKonfig.iProgrammbeenden = 0; > sKonfig.iRingeTurmA[sKonfig.iAnzahlRinge] = sKonfig.iAnzahlRinge; Äh nein. Irgendwie hab ich das Gefühl, dir ist noch nicht klar, was du überhaupt in deinem Array speichern willst. Was bedeuten denn die Zahlen im Array? Wie willst du es verwenden?
Matthias Knab schrieb: > if ( Ausgabe.iAnzahlRinge < 10) > { > printf("0%d", Ausgabe.iAnzahlRinge); > } > else > { > printf("%d", Ausgabe.iAnzahlRinge); > } Du solltest Dir mal die Dokumentation von printf genauer ansehen. Das geht auch mit einem einfachen printf("%02d", Ausgabe.iAnzahlRinge);
Karl heinz Buchegger schrieb: > Brauchst du eine grafische Repräsentierung damit der Benutzer das Rätsel > lösen kann oder brauchst du ein Programm welches dir sagt, welche > Scheibe wohin verfrachtet werden muss. das programm muss entweder automatisch durchlaufen oder wenn ich die leertaste drücke schritt für schritt durchlaufen. sprich bei jedem druck der leertaste muss er einen schritt weiter gehn. also eine scheibe verschieben. das ganze soll in etwa so aussehen: # # # ## ## ## ### ### ### #### #### #### ##### ##### ##### ###### ###### ###### Turm A Turm B Turm C am anfang soll man auf Turm a die Ringe aufzählen können, diese Funktion hab ich ja schon. Nur wie gebe ich es eben aus? Karl heinz Buchegger schrieb: > Äh nein. > Irgendwie hab ich das Gefühl, dir ist noch nicht klar, was du überhaupt > in deinem Array speichern willst. > Was bedeuten denn die Zahlen im Array? Wie willst du es verwenden? ich nehme mal an deine aussage bezieht sich hier drauf: sKonfig.iRingeTurmA[sKonfig.iAnzahlRinge] = sKonfig.iAnzahlRinge; hier hab ich mir gedacht dass ich in das array von [1-12] die Ringe eintrage also 1-12 und die dann irgendwie ausgebe. Sprich 1 wäre das kleinste # und 12 wäre das größte #. Rufus Τ. Firefly schrieb: > Das geht auch mit einem einfachen > > printf("%02d", Ausgabe.iAnzahlRinge); danke hab ich nicht gewusst habs bislang immer so gemacht und mirs halt so hergeleitet da hab ichs auch verstanden. aber dein vorschlag ist halt kürzer.
Karl heinz Buchegger schrieb: > Äh nein. > Irgendwie hab ich das Gefühl, dir ist noch nicht klar, was du überhaupt > in deinem Array speichern willst. > Was bedeuten denn die Zahlen im Array? Wie willst du es verwenden? steht aber weiter unten nochmal drinn jeweils beim auf und abzählen. hier abzählen. Matthias Knab schrieb: > if ( Konfig->iProgrammbeenden == '-') //ab hier werden die Ringe > abgezählt > { > (Konfig->iAnzahlRinge)--; > Konfig->iRingeTurmA[Konfig->iAnzahlRinge] = Konfig->iAnzahlRinge; > _gotoxy(10,16 - Konfig->iAnzahlRinge); > printf("%d", Konfig->iRingeTurmA[Konfig->iAnzahlRinge]); > > if (Konfig->iAnzahlRinge < 0) > { > Konfig->iAnzahlRinge = Max; > } > }
Matthias Knab schrieb: > das ganze soll in etwa so aussehen: > > # # # > ## ## ## > ### ### ### > #### #### #### > ##### ##### ##### > ###### ###### ###### > > Turm A Turm B Turm C ok. also brauchst du eine grafische Anzeige. Gut >> Was bedeuten denn die Zahlen im Array? Wie willst du es verwenden? > > ich nehme mal an deine aussage bezieht sich hier drauf: > > sKonfig.iRingeTurmA[sKonfig.iAnzahlRinge] = sKonfig.iAnzahlRinge; > > > hier hab ich mir gedacht dass ich in das array von [1-12] die Ringe > eintrage also 1-12 und die dann irgendwie ausgebe. Sprich 1 wäre das > kleinste # und 12 wäre das größte #. Wenn schon, dann brauchst du 3 Arrays, in denen du speichern kannst welche Rungnummer da gerade abgelegt sind. int TurmA[12]; int TurmB[12]; int TurmC[12]; dazu nach 3 Variablen, die einem sagen wieviele Ringe gerade in jedem Turm sind. Bei 3 Ringen hast du also (die Arrays sind durch ... nur angedeutet) TurmA 3 2 1 0 0 ... AnzRingeA 3 TurmB 0 0 0 0 0 ... AnzRingeB 0 TurmC 0 0 0 0 0 ... AnzRingeC 0 Das bedeutet: Im Turm A sind momentan 3 Ringe, in den Türmen B und C noch keine (AnzRingeX ist jeweils 0). Die 3 Ringe, die im Turm A sind, sind (von unten nach oben): Ring mit der Nummer 3 Ring mit der Nummer 2 Ring mit der Nummer 1 Jetzt kommt der Benutzer und macht seinen ersten Zug. Er verlegt den obersten Ring von A nach C. Und genau das führst du in deinen Arrays aus. Der oberste Ring von A (die Anzahl Ringe kennst du ja, steht in AnzRingeA) wird von A nach C überführt. Danach ist im Turm A 1 Ring weniger und dafür in C 1 Ring mehr. Das Endergebnis der Operation sieht daher so aus TurmA 3 2 0 0 0 ... AnzRingeA 2 TurmB 0 0 0 0 0 ... AnzRingeB 0 TurmC 1 0 0 0 0 ... AnzRingeC 1 Der Benutzer legt den obersten Ring von A nach B um. Da die Anzahl der Ringe in A 2 Stück sind, ist daher der oberste Ring im Turm A an der Stelle TurmA[ AnzRingeA - 1] oder TurmA[1] zu finden. Dort steht 2 drinnen (weil die oberste Scheibe jetzt die mit der Nummer 2 ist). Diese Scheibe kommt auf den Turm B (wo sie dorthin kommt, sagt dir wieder die Anzahl der in diesem Turm aktuell enthaltenen Ringe) und wieder werden die Anzahl der Ringe entsprechend korrigiert: in A 1 weniger, dafür in B 1 mehr. TurmA 3 0 0 0 0 ... AnzRingeA 1 TurmB 2 0 0 0 0 ... AnzRingeB 1 TurmC 1 0 0 0 0 ... AnzRingeC 1 und so gehts weiter. C nach B TurmA 3 0 0 0 0 ... AnzRingeA 1 TurmB 2 1 0 0 0 ... AnzRingeB 2 TurmC 0 0 0 0 0 ... AnzRingeC 0 A nach C TurmA 0 0 0 0 0 ... AnzRingeA 0 TurmB 2 1 0 0 0 ... AnzRingeB 2 TurmC 3 0 0 0 0 ... AnzRingeC 1 B nach A TurmA 1 0 0 0 0 ... AnzRingeA 1 TurmB 2 0 0 0 0 ... AnzRingeB 1 TurmC 3 0 0 0 0 ... AnzRingeC 1 B nach C TurmA 1 0 0 0 0 ... AnzRingeA 1 TurmB 0 0 0 0 0 ... AnzRingeB 0 TurmC 3 2 0 0 0 ... AnzRingeC 2 und A nach C TurmA 0 0 0 0 0 ... AnzRingeA 0 TurmB 0 0 0 0 0 ... AnzRingeB 0 TurmC 3 2 1 0 0 ... AnzRingeC 3 Ehe du dich da jetzt mit einer graphischen Repräsentierung verzettelst, sieh erst mal zu, dass du deine Ausgabe so oder so ähnlich hinkriegst, wie hier in diesem Posting. Einfach die 3 Türme untereinander, daneben welche Ringnummern jeweils im Turm sind und wieviele Ringe in diesem Turm sind. Wenn dann erst mal die Array-Operationen korrekt sind, kannst du dich mit einer ansprechenderen Ausgabe beschäftigen.
> das programm muss entweder automatisch durchlaufen oder wenn ich > die leertaste drücke schritt für schritt durchlaufen. Darf ich fragen, wo du die Lösung her hast wenn das automatisch durchlaufen soll? Irgendwie will mir das nicht in den Schädel, dass du zwar einen rekursiven Hanoi-Algorithmus hinkriegst, aber mit Arrays und eigentlich trivialer Ausgabe auf Kriegsfuss stehst. Das ergibt keinen Sinn. Hanoi zu lösen ist so unedlich schwerer als eine Ausgabe zu programmieren, dass da etwas ganz gewaltig nicht zusammenpasst.
Karl heinz Buchegger schrieb: > Irgendwie will mir das nicht in den Schädel, dass du zwar einen > rekursiven Hanoi-Algorithmus hinkriegst Das Internet ist lang und breit, Hanoi ist da gelegentlich zu finden.
Klaus Wachtler schrieb: > Karl heinz Buchegger schrieb: >> Irgendwie will mir das nicht in den Schädel, dass du zwar einen >> rekursiven Hanoi-Algorithmus hinkriegst > > Das Internet ist lang und breit, Hanoi ist da gelegentlich zu finden. Nun ja. Wenn ich jetzt noch den Thread-Titel mit dazunehme, in dem das Wort "Prüfungsaufgabe" vorkommt, frage ich mich ob ich hier das Richtige tue. Aber: in dubio vielleicht hatte er wirklich nur einen Hänger. Manchmal muss man mit der Nase auf eine erfolgverpsrechende Datenstruktur gestossen werden. Wenn da dann nicht wieder die Nachfrage nach dem "Wie gebe ich das aus?" wäre :-)
> das ganze soll in etwa so aussehen: > > # # # > ## ## ## > ### ### ### > #### #### #### > ##### ##### ##### > ###### ###### ###### > > Turm A Turm B Turm C Falsch. Die Position sagt nichts über den Durchmesser der Scheibe aus. Es kann sehr gut auch so aussehen: # ## ### ###### #### ###### Turm A Turm B Turm C Du brauchst also eine Anzeige auf welchem Stapel in welcher Position welcher Durchmesser liegt. int tower[3][7]; Das sollte doch einfach zu programmieren sein.
Karl heinz Buchegger schrieb: > Wenn schon, dann brauchst du 3 Arrays, in denen du speichern kannst > welche Rungnummer da gerade abgelegt sind. weiß ich, ich wollte es halt zuerst hinbekommen dass er mir den ersten turm wenigstens mal anzeigt wenn ich die ringe einstelle. Karl heinz Buchegger schrieb: > Darf ich fragen, wo du die Lösung her hast wenn das automatisch > durchlaufen soll? hä? ich hab gar nix. Das is ja das Problem. bislang bin ich nur soweit dass ich den modus von hand auf automatik umstellen kann und das programm bei verschiedenen tastendrücken etwas tut. zb beendet, die ringe hochzählt usw. Mir fehlt lediglich der übergang wie ich es mit der eigentlichen funktion die das programm ausüben soll verschachtele.
Matthias Knab schrieb: > Karl heinz Buchegger schrieb: >> Wenn schon, dann brauchst du 3 Arrays, in denen du speichern kannst >> welche Rungnummer da gerade abgelegt sind. > > weiß ich, ich wollte es halt zuerst hinbekommen dass er mir den ersten > turm wenigstens mal anzeigt wenn ich die ringe einstelle. Na, ja. Jetzt weißt du ja, wie du die Arrays am besten benutzt. In jeweiligen Turm-Array steht an der Index-Position 0 die jeweils unterste Scheibe. Und von dort ausgehend ist es ja nicht mehr schwer da eine entsprechend ansprechende Ausgabe zu erzeugen. > hä? ich hab gar nix. Das is ja das Problem. Das sehe ich allerdings mitlerweile genauso. Das du ein Problem hast, mein ich. > bislang bin ich nur soweit > dass ich den modus von hand auf automatik umstellen kann und das > programm bei verschiedenen tastendrücken etwas tut. zb beendet, die > ringe hochzählt usw. Auf deutsch: Du hast noch gar nichts. Zumindest nichts wesentliches. :-) > Mir fehlt lediglich der übergang wie ich es mit der eigentlichen > funktion die das programm ausüben soll verschachtele. Das sehe ich eigentlich nicht so. 'ledglich' ist in diesem Zusammenhang die Untertreibung des Jahres. Denn diese Anbindung ist trivial. Der Hammer kommt erst, wenn du die Züge an sich generieren sollst (und dabei nicht auf Code aus dem Web zurückgreifen willst) Aber ich will dich nicht aufhalten. Mach mal. PS: MaWin hat Recht. Mit einem 2D Array für die Türme wirds Code-technisch einfacher, wenn auch gedanklich für dich mglw. etwas schwieriger.
Karl heinz Buchegger schrieb: > PS: MaWin hat Recht. Mit einem 2D Array für die Türme wirds > Code-technisch einfacher, wenn auch gedanklich für dich mglw. etwas > schwieriger. das heißt? ich soll Turm 1 in [0][0] speichern, turm 2 in [1][0] unt turm 3 in [2][0]?
Was mir eufgefallen ist wir haben irgendwie aneinander vorbei geredet. Und zwar wollte ich in erster linie eigentlich wissen warum er mir wenn ich die aufgezaehlte zahl in ein array speichere und probeweise ausgebe er mir beim aufzaehlen von 1-13 speichert und beim abzaehlen von -1-11. Dass waere eigentlich vorerst mein einziges problem. Kann mir dass jemand kurz sagen?
gehs doch einfach durch Hier ist der Code
1 | if ( Konfig->iProgrammbeenden == '+') //ab hier werden die Ringe |
2 | aufgezählt |
3 | {
|
4 | (Konfig->iAnzahlRinge)++; |
5 | Konfig->iRingeTurmA[Konfig->iAnzahlRinge] = Konfig->iAnzahlRinge; |
6 | _gotoxy(10,16 - Konfig->iAnzahlRinge); |
7 | printf("%d", Konfig->iRingeTurmA[Konfig->iAnzahlRinge]); |
8 | |
9 | if (Konfig->iAnzahlRinge > Max) |
10 | {
|
11 | Konfig->iAnzahlRinge = 0; |
12 | }
|
13 | }
|
Konfig->iAnzahlRinge sei 11 Was passiert? (Konfig->iAnzahlRinge)++; es wird erhöht, also 12 Konfig->iRingeTurmA[Konfig->iAnzahlRinge] = Konfig->iAnzahlRinge; zugewiesen (wozu das auch immer gut sein soll) _gotoxy(10,16 - Konfig->iAnzahlRinge); printf("%d", Konfig->iRingeTurmA[Konfig->iAnzahlRinge]); ausgegeben -> daher Ausgabe von 12 if (Konfig->iAnzahlRinge > Max) Max ist 12, Konfig->iAnzahlRinge (auch 12) ist nicht größer als Max, daher passiert nichts weiter. Gut. Und jetzt erhöhst du nocheinmal Wieder beginnt die Sequenz (Konfig->iAnzahlRinge)++; erhöhen, also 13 Konfig->iRingeTurmA[Konfig->iAnzahlRinge] = Konfig->iAnzahlRinge; zuweisen _gotoxy(10,16 - Konfig->iAnzahlRinge); printf("%d", Konfig->iRingeTurmA[Konfig->iAnzahlRinge]); Ausgeben. Also steht jetzt 13 dort if (Konfig->iAnzahlRinge > Max) diesmal ist Konfig->iAnzahlRinge größer als Max, daher Konfig->iAnzahlRinge = 0; auf 0 setzen. Aber: Die 13 wurden schon ausgegeben, und aufs Array hast du auch schon an der falschen Stelle zugegriffen. Ein Arrayelement Konfig->iRingeTurmA[12] existiert nicht.
Dacht ichs mir doch dass ein gleichheitszeichen rein muss. Habs gestrern bereits mal probiert und dann kam gar nix mehr. Gut vielleicht war noch ein anderer fehler drinn so dass es mir nicht aufgefallen ist. Danke schon mal. Muss nachher wenn vorlesung vorbei ist nochmal schauen.
Matthias schrieb: > Dacht ichs mir doch dass ein gleichheitszeichen rein muss. Keine gute Idee. D.h. Schon. Aber es behebt das Problem noch nicht wirklich.
habs auch beim heimfahren überlegt. muss mir das nochmal durch den kopf gehen lassen.
kurze frage wie bekomme ich es hin dass zb: void Towers (int iy, int ix, struct Konfiguration Ringe) sich selbst wieder aufruft? Hab mir das ganze mal mit der Uhrzeigersinn lösung angeschaut und will dass nun irgendwie so lösen. nur muss ich da halt rekursiv arbeiten. irgendwie.
jop dass weiß ich nur wie füge ich eine array nochmals ein? so wie in meinem fall halt.
1 | void Towers (int iy, int ix, struct Konfiguration Ringe) { |
2 | if (irgendwas) |
3 | Towers(iy+1, ix-1, Ringe); |
4 | }
|
1 | funktion bewege (Zahl i, Stab a, Stab b, Stab c) { |
2 | falls (i > 0) { |
3 | bewege(i-1, a, c, b); |
4 | verschiebe oberste Scheibe von a nach c; |
5 | bewege(i-1, b, a, c); |
6 | } |
7 | } |
Ach ja, liess dir bei Gelegenheit mal irgend einen Coding-Style-Guide durch.
coding style guide hab ich hier wie gesagt dass ist ein testprogramm wo ich alles einfach so reinpacke.
Matthias Knab schrieb: > coding style guide hab ich hier wie gesagt dass ist ein testprogramm wo > ich alles einfach so reinpacke. Sowas gilt nicht. Und sollte auch nicht so gehandhabt werden, so ein coding style hilft auch Fehler zu vermeiden.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.