/// <summary>
    /// berechnet die Anzahl der Schritte um eine einzelne Kiste zum Ziel zu bewegen
    /// </summary>
    /// <param name="raum">Raum mit der einzelnen Kiste</param>
    /// <returns>Mindestzahl der Schritte zum Ziel (oder 60000 = wenn kein Ziel möglich)</returns>
    int RechneMinZügeKiste(SokowahnRaum raum)
    {
      var varianten = raum.GetVariantenBlockerZiele().ToArray();

      int mindest = 60000;

      foreach (var variante in varianten)
      {
        raum.LadeStellung(variante);
        raum.spielerZugTiefe = 0;

        int i = RechneMindestZüge(raum);

        if (i < mindest) mindest = i;
      }

      return mindest;
    }
    /// <summary>
    /// ermittelt alle Zielstellungen, welche mit der entsprechenden Anzahl der Kisten erreichbar sind
    /// </summary>
    /// <returns>Enumerable aller möglichen Zielstellungen</returns>
    IEnumerable<SokowahnStellung> SammlerBerechneZielStellungen()
    {
      SokowahnRaum raum = new SokowahnRaum(basisRaum);
      raum.KistenAnzahl = sammlerKistenAnzahl;

      char[] feldData = basisRaum.FeldData;
      int feldBreite = basisRaum.FeldBreite;

      bool[] spielerRaum = SokowahnStaticTools.SpielfeldRaumScan(feldData, feldBreite);
      int[] raumZuFeld = Enumerable.Range(0, spielerRaum.Length).Where(i => spielerRaum[i]).ToArray();
      int[] feldZuRaum = Enumerable.Range(0, feldData.Length).Select(i => spielerRaum[i] ? raumZuFeld.ToList().IndexOf(i) : -1).ToArray();

      var sammlerKistenRaum = raumZuFeld.Select(i => (feldData[i] == '.' || feldData[i] == '*' || feldData[i] == '+') ? feldZuRaum[i] : -1).Where(i => i >= 0).ToArray();

      foreach (var variante in Tools.BerechneElementeVarianten(basisRaum.KistenAnzahl, sammlerKistenAnzahl, false))
      {
        raum.LadeStellung(variante, sammlerKistenRaum);
        foreach (var stellung in raum.GetVariantenBlockerZiele())
        {
          yield return stellung;
        }
      }
      yield break;
    }