#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
#include <string.h>

const int GROESSE=200;
const int FeldHoehe=13;
const int FeldBreite=46;
char Feld [FeldHoehe] [FeldBreite];


class stacker
{
private:
   int hoehe;         // Wie viel vom Stack ist belegt, 0 falls Stack leer ist
   int stack[GROESSE+1];   // unterstes Element ist [1], oberes variiert
                      // (laut Konvention von C beginnt Array bei 0, wir
                      //beginnen der Uebersicht halber erst bei 1.
public:
   stacker();
   ~stacker();
   int TOP (void);
   void PUSH (int);
   void POP (void);
   int EMPTY (void);       //int weil in C++ kein bool existiert
   void CREATE (void);
   void GIBAUS (void);
};




stacker::stacker (void)                // Konstruktor
{
   hoehe=0;
   cout << "\nHab leeren Stack erschaffen!";
}

stacker::~stacker (void)               // Destruktor
{
   hoehe=0;
   cout << "\nHab Stack komplett zerstoert!\n";
}


int stacker::TOP (void)                // Gib oberstes Element vom Stack aus
{
   if (hoehe>0)
   {
      return stack[hoehe];
   }
   else
   {
      cout << "\nTOP: Stapel ist leer";
      return -1;
   }
}


void stacker::PUSH (int Wert)          // Lege Element auf Stack
{
   if (hoehe < GROESSE)
   {
      cout << "\nLege Element " << Wert << " auf Stack";
      hoehe++;
      stack[hoehe] = Wert;
   }
   else
   {
      cout << "\nFehler bei PUSH: Stack ist voll!";
   }
}

void stacker::POP (void)               // Entferne oberstes Element vom Stack
{
   if (hoehe>0)
   {
      cout << "\nPOP: Loesche oberstes Element " << stack[hoehe];
      hoehe--;                         // Entferne Element
   }
}


int stacker::EMPTY (void)               // Gib 1 zurueck wenn Stapel leer, 0 sonst
{
   if (hoehe==0)
   {
      return 1;      // ist leer
   }
   return 0;         // ist nicht leer
}

void stacker::CREATE (void)             // erschaffe leeren Stapel
{
   stacker(); // rufe Konstruktor auf
}

void stacker::GIBAUS (void)             // Gib gesamten Stapel aus
{
   cout << "\nStack enthaelt:";
   for (int i=1;i<=hoehe;i++)
   {
   cout << " / " << stack[i];
   }
}

void InitialisiereFeld (void)
{
   char zeile[250];
   char Datei[]="fill.txt";

   for (int i=0;i<FeldHoehe;i++)
      for (int j=0;j<FeldBreite;j++)
         Feld[i][j]=0;

   int counter=0;
   ifstream eingabe (Datei, ios::in | ios::nocreate);
                     // oeffne Datei zum Auslesen
   while (eingabe.good())  // Bis wir am Zeilenende angekommen sind
   {
   eingabe.getline(zeile,FeldBreite);
   strncpy (Feld[counter],zeile,FeldBreite);
   counter++;
   }
}


void FuelleFeld (int posx, int posy)
{
   cout << "Fuelle Feld...";
   stacker Haufen;
   Haufen.CREATE();
   if (Feld[posy][posx] !='x')   // lege angegebenes Element auf Stack
      {
      Haufen.PUSH (posx);
      Haufen.PUSH (posy);
      }
      
   while (!(Haufen.EMPTY()))   // while Haufen not empty
      {
      posy = Haufen.TOP();
      Haufen.POP();
      posx = Haufen.TOP();
      Haufen.POP();
      Feld [posy] [posx]='x';    // nehme oberstes Element vom Stack
                                 // und fuelle es aus in Feld
      if ((Feld[posy-1][posx]!='x') && (posy-1)>=0)
         {                    // Element drueber
         Haufen.PUSH(posx);
         Haufen.PUSH(posy-1);
         }
      if ((Feld[posy+1][posx]!='x') && (posy+1)<FeldHoehe)
         {                    // Element drunter
         Haufen.PUSH(posx);
         Haufen.PUSH(posy+1);
         }
      if ((Feld[posy][posx-1]!='x') && (posy-1)>=0)
         {                    // Element links
         Haufen.PUSH(posx-1);
         Haufen.PUSH(posy);
         }
      if ((Feld[posy][posx+1]!='x') && (posx+1)<FeldBreite)
         {                    // Element rechts
         Haufen.PUSH(posx+1);
         Haufen.PUSH(posy);
         }
      }  

   cout << "\nFeld nach Fuellung:"; // gib nun das Feld aus
   for (int i=0;i<FeldHoehe;i++) // fuer jede Zeile
      {
      cout <<"\n";
      for (int j=0;j<FeldBreite;j++)   // jede Position innerhalb 
         {                             // einer Zeile
         if (Feld[i][j]=='x') 
            cout << "M";
         else
            cout << "-";
         }
      }


}


void main (void)
{

   cout << "Beginn";
   stacker Haufen;
   Haufen.PUSH (9);
   Haufen.PUSH (6);
   Haufen.PUSH (1);
   cout << "\nOberstes Element: " << Haufen.TOP();
   Haufen.GIBAUS();
   Haufen.POP ();
   Haufen.GIBAUS();
   cout << "\nTaste druecken";
   while (!(cin.get()));   // warte auf naechsten Tastendruck

   InitialisiereFeld();    // Fuelle Feld mit Angaben aus Datei
	cout <<"FuelleFeld (5,10)\n";
   FuelleFeld(5,10);       // Fuelle Struktur auf
   cout << "\nTaste druecken";
   while (!(cin.get()));   // warte auf naechsten Tastendruck

   InitialisiereFeld();    // Fuelle Feld mit Angaben aus Datei
   cout << "FuelleFeld (20,10)\n";
	FuelleFeld(20,10);      // Fuelle Struktur auf
   
   cout << "Beende Programm. Destruktor fuer noch lebendigen";
   cout << " Stack wird implizit aufgerufen.\n";
}

