C/C++ Programmierung

Aufgabe 10

Bei dem Spiel "Die Türme von Hanoi" muß ein Stapel - der Größe nach geordneter - Scheiben von einer der drei erlaubten Positionen in eine andere versetzt werden.

Dabei darf

  1. immer nur die oberste Scheibe bewegt werden
  2. nur eine kleinere Scheibe auf eine größere gelegt werden

Hinweis: Es bietet sich an, eine Funktion BewegeBisScheibe zu schreiben, die sich rekursiv selbst aufruft, um die über der aktuellen Scheibe liegende Scheibe zu bewegen (jeder rekursive Aufruf kümmert sich wiederum wieder um die Scheibe darüber). Die aktuelle Scheibe wird dann in dieser Funktion selbst behandelt (umgesetzt).
Das Hauptprogramm würde dann nur noch aus einigen Eingaben und dem Aufruf dieser Funktion mit der Nummer der untersten Scheibe bestehen.

Lösung für die Aufgabe

#include <stdio.h>

int Zug=0;

/*--------------------------------------------------------------------------*/

// Grundwerte für die Variablen "Scheiben" und "NumScheiben" setzen
void TuermeInitialisieren(int *Scheiben, int TopScheiben[3], int NumScheiben)
{
  int i;

  for (i = 0; i < NumScheiben; i++)
  {
    Scheiben[i] = NumScheiben - i;       // 1. Turm mit Scheiben fuellen
    Scheiben[NumScheiben + i] = 0;       // 2. Turm auf 0 setzen
    Scheiben[(NumScheiben * 2) + i] = 0; // 3. Turm auf 0 setzen
  }

  // Anzahl der Scheiben für jeden Turm
  TopScheiben[0] = NumScheiben;
  TopScheiben[1] = 0;
  TopScheiben[2] = 0;
}

/*--------------------------------------------------------------------------*/

void EineScheibeVerschieben(int *Scheiben, int TopScheiben[3], int NumScheiben, int VonTurm, int NachTurm)
{
  int AktuelleScheibe = Scheiben[(NumScheiben * VonTurm) + TopScheiben[VonTurm] - 1];

  Zug++;
  printf("Zug: %d Scheibe: %d Von: %d Nach:%d\n", Zug, AktuelleScheibe, VonTurm + 1, NachTurm + 1);

  TopScheiben[VonTurm]--;
  Scheiben[(NumScheiben * VonTurm) + TopScheiben[VonTurm]] = 0;

  Scheiben[(NumScheiben * NachTurm) + TopScheiben[NachTurm]] = AktuelleScheibe;
  TopScheiben[NachTurm]++;
}

/*--------------------------------------------------------------------------*/

// Hier kommt die Funktion mit den rekursiven Aufrufen
void ScheibenVerschieben(int *Scheiben, int TopScheiben[3], int NumScheiben, int VonTurm, int NachTurm, int DummyTurm, int AktuelleScheibe)
{
  if (AktuelleScheibe == 1)
    EineScheibeVerschieben(Scheiben, TopScheiben, NumScheiben, VonTurm, NachTurm); // Scheibe verschieben
  else
  {
    ScheibenVerschieben(Scheiben, TopScheiben, NumScheiben, VonTurm, DummyTurm, NachTurm, AktuelleScheibe - 1); // rekursiver Aufruf mit Aktueller Scheibe - 1
    EineScheibeVerschieben(Scheiben, TopScheiben, NumScheiben, VonTurm, NachTurm); // Scheibe verschieben
    ScheibenVerschieben(Scheiben, TopScheiben, NumScheiben, DummyTurm, NachTurm, VonTurm, AktuelleScheibe - 1); // rekursiver Aufruf mit Aktueller Scheibe - 1
  }
}

/*--------------------------------------------------------------------------*/

int main(void)
{
  int *Scheiben;
  int TopScheiben[3];
  int Anzahl;

  printf("Bitte Anzahl der Scheiben eingeben: ");
  scanf("%d", &Anzahl);

  // testen, ob min. 1 eingegeben wurde
  if(Anzahl<1)
  {
    printf("Es muss mindestens eine Scheibe vorhanden sein!\n");
    return(1); // Programm beenden
  }

  // Speicher reservieren
  Scheiben = (int *)malloc((3 * Anzahl) * sizeof(int));
  if (!Scheiben)
  {
    printf("Es konnte nicht genug Speicher reserviert werden!\n");
    return(2); // Programm beenden
  }

  // Grundwerte setzen
  TuermeInitialisieren(Scheiben, TopScheiben, Anzahl);

  // Scheiben von einem Turm auf einen anderen verschieben
  ScheibenVerschieben(Scheiben, TopScheiben, Anzahl, 0, 1, 2, Anzahl);

  // Speicher wieder freigeben
  free(Scheiben);

  return(0); /* Das Hauptprogramm gibt am Ende 0 zurück, da kein Fehler aufgetreten ist. */
}


Zurück zur Übersicht