Exemplo n.º 1
0
    /// <summary>
    /// generiert die allgemeinen SokoTools
    /// </summary>
    /// <param name="projectName">Name/Namespace des Projektes</param>
    /// <returns>fertig zusammengestellte Cs-Datei</returns>
    public static CsFile GenSokoTools(string projectName)
    {
      var csSokoTools = new CsFile();

      #region # // --- using *.* ---
      csSokoTools.Write();
      csSokoTools.Write();
      csSokoTools.Write("#region # using *.*");
      csSokoTools.Write();
      csSokoTools.Write("using System.Text;");
      csSokoTools.Write("using System.Linq;");
      csSokoTools.Write("using System.Collections.Generic;");
      csSokoTools.Write("using System.Runtime.CompilerServices;");
      csSokoTools.Write();
      csSokoTools.Write("#endregion");
      csSokoTools.Write();
      csSokoTools.Write();
      #endregion

      csSokoTools.Write("namespace " + projectName, ns =>
      {
        ns.Write("static class SokoTools", cl =>
        {
          #region # // --- IEnumerable<int[]> FieldBoxesVariants(int fieldCount, int boxesCount) ---
          cl.Write("public static IEnumerable<int[]> FieldBoxesVariants(int fieldCount, int boxesCount)", m =>
          {
            m.Write("int dif = fieldCount - boxesCount;");
            m.Write("int end = boxesCount - 1;");
            m.Write();
            m.Write("var boxesVariant = new int[boxesCount];");
            m.Write();
            m.Write("for (int box = 0; ; )", f =>
            {
              f.Write("while (box < end) boxesVariant[box + 1] = boxesVariant[box++] + 1;");
              f.Write("yield return boxesVariant;");
              f.Write("while (boxesVariant[box]++ == box + dif) if (--box < 0) yield break;");
            });
          });
          cl.Write();
          #endregion

          #region # // --- Crc64-Tools ---
          cl.Write("public const ulong CrcStart = 0xcbf29ce484222325u;");
          cl.Write("const ulong CrcMul = 0x100000001b3;");
          cl.Write();
          cl.Write("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
          cl.Write("public static ulong CrcCompute(ulong crc64, int value)", crcf =>
          {
            cl.Write("return (crc64 ^ (uint)value) * CrcMul;");
          });
          cl.Write();
          cl.Write("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
          cl.Write("public static ulong CrcCompute(ulong crc64, ushort[] buffer, int ofs, int len)", crcf =>
          {
            crcf.Write("crc64 ^= buffer[ofs];");
            crcf.Write("for (int i = 1; i < len; i++) crc64 = crc64 * CrcMul ^ buffer[i + ofs];");
            crcf.Write("return crc64 * CrcMul;");
          });
          cl.Write();
          #endregion

          #region # // --- TxtView() ---
          cl.Write("public static string TxtView(char[] fieldData, int fieldWidth, ushort[] fieldTargets, int playerPos)", tx =>
          {
            tx.Write("var output = new StringBuilder();");
            tx.Write("for (int i = 0; i < fieldData.Length - 1; i++)", f =>
            {
              f.Write("bool target = fieldTargets.Any(x => x == i);");
              f.Write("bool player = playerPos == i;");
              f.Write("switch (fieldData[i])", sw =>
              {
                sw.Write("case ' ': output.Append(target ? (player ? '+' : '.') : (player ? '@' : ' ')); break;");
                sw.Write("case '#': output.Append('#'); break;");
                sw.Write("default: output.Append(target ? '*' : '$'); break;");
              });
              f.Write("if (i % fieldWidth == fieldWidth - 1) output.AppendLine();");
            });
            tx.Write("output.Append(fieldData[fieldData.Length - 2]).AppendLine().AppendLine();");
            tx.Write("return output.ToString();");
          });
          #endregion
        });
      });

      return csSokoTools;
    }
Exemplo n.º 2
0
    /// <summary>
    /// generiert den Code vom schnelleren Dictionary-Ersatz
    /// </summary>
    /// <param name="projectName">Name/Namespace des Projektes</param>
    /// <returns>fertig zusammengestellte Cs-Datei</returns>
    public static CsFile GenDictionaryFastCrc(string projectName)
    {
      var csDictFast = new CsFile();

      #region # // --- using *.* ---
      csDictFast.Write();
      csDictFast.Write();
      csDictFast.Write("#region # using *.*");
      csDictFast.Write();
      csDictFast.Write("using System;");
      csDictFast.Write("using System.Runtime.CompilerServices;");
      csDictFast.Write();
      csDictFast.Write("// ReSharper disable UnusedMember.Global");
      csDictFast.Write();
      csDictFast.Write("#endregion");
      csDictFast.Write();
      csDictFast.Write();
      #endregion

      csDictFast.Write("namespace " + projectName, ns =>
      {
        ns.Write("sealed class DictionaryFastCrc<TValue> where TValue : struct", cl =>
        {
          cl.Write("private int[] buckets = new int[1];");
          cl.Write("private ulong bucketsMask;");
          cl.Write("private Entry[] entries = new Entry[1];");
          cl.Write("private int count;");
          cl.Write("private int freeList;");
          cl.Write("private int freeCount;");
          cl.Write("internal int Count { get { return count - freeCount; } }");
          cl.Write("public TValue this[ulong key]", th =>
          {
            th.Write("get", g =>
            {
              g.Write("int entry = FindEntry(key);");
              g.Write("if (entry >= 0) return entries[entry].value;");
              g.Write("throw new Exception(\"key not found\");");
            });
            th.Write("set { Insert(key, value, false); }");
          });
          cl.Write();
          cl.Write("internal DictionaryFastCrc(int capacity = 1) { Initialize(Math.Max(1, capacity)); }");
          cl.Write();
          cl.Write("internal void Add(ulong key, TValue value) { Insert(key, value, true); }");
          cl.Write();
          cl.Write("public void Clear()", f =>
          {
            f.Write("if (count <= 0) return;");
            f.Write("Array.Clear(buckets, 0, buckets.Length);");
            f.Write("Array.Clear(entries, 0, count);");
            f.Write("freeList = -1;");
            f.Write("count = 0;");
            f.Write("freeCount = 0;");
          });
          cl.Write();
          cl.Write("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
          cl.Write("internal bool ContainsKey(ulong key)", f =>
          {
            f.Write("for (int index = buckets[key & bucketsMask]; index != 0; index = entries[index].next) if (entries[index].key == key) return true;");
            f.Write("return false;");
          });
          cl.Write();
          cl.Write("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
          cl.Write("private int FindEntry(ulong key)", f =>
          {
            f.Write("for (int index = buckets[key & bucketsMask]; index != 0; index = entries[index].next) if (entries[index].key == key) return index;");
            f.Write("return -1;");
          });
          cl.Write();
          cl.Write("static int GetDouble(int min)", f =>
          {
            f.Write("int dub = 1;");
            f.Write("while (dub < min) dub *= 2;");
            f.Write("return dub;");
          });
          cl.Write();
          cl.Write("private void Initialize(int capacity)", f =>
          {
            f.Write("int prime = GetDouble(capacity);");
            f.Write("buckets = new int[prime];");
            f.Write("bucketsMask = (ulong)(buckets.Length - 1);");
            f.Write("entries = new Entry[prime];");
            f.Write("freeList = -1;");
          });
          cl.Write();
          cl.Write("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
          cl.Write("private void Insert(ulong key, TValue value, bool add)", f =>
          {
            f.Write("var index1 = key & bucketsMask;");
            f.Write("int num2 = 0;");
            f.Write("for (int index2 = buckets[index1]; index2 != 0; index2 = entries[index2].next)", fr =>
            {
              fr.Write("if (entries[index2].key == key)", i =>
              {
                i.Write("if (add) throw new ArgumentException();");
                i.Write("entries[index2].value = value;");
                i.Write("return;");
              });
              fr.Write("++num2;");
            });
            f.Write("int index3;");
            f.Write("if (freeCount > 0)", i =>
            {
              i.Write("index3 = freeList;");
              i.Write("freeList = entries[index3].next;");
              i.Write("--freeCount;");
            });
            f.Write("else", e =>
            {
              e.Write("if (count == entries.Length)", i =>
              {
                i.Write("Resize(GetDouble(count + 1));");
                i.Write("index1 = key & bucketsMask;");
              });
              e.Write("index3 = count;");
              e.Write("++count;");
            });
            f.Write("entries[index3].next = buckets[index1];");
            f.Write("entries[index3].key = key;");
            f.Write("entries[index3].value = value;");
            f.Write("buckets[index1] = index3;");
            f.Write("if (num2 <= 100) return;");
            f.Write("Resize(entries.Length);");
          });
          cl.Write();
          cl.Write("private static unsafe void ResizeConvert(int* numArray, Entry[] entryArray, int limit)", f =>
          {
            f.Write("ulong mask = (ulong)entryArray.Length - 1;");
            f.Write("if (limit > entryArray.Length) throw new IndexOutOfRangeException();");
            f.Write("for (int i = 0; i < limit; i++)", fr =>
            {
              fr.Write("var index2 = entryArray[i].key & mask;");
              fr.Write("entryArray[i].next = numArray[index2];");
              fr.Write("numArray[index2] = i;");
            });
          });
          cl.Write();
          cl.Write("private unsafe void Resize(int newSize)", f =>
          {
            f.Write("var numArray = new int[newSize];");
            f.Write("var entryArray = new Entry[newSize];");
            f.Write("Array.Copy(entries, 0, entryArray, 0, count);");
            f.Write("fixed (int* numArrayP = numArray)", fr =>
            {
              fr.Write("ResizeConvert(numArrayP, entryArray, count);");
            });
            f.Write("buckets = numArray;");
            f.Write("bucketsMask = (ulong)(buckets.Length - 1);");
            f.Write("entries = entryArray;");
          });
          cl.Write();
          cl.Write("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
          cl.Write("public bool TryGetValue(ulong key, out TValue value)", f =>
          {
            f.Write("int entry = FindEntry(key);");
            f.Write("if (entry >= 0)", i =>
            {
              i.Write("value = entries[entry].value;");
              i.Write("return true;");
            });
            f.Write("value = default(TValue);");
            f.Write("return false;");
          });
          cl.Write();
          cl.Write("private struct Entry", f =>
          {
            f.Write("public ulong key;");
            f.Write("public int next;");
            f.Write("public TValue value;");
          });
        });
      });

      return csDictFast;
    }