/// <summary>
    /// Konstruktor
    /// </summary>
    /// <param name="spielFeld">Spielfeld als Textzeilen</param>
    public SokoWahn_5th(string spielFeld)
    {
      SokowahnStaticTools.SpielfeldEinlesen(spielFeld, out feldBreite, out feldHöhe, out feldSpielerStartPos, out feldData, out feldDataLeer);

      raumBasis = new SokowahnRaum(feldData, feldBreite);

      Directory.CreateDirectory(TempOrdner);

      // --- Vorwärtssuche initialisieren ---
      bekannteStellungen = new SokowahnHash_Index24Multi();
      bekannteStellungen.Add(raumBasis.Crc, 0);
      vorwärtsTiefe = 0;
      vorwärtsTiefeAktuell = 0;
      vorwärtsSucher = new SokowahnLinearList2[0];
      vorwärtsSucherPunkte = new Dictionary<int, int>[0];
      VorwärtsAdd(raumBasis.GetStellung(), new SokowahnPunkte());

      // --- Zielstellungen und Rückwärtssuche initialisieren ---
      zielStellungen = new SokowahnHash_Index24Multi();
      rückwärtsTiefe = 0;
      rückwärtsSucher = new SokowahnLinearList2[0];

      foreach (SokowahnStellung stellung in SokowahnStaticTools.SucheZielStellungen(raumBasis))
      {
        zielStellungen.Add(stellung.crc64, 60000);
        RückwärtsAdd(stellung);
      }

      ulong spielFeldCrc = Crc64.Start.Crc64Update(raumBasis.FeldBreite, raumBasis.FeldHöhe, raumBasis.FeldData);

      blocker = new SokowahnBlockerB2(Environment.CurrentDirectory + "\\temp\\blocker2_x" + spielFeldCrc.ToString("x").PadLeft(16, '0') + ".gz", raumBasis);
    }
    /// <summary>
    /// Rekursive Suchmethode einer einzelnen Kiste
    /// </summary>
    /// <param name="raum">Raum mit der einzelnen Kiste und Spielerstellung</param>
    /// <returns>Mindestzahl der Schritte zum Ziel (oder 60000 = wenn kein Ziel möglich)</returns>
    int RechneMindestZüge(SokowahnRaum raum)
    {
      List<List<SokowahnStellung>> list = new List<List<SokowahnStellung>>();
      list.Add(new List<SokowahnStellung>(raum.GetStellung().SelfEnumerable()));
      int listTiefe = 0;

      SokowahnHash_Index0 hash = new SokowahnHash_Index0();

      while (listTiefe < list.Count)
      {
        foreach (var stellung in list[listTiefe])
        {
          raum.LadeStellung(stellung);
          if (raumZiele[stellung.kistenZuRaum[0]]) return listTiefe;

          foreach (var variante in raum.GetVarianten())
          {
            int find = hash.Get(variante.crc64);
            if (find < 65535)
            {
              if (find <= variante.zugTiefe) continue;
              hash.Update(variante.crc64, variante.zugTiefe);
            }
            else
            {
              hash.Add(variante.crc64, variante.zugTiefe);
            }
            while (list.Count <= variante.zugTiefe)
            {
              list.Add(new List<SokowahnStellung>());
            }
            list[variante.zugTiefe].Add(variante);
          }
        }
        listTiefe++;
      }

      return 60000;
    }
Esempio n. 3
0
  /// <summary>
  /// ermittelt alle möglichen Zielstellungen
  /// </summary>
  /// <param name="raumBasis">Raumsystem mit Basis-Stellung</param>
  /// <returns>Enumerable aller möglichen Zielstellungen</returns>
  public static IEnumerable<SokowahnStellung> SucheZielStellungen(SokowahnRaum raumBasis)
  {
   int feldBreite = raumBasis.FeldBreite;
   int feldHöhe = raumBasis.FeldHöhe;
   char[] feldData = raumBasis.FeldDataLeer.Select(c => c == '.' ? '*' : c).ToArray();

   for (int spielerY = 1; spielerY < feldHöhe - 1; spielerY++)
   {
    for (int spielerX = 1; spielerX < feldBreite - 1; spielerX++)
    {
     int pos = spielerX + spielerY * feldBreite;
     if (feldData[pos] == ' ' && (feldData[pos - 1] == '*' || feldData[pos + 1] == '*' || feldData[pos - feldBreite] == '*' || feldData[pos + feldBreite] == '*'))
     {
      feldData[pos] = '@';
      SokowahnRaum tmpRaum = new SokowahnRaum(feldData, feldBreite);
      tmpRaum.SpielerZugTiefe = 60000;

      var findStellungen = tmpRaum.GetVariantenRückwärts().ToArray();

      if (findStellungen.Length > 0)
      {
       yield return tmpRaum.GetStellung();
//       foreach (var findStellung in findStellungen) yield return findStellung;
      }

      feldData[pos] = ' ';
     }
    }
   }

   yield break;
  }