//=============================================================================

#include <iostream>
#include <limits>
#include <string>
#include <vector>
using namespace std;

//-----------------------------------------------------------------------------

vector<int> tower1;
vector<int> tower2;
vector<int> tower3;

int countSlices;
int counter;

//-----------------------------------------------------------------------------

void printEmptyLine()
{
   cout << '\n';
}

//-----------------------------------------------------------------------------

[[nodiscard]] bool sliceExistsInThisLevel(const vector<int>& tower, int level)
{
   return level < tower.size();
}

//-----------------------------------------------------------------------------

void printSlice(int slice)
{
   const int spaces = countSlices - slice;
   const string sspaces(spaces, ' ');
   const string sslice(slice, '-');
   cout << sspaces << sslice << '|' << sslice << sspaces;
}

//-----------------------------------------------------------------------------

void printNoSlice()
{
   const string sspaces(countSlices, ' ');
   cout << sspaces << '|' << sspaces;
}

//-----------------------------------------------------------------------------

void printTowerOnLevel(const vector<int>& tower, int level)
{
   if (sliceExistsInThisLevel(tower, level))
   {
      const int slice = tower[level];
      printSlice(slice);
      return;
   }
   printNoSlice();
}

//-----------------------------------------------------------------------------

void printTowerLevel(int level)
{
   cout << ' ';
   printTowerOnLevel(tower1, level);
   cout << ' ';
   printTowerOnLevel(tower2, level);
   cout << ' ';
   printTowerOnLevel(tower3, level);
   cout << '\n';
}

//-----------------------------------------------------------------------------

void printOnlyTowers()
{
   for (int level = countSlices -1; level >=  0; --level)
   {
      printTowerLevel(level);
   }
}

//-----------------------------------------------------------------------------

void printBasePlate()
{
   const string base(6 * countSlices + 7, '=');
   cout << base << '\n';
}

//-----------------------------------------------------------------------------

void printTower()
{
   printEmptyLine();
   cout << counter << ".\n";
   printOnlyTowers();
   printBasePlate();
}

//-----------------------------------------------------------------------------

void initTower1()
{
   for (int i = countSlices; i > 0; --i)
   {
      tower1.push_back(i);
   }
}

//-----------------------------------------------------------------------------

void moveSlice(vector<int>& src, vector<int>& dest)
{
   const int slice = src.back();
   src.pop_back();
   dest.push_back(slice);

   ++counter;
   printTower();
}

//-----------------------------------------------------------------------------

void moveTower(vector<int>& src, vector<int>& dest, vector<int>& util, int count)
{
   if (count == 1)
   {
      moveSlice(src, dest);
      return;
   }
   moveTower(src, util, dest, count - 1);
   moveSlice(src, dest);
   moveTower(util, dest, src, count - 1);
}

//-----------------------------------------------------------------------------

void simulateHanoi()
{
   counter = 1;
   moveTower(tower1, tower3, tower2, countSlices);
}

//-----------------------------------------------------------------------------

void askUserForCountSlices()
{
   for (;;)
   {
      cout << "Lieber Nutzer, mit wie vielen Scheiben willst du spielen: ";
      cin >> countSlices;
      if (cin && countSlices > 0 && countSlices < 11) break;
      cout << "Bitte Wert von 1..10 eingeben\n";
      cin.clear();
      cin.ignore(numeric_limits<streamsize>::max(), '\n');
   }
}

//-----------------------------------------------------------------------------

int main()
{
   cout << "Tuerme von Hanoi 1\n\n";

   askUserForCountSlices();
   initTower1();
   printTower();
   simulateHanoi();
}
