/// <summary>
    /// berechnet den nächsten Schritt
    /// </summary>
    /// <param name="limit">Anzahl der zu berechnenden (kleinen) Arbeitsschritte, negativer Wert = optionale Vorbereitungsschritte)</param>
    /// <returns>gibt an, ob noch weitere Berechnungen anstehen</returns>
    public bool Next(int limit)
    {
      if (limit == 0) return false;
      switch (modus)
      {
        #region # case Modus.unbekannt:
        case Modus.Unbekannt:
        {
          if (limit > 0)
          {
            modus = Modus.SucheInit; // Initialisierung für die Suche direkt starten
          }
          else
          {
            modus = Modus.SteinerInit; // Initialisierung der Vorbereitung starten
          }
          return true;
        }
        #endregion
        #region # case Modus.steinerInit:
        case Modus.SteinerInit:
        {
          if (limit > 0)
          {
            modus = Modus.SucheInit; // Vorbereitung abbrechen und Suche direkt starten
            return true;
          }

          int maxKisten = feldData.Where(c => c == '$' || c == '*').Count();

          kistenAnzahl++;

          if (kistenAnzahl >= maxKisten)
          {
            return false; // Maximale Kistenanzahl erreicht, weitere Berechnungen sind nicht mehr möglich
          }

          modus = Modus.SteinerVarianten; // neue Aufgabe: alle Varianten ermitteln

          KistenSteinerInit();
          steinerPrüfStellungen = new List<Variante>();
          steinerPrüfstellungenPos = 0;

          return true;
        }
        #endregion
        #region # case Modus.steinerVarianten:
        case Modus.SteinerVarianten:
        {
          if (limit > 0)
          {
            modus = Modus.SucheInit; // Vorbereitung abbrechen und Suche direkt starten
            return true;
          }

          limit = -limit;

          while (limit > 0)
          {
            if (steinerPrüfstellungenPos == steinerPrüfStellungen.Count)
            {
              limit--;
              if (!KistenSteinerNext())
              {
                modus = Modus.SteinerLösen;
                steinerBöseStellungen = steinerPrüfStellungen.Where(x => hashStellungen.Get(x.stellungCrc) == 1).ToArray();
                steinerPrüfStellungen = steinerPrüfStellungen.Where(x => hashStellungen.Get(x.stellungCrc) == 2).ToList();
                var old = hashStellungen;
                hashStellungen = new SokowahnHash_Index24Multi();
                foreach (var satz in old.GetAll().Where(x => x.Value == 1))
                {
                  hashStellungen.Add(satz.Key, satz.Value);
                }
                steinerPrüfstellungenPos = 0;
                return true;
              }
            }
            else
            {
              var prüf = steinerPrüfStellungen[steinerPrüfstellungenPos++];
              LadeStellung(prüf.stellung); limit--;
              if (kistenMitZiel == kistenAnzahl)
              {
                if (hashStellungen.Get(prüf.stellungCrc) == 65535) hashStellungen.Add(prüf.stellungCrc, 2); else hashStellungen.Update(prüf.stellungCrc, 2);
              }
              foreach (var neuPrüf in SucheVariantenSteiner())
              {
                steinerPrüfStellungen.Add(neuPrüf);
                hashStellungen.Add(neuPrüf.stellungCrc, 1);
              }
            }
          }

          return true;
        }
        #endregion
        #region # case Modus.steinerLösen:
        case Modus.SteinerLösen:
        {
          if (limit > 0)
          {
            modus = Modus.SucheInit; // Vorbereitung abbrechen und Suche direkt starten
            return true;
          }

          limit = -limit;

          while (limit > 0)
          {
            if (steinerPrüfstellungenPos == steinerPrüfStellungen.Count)
            {
              // var dummy = steinerBöseStellungen.Where(x => bekannteStellungen.ContainsKey(x.stellungCrc)).ToArray();

              foreach (var satz in steinerBöseStellungen.Where(x => hashStellungen.Get(x.stellungCrc) < 65535))
              {
                SteinerBlockerDazu(satz.stellung);
              }

              modus = Modus.SteinerInit;

              return true;
            }

            var prüf = steinerPrüfStellungen[steinerPrüfstellungenPos++];
            LadeStellung(prüf.stellung); limit--;
            suchTiefe = 99999;

            var vorgänger = SucheVariantenVorgänger().ToArray();

            if (vorgänger.Length > 0)
            {
              foreach (var check in vorgänger)
              {
                if (hashStellungen.Get(check.stellungCrc) < 65535)
                {
                  steinerPrüfStellungen.Add(new Variante { stellung = check.stellung, stellungCrc = check.stellungCrc, tiefe = 1 });
                  hashStellungen.Remove(check.stellungCrc);
                }
              }
            }
            else // gute Stellung, da keine Vorgänger möglich sind
            {
              if (hashStellungen.Get(prüf.stellungCrc) < 65535)
              {
                hashStellungen.Remove(prüf.stellungCrc);
              }
            }

          }

          return true;
        }
        #endregion
        #region # case Modus.sucheInit:
        case Modus.SucheInit:
        {
          raumSpielerPos = feldZuRaum[startSpielerPos];

          KistenStandardInit();

          suchListenSatz = kistenAnzahl + 1;

          suchTiefe = 0;
          SuchListeInsert(GetStellung(), suchTiefe);

          hashStellungen = new SokowahnHash_Index24Multi();
          hashStellungen.Add(StellungCrc(GetStellung()), 0);

          modus = Modus.SucheRechne;
          return true;
        }
        #endregion
        #region # case Modus.sucheRechne:
        case Modus.SucheRechne:
        {
          var listeAuswahl = suchListe[suchTiefe];
          limit = (int)Math.Min(limit, listeAuswahl.SatzAnzahl);
          for (int listenPos = 0; listenPos < limit; listenPos++)
          {
            LadeStellung(listeAuswahl.Pop());
            if (kistenMitZiel == kistenAnzahl)
            {
              modus = Modus.SucheGefunden;
              return false;
            }

            if (StellungBekannt(StellungCrc(GetStellung())) < suchTiefe) continue; // zu prüfende Stellung wurde schon früher (mit weniger Tiefe) berechnet

            foreach (var variante in SucheVariantenHashcheck())
            {
              var tmpTiefe = StellungBekannt(variante.stellungCrc);
              if (tmpTiefe >= 0)
              {
                if (tmpTiefe <= variante.tiefe) continue; // Vorschlag ignorieren
                hashStellungen.Update(variante.stellungCrc, variante.tiefe);
                SuchListeInsert(variante.stellung, variante.tiefe);
              }
              else
              {
                hashStellungen.Add(variante.stellungCrc, variante.tiefe);
                SuchListeInsert(variante.stellung, variante.tiefe);
              }
            }
          }
          if (listeAuswahl.SatzAnzahl == 0) suchTiefe++; // keine weiteren Stellungen bei dieser Zugtiefe vorhanden, dann zur nächsten Zugtiefe springen
          return true;
        }
        #endregion
        case Modus.SucheGefunden: return false; // Ergebnis gefunden, keine weiteren Berechnungen notwendig
        default: throw new Exception("? " + modus);
      }

    }