Türme von Hanoi mit Visualisierung



  • Hallo zusammen,

    also ich hab das Programm jetzt fertig gestellt. Nachdem ich noch mehrer kleine Fehler usw. beseitigt habe und das ganze mit einem Menue erweitert habe bin ich mit meiner Lösung ganz zufrieden.

    Jetzt fang ich an die Dokumentation zu schreiben.

    Hier der Quellcode für diejenigen dies interessiert:

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <conio.h> 
    #include <string.h> 
    #include <Windows.h>
    
    #include "Utilities.h" 
    
    void settower(struct Tower *turmlinks, struct Tower *turmmitte,struct Tower *turmrechts,int wert);
    
    void setrings(struct Tower *turm, int rings);
    
    void setloesung(int loesung[4100][2], int c);
    
    void zeigeturm(struct Tower *turm, int x);//zeigt einen Turm an un verschiebt ihn um x nach rechts 
    void showtowers(struct Tower *turmlinks, struct Tower *turmmitte, struct Tower *turmrechts);//zeigt alle Türme nebeneinander an 
    void verschiebe (int *von, int *nach);//verschiebt eine "Scheibe" von einem Turm auf einen anderen 
    static int* bewege(int anzscheiben, int von, int nach, int ueber, int loesung[4100][2]);//Soll Rekursiv die Schritte berechnen und un loesung speichern 
    void automatik(struct Tower *turmlinks, struct Tower *turmmitte, struct Tower *turmrechts, int loesung[4100][2],int anzscheiben, char modus);//Verschiebt Scheiben automatisch mit eine Sekunde pause, bricht ab wenn taste gedrückt
    void printmenue();
    int manuell(struct Tower *turmlinks, struct Tower *turmmitte, struct Tower *turmrechts, int loesung[4100][2],int anzscheiben, char modus);
    
    void statuszeile(int anzscheiben, char modus, int schrittinfo, int schritt, int loesung[4100][2]);
    
    //struktur turm mit einem int array 
    //kleinste scheibe = 1, größte scheibe=12, keine scheibe=0 
    //von oben nach unten z.B. 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 
    struct Tower 
    { 
        int wertigkeit[15]; 
    }; 
    
    int main () 
    { 
        //erstellen der Türme A B C von links nach rechts 
        struct Tower towerA; 
        struct Tower towerB; 
        struct Tower towerC; 
    
        //hier sollen die Lösungsschritte gespeichert werden 
        int loesung[4100][2]; 
    	int c=0;
        int i; 
        int anzscheiben=12; //anzahl der Scheieb noch fest eingegeben 
    	static int* zaehler;
    	char modus='m';
    
    	printmenue();
    
    	settower(&towerA,&towerB,&towerC,0);
    	setloesung(loesung,0);
    	setrings(&towerA,anzscheiben);
    	showtowers(&towerA, &towerB, &towerC);
    
    	//zaehler=bewege(anzscheiben,1,3,2,loesung); 
    	//*zaehler=0;
    
    	do
    	{
    		if(c=='a')
    		{
    			modus='a';
    		}
    		if(c=='m')
    		{
    			modus='m';
    		}
    
    		if(c==43)
    		{
    			anzscheiben++;
    			if(anzscheiben>=12)anzscheiben=12;
    		}
    		 if(c==45)
    		{
    			anzscheiben--;
    			if(anzscheiben<=1)anzscheiben=1;
    		}
    		settower(&towerA,&towerB,&towerC,0);
    		setloesung(loesung,0);
    		setrings(&towerA,anzscheiben);
    		showtowers(&towerA, &towerB, &towerC);
    
    		zaehler=bewege(anzscheiben,1,3,2,loesung); 
    		*zaehler=0;
    		statuszeile(anzscheiben,modus,0,0,loesung);
    
    		c=getch();
    
    		if(modus=='a'&&c==115)
    		{
    			automatik(&towerA, &towerB, &towerC, loesung, anzscheiben,modus);
    
    		}
    
    		if(modus=='m'&&c==115)
    		{
    			c=manuell(&towerA, &towerB, &towerC, loesung,anzscheiben,modus);
    
    		}
    
    	}while(c!=113); 
    
    	system("cls");
    	_gotoxy(25,15);
    	printf("DAS PROGRAMM WURDE BEENDET!");
        getch(); 
        return 0; 
    } 
    
    void statuszeile(int anzscheiben, char modus, int schrittinfo, int schritt, int loesung[4100][2])
    {
    
    	if(schrittinfo==1)
    	{
    		_gotoxy(0,28);
    		printf("Aktueller Schritt:   Scheibe von %i -->%i",loesung[schritt][0],loesung[schritt][1]);
    	}
    	_gotoxy(0,30);
    	printf("Anzahl Scheiben: %i\t", anzscheiben);
    	if(modus=='a')
    	{
    		printf("Modus: Automatik\t\t");
    	}
    	if(modus=='m')
    	{
    		printf("Modus: Manuell  \t\t");
    	}
    	printf("z fuer zurueck");
    
    }
    
    int manuell(struct Tower *turmlinks, struct Tower *turmmitte, struct Tower *turmrechts, int loesung[4100][2], int anzscheiben, char modus)
    {
    	int c;
    	int i=0;
    	do
    	{
    		if(loesung[i][0]==1 && loesung[i][1]==2)
    		{
    			verschiebe(turmlinks->wertigkeit,turmmitte->wertigkeit);
    		}
    
    		if(loesung[i][0]==1 && loesung[i][1]==3)
    		{
    			verschiebe(turmlinks->wertigkeit,turmrechts->wertigkeit);
    		}
    
    		if(loesung[i][0]==2 && loesung[i][1]==3)
    		{
    			verschiebe(turmmitte->wertigkeit,turmrechts->wertigkeit);
    		}
    
    		if(loesung[i][0]==2 && loesung[i][1]==1)
    		{
    			verschiebe(turmmitte->wertigkeit,turmlinks->wertigkeit);
    		}
    
    		if(loesung[i][0]==3 && loesung[i][1]==1)
    		{
    			verschiebe(turmrechts->wertigkeit,turmlinks->wertigkeit);
    		}
    
    		if(loesung[i][0]==3 && loesung[i][1]==2)
    		{
    			verschiebe(turmrechts->wertigkeit,turmmitte->wertigkeit);
    		}
    		showtowers(turmlinks, turmmitte, turmrechts);
    		i++;
    		statuszeile(anzscheiben,modus,1,i-1,loesung);
    		c=getch();
    
    		if(loesung[i][0]==0 && loesung[i][1]==0)
    		{
    			c=122;	
    		}
    
    	}while(c!=113 && c!=122);
    	if(c==113)return 113;
    
    }
    
    void printmenue()
    {
    	char zeichen[]="################################################";
    	printf("%30.30s%s%31.31s",zeichen,"  Towers of Hanoi  ",zeichen);
    	printf("\n\n");
    	printf("\ts: Spiel starten \t\t q: Spiel beenden\n\n");
    	printf("\t+: Scheibenanzahl erhoehen \t -: Scheibenanzahl verringern\n\n");
    	printf("\ta: Automatik - Modus \t\t m: Manueller - Modus\n\n");
    	printf("%40.40s%40.40s",zeichen,zeichen);
    }
    
    void automatik(struct Tower *turmlinks, struct Tower *turmmitte, struct Tower *turmrechts, int loesung[4100][2],int anzscheiben, char modus)
    {
    	int i=0;
    
    	while((loesung[i][0]!=0)&&(kbhit()==0))
    	{
    		if(loesung[i][0]==1 && loesung[i][1]==2)
    		{
    			verschiebe(turmlinks->wertigkeit,turmmitte->wertigkeit);
    		}
    
    		if(loesung[i][0]==1 && loesung[i][1]==3)
    		{
    			verschiebe(turmlinks->wertigkeit,turmrechts->wertigkeit);
    		}
    
    		if(loesung[i][0]==2 && loesung[i][1]==3)
    		{
    			verschiebe(turmmitte->wertigkeit,turmrechts->wertigkeit);
    		}
    
    		if(loesung[i][0]==2 && loesung[i][1]==1)
    		{
    			verschiebe(turmmitte->wertigkeit,turmlinks->wertigkeit);
    		}
    
    		if(loesung[i][0]==3 && loesung[i][1]==1)
    		{
    			verschiebe(turmrechts->wertigkeit,turmlinks->wertigkeit);
    		}
    
    		if(loesung[i][0]==3 && loesung[i][1]==2)
    		{
    			verschiebe(turmrechts->wertigkeit,turmmitte->wertigkeit);
    		}
    		showtowers(turmlinks, turmmitte, turmrechts);
    		i++;
    		statuszeile(anzscheiben,modus,1,i-1,loesung);
    		Sleep(1000);
    		}
    }
    
    void setloesung(int loesung[4100][2], int c)
    {
    	int i;
    	for(i=0;i<4100;i++) 
        { 
           loesung[i][0]=c;
    	   loesung[i][1]=c;
        } 
    }
    
    void setrings(struct Tower *turm, int rings)
    {
    	int i;
    	for(i=14;i>14-rings;i--) 
        { 
            turm->wertigkeit[i]=i-2; 
        } 
    }
    
    void settower(struct Tower *turmlinks, struct Tower *turmmitte,struct Tower *turmrechts,int wert)
    {
    	int i;
    	for(i=0;i!=15;i++) 
    	{ 
    		turmlinks->wertigkeit[i]=wert; 
    		turmmitte->wertigkeit[i]=wert;
    		turmrechts->wertigkeit[i]=wert;
    	} 
    }
    
    void zeigeturm(struct Tower *turm, int x) 
    { 
        int i; 
        for(i=0;i!=15;i++) 
        { 
            int len = turm->wertigkeit[i]*2+1; 
            if(len <= 25 ) 
            { 
                char fmt[100]; 
                char xxx[] = "################################################################"; 
                _gotoxy(x,12+i); 
                sprintf(fmt, "%%%d.%ds%%%d.%ds\n", (25-len)/2, (25-len)/2,len,len); 
                printf(fmt, "", xxx); 
            } 
        } 
    } 
    
    void showtowers(struct Tower *turmlinks, struct Tower *turmmitte, struct Tower *turmrechts) 
    { 
    	system("cls");
    	printmenue();
        zeigeturm(turmlinks, 0); 
        zeigeturm(turmmitte, 27); 
        zeigeturm(turmrechts, 54); 
    } 
    
    void verschiebe (int *von, int *nach) 
    { 
        //sucht im turm "von" von oben nach unten nach einer Scheibe (Wert größer 0) 
        //scht dann in turm "nach" von unten nach oben nach der ersten Stelle an der keine Scheibe mehr ist (Wert=0) 
        //falls diese Stelle gefunden wurde, werden diese beiden Werte getauscht 
        int i,k; 
        for(i=0;i!=15;i++) 
        { 
            if(von[i]>0) 
            { 
                for(k=14;k!=0;k--) 
                { 
                    if(nach[k]==0) 
                    {    
                        nach[k]=von[i]; 
                        von[i]=0; 
                        k=1; 
                    } 
                }            
                i=14;    
            } 
        } 
    } 
    
    //Soll die Lösungschritte "errechnen" und in loesung speichern 
    static int* bewege(int anzscheiben, int von, int nach, int ueber, int loesung[4100][2]) 
    { 
    	static int count=0;
    
    	if (anzscheiben == 1) 
       { 
    	  loesung[count][0]=von;
    	  loesung[count][1]=nach;
    	  count++;
       } 
       else 
       { 
          bewege(anzscheiben-1, von, ueber, nach,loesung); 
          bewege(       1, von, nach, ueber, loesung); 
          bewege(anzscheiben-1, ueber, nach, von,loesung);
    	}
    	return &count;
    }
    

    Die Funktion gotoxy kann ich euch leider nicht zeigen, da ich die vom Prof bekommen habe. Die Funktion setzt einfach nur den Cursor an eine Stelle der Konsole beschrieben durch die X und Y Koordinate.

    Eventuell könnt ihr diese Stellen ja ersetzen, wenn ihr euch das ganze anschauen wollt.

    Dann nochmals Danke für die Hilfe hier durch das Forum!!

    Frohe Weihnachten und einen Guten Rutsch ins neue Jahr!

    Gruß Sven


Anmelden zum Antworten