diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton.sln b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton.sln
new file mode 100644
index 0000000..78e4f24
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33205.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LangtonWholeInOne", "Langton\LangtonWholeInOne.csproj", "{500A2445-E4BF-48A7-900C-CFA0BB244AA4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LangtonFrontend", "LangtonFrontend\LangtonFrontend.csproj", "{623833F8-B936-4AEA-9BE0-2DB62C298C01}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LangtonBackend", "LangtonBackend\LangtonBackend.csproj", "{AD301928-3F49-4A34-9F1F-8336097DAE65}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {500A2445-E4BF-48A7-900C-CFA0BB244AA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {500A2445-E4BF-48A7-900C-CFA0BB244AA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {500A2445-E4BF-48A7-900C-CFA0BB244AA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {500A2445-E4BF-48A7-900C-CFA0BB244AA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {623833F8-B936-4AEA-9BE0-2DB62C298C01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {623833F8-B936-4AEA-9BE0-2DB62C298C01}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {623833F8-B936-4AEA-9BE0-2DB62C298C01}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {623833F8-B936-4AEA-9BE0-2DB62C298C01}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AD301928-3F49-4A34-9F1F-8336097DAE65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AD301928-3F49-4A34-9F1F-8336097DAE65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AD301928-3F49-4A34-9F1F-8336097DAE65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AD301928-3F49-4A34-9F1F-8336097DAE65}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {9F000889-483E-41AD-A737-6DAE337EAE6D}
+ EndGlobalSection
+EndGlobal
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/App.config b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Direction.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Direction.cs
new file mode 100644
index 0000000..5db9414
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Direction.cs
@@ -0,0 +1,10 @@
+namespace Langton
+{
+ public enum EDirection
+ {
+ LEFT,
+ UP,
+ RIGHT,
+ DOWN,
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Field.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Field.cs
new file mode 100644
index 0000000..3a4a5d5
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Field.cs
@@ -0,0 +1,99 @@
+using System.Threading;
+
+using Console = System.Console;
+using Math = System.Math;
+
+namespace Langton
+{
+ internal class CField
+ {
+ private static readonly int WORLD_SIZE = 11;
+ public static int SLEEP_TIME = 500;
+
+ private bool[,] mi_field;
+ private EDirection mi_dir = EDirection.LEFT;
+ private SVector2 mi_pos;
+
+ public CField()
+ {
+ mi_field = new bool[WORLD_SIZE, WORLD_SIZE];
+ mi_pos = new SVector2((int) Math.Ceiling(WORLD_SIZE / 2.0f), (int)Math.Ceiling(WORLD_SIZE / 2.0f));
+ }
+
+ public void fu_Run()
+ {
+ bool isRunning = true;
+
+ Thread inputThread = new Thread(() =>
+ {
+ if (Console.ReadKey(true).Key == System.ConsoleKey.Escape)
+ isRunning = false;
+ });
+ inputThread.Start();
+
+ while (isRunning)
+ {
+ fi_Draw();
+ Thread.Sleep(SLEEP_TIME);
+ fi_Calculate();
+ }
+ }
+
+ private void fi_Calculate()
+ {
+ // rotate
+ mi_dir += mi_field[mi_pos.X, mi_pos.Y] ? -1 : 1;
+ mi_dir = (EDirection) (((int)mi_dir + 4) % 4);
+
+ // color
+ mi_field[mi_pos.X, mi_pos.Y] = !mi_field[mi_pos.X, mi_pos.Y];
+
+ // move
+ mi_pos += mi_dir;
+ mi_pos = mi_pos.fu_DonutClamp(WORLD_SIZE);
+ }
+
+ private void fi_Draw()
+ {
+ Console.CursorVisible = false;
+ for(int y = 0; y < mi_field.GetLength(1); y++)
+ {
+ for(int x = 0; x < mi_field.GetLength(0); x++)
+ {
+ Console.SetCursorPosition(x, y);
+ Console.BackgroundColor = mi_field[x, y] ? System.ConsoleColor.Black : System.ConsoleColor.White;
+ if (mi_pos.X == x && mi_pos.Y == y)
+ {
+ Console.ForegroundColor = System.ConsoleColor.Red;
+ Console.Write(fi_CharForDir());
+ }
+ else
+ {
+ Console.Write(' ');
+ }
+ }
+ Console.SetCursorPosition(0, WORLD_SIZE);
+ Console.ResetColor();
+ }
+
+ Console.WriteLine("Press Escape for exiting");
+ }
+
+ private char fi_CharForDir()
+ {
+ switch (mi_dir)
+ {
+ case EDirection.LEFT:
+ return '←';
+ case EDirection.UP:
+ return '↑';
+ case EDirection.RIGHT:
+ return '→';
+ case EDirection.DOWN:
+ return '↓';
+ default:
+ throw new System.ArgumentException($"Direction {mi_dir} not valid");
+ }
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/LangtonWholeInOne.csproj b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/LangtonWholeInOne.csproj
new file mode 100644
index 0000000..fdfc0c1
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/LangtonWholeInOne.csproj
@@ -0,0 +1,56 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {500A2445-E4BF-48A7-900C-CFA0BB244AA4}
+ Exe
+ Langton
+ Langton
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Program.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Program.cs
new file mode 100644
index 0000000..fb479eb
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Program.cs
@@ -0,0 +1,13 @@
+// Disclaimer - Diese Lösung habe ich implementiert bevor ich die README.MD gelesen habe,
+// nur anhand der mitgelieferten GIF und theoretischem Vorwissen zu Langtons Ameise
+namespace Langton
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ CField f = new CField();
+ f.fu_Run();
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Properties/AssemblyInfo.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d955d95
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("Langton")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Langton")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("500a2445-e4bf-48a7-900c-cfa0bb244aa4")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Vector2.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Vector2.cs
new file mode 100644
index 0000000..1d51369
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/Langton/Vector2.cs
@@ -0,0 +1,42 @@
+namespace Langton
+{
+ internal struct SVector2
+ {
+ public int X;
+ public int Y;
+
+ public SVector2(int _x, int _y)
+ {
+ X = _x;
+ Y = _y;
+ }
+
+ public static SVector2 operator +(SVector2 _v1, SVector2 _v2)
+ {
+ return new SVector2(_v1.X + _v2.X, _v1.Y + _v2.Y);
+ }
+
+ public static SVector2 operator +(SVector2 _v1, EDirection _dir)
+ {
+ switch (_dir)
+ {
+ case EDirection.LEFT:
+ return _v1 + new SVector2(-1, 0);
+ case EDirection.UP:
+ return _v1 + new SVector2(0, -1);
+ case EDirection.RIGHT:
+ return _v1 + new SVector2(1, 0);
+ case EDirection.DOWN:
+ return _v1 + new SVector2(0, 1);
+ default:
+ throw new System.ArgumentException($"Direction {_dir} not valid");
+ }
+ }
+
+ public SVector2 fu_DonutClamp(int _worldSize)
+ {
+ return new SVector2((X + _worldSize) % _worldSize,
+ (Y + _worldSize) % _worldSize);
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/App.config b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Direction.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Direction.cs
new file mode 100644
index 0000000..5577572
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Direction.cs
@@ -0,0 +1,10 @@
+namespace LangtonBackend
+{
+ public enum EDirection
+ {
+ LEFT,
+ UP,
+ RIGHT,
+ DOWN,
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Field.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Field.cs
new file mode 100644
index 0000000..048239b
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Field.cs
@@ -0,0 +1,96 @@
+using System.IO;
+using System.Text;
+
+using Console = System.Console;
+
+namespace LangtonBackend
+{
+ internal class CField
+ {
+ private int mi_worldSize;
+ private int mi_stepCount;
+
+ private bool[,] mi_field;
+ private EDirection mi_dir = EDirection.LEFT;
+ private SVector2 mi_pos;
+
+ public CField()
+ {
+ Console.WriteLine("Willkommen zu Langtons Ameise - Backend");
+ Console.WriteLine("Bevor es losgehen kann benötigen wir ein paar Eingaben");
+ mi_worldSize = Helper.fu_SafeNumberInput("Gewünschte Feldgröße", 1, 50);
+ mi_pos = Helper.fu_SafeVectorInput("Gewünschte Startposition", new SVector2(0,0), new SVector2(mi_worldSize - 1, mi_worldSize - 1));
+
+ mi_dir = Helper.fu_SafeDirectionInput("Gewünschte Startrichtung");
+
+ mi_stepCount = Helper.fu_SafeNumberInput("Gewünschte Anzahl der Spielzüge", 1, int.MaxValue);
+
+ mi_field = new bool[mi_worldSize, mi_worldSize];
+ }
+
+ public void fu_Run()
+ {
+ bool isRunning = true;
+
+ StringBuilder sb = new StringBuilder();
+ fi_AddFieldToString(sb);
+ for (int count = 1; count < mi_stepCount && isRunning; count++)
+ {
+ fi_Calculate();
+ fi_AddFieldToString(sb);
+ }
+
+ File.WriteAllText("output.save", sb.ToString());
+ Console.WriteLine("output.save erfolgreich geschrieben");
+ Console.WriteLine("Drücke eine beliebige Taste um das Programm zu beenden");
+ Console.Read();
+ }
+
+ private void fi_Calculate()
+ {
+ // rotate
+ mi_dir += mi_field[mi_pos.X, mi_pos.Y] ? -1 : 1;
+ mi_dir = (EDirection)(((int)mi_dir + 4) % 4);
+
+ // color
+ mi_field[mi_pos.X, mi_pos.Y] = !mi_field[mi_pos.X, mi_pos.Y];
+
+ // move
+ mi_pos += mi_dir;
+ mi_pos = mi_pos.fu_DonutClamp(mi_worldSize);
+ }
+ private char fi_CharForDir()
+ {
+ switch (mi_dir)
+ {
+ case EDirection.LEFT:
+ return 'w';
+ case EDirection.UP:
+ return 'n';
+ case EDirection.RIGHT:
+ return 'o';
+ case EDirection.DOWN:
+ return 's';
+ default:
+ throw new System.ArgumentException($"Direction {mi_dir} not valid");
+ }
+ }
+
+ private void fi_AddFieldToString(StringBuilder _sb)
+ {
+ for (int y = 0; y < mi_field.GetLength(1); y++)
+ {
+ for (int x = 0; x < mi_field.GetLength(0); x++)
+ {
+ if (mi_pos.X == x && mi_pos.Y == y)
+ {
+ _sb.Append(fi_CharForDir());
+ }
+ _sb.Append(mi_field[x, y] ? "s" : "w");
+ _sb.Append(',');
+ }
+ }
+ _sb.Append(System.Environment.NewLine);
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Helper.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Helper.cs
new file mode 100644
index 0000000..2f5883a
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Helper.cs
@@ -0,0 +1,79 @@
+using Console = System.Console;
+
+namespace LangtonBackend
+{
+ public static class Helper
+ {
+ public static int fu_SafeNumberInput(string _text)
+ {
+ return fu_SafeNumberInput(_text, int.MinValue, int.MaxValue);
+ }
+
+ public static int fu_SafeNumberInput(string _text, int _min, int _max)
+ {
+ string outputText;
+ if (_min == int.MinValue && _max == int.MaxValue)
+ {
+ outputText = _text + ": ";
+ }
+ else
+ {
+ outputText = _text + $" ({_min}-{_max}): ";
+ }
+
+ int returnValue;
+ while (true)
+ {
+ Console.Write(outputText);
+ if (int.TryParse(Console.ReadLine(), out returnValue))
+ {
+ if (returnValue >= _min && returnValue <= _max)
+ {
+ return returnValue;
+ }
+ Console.WriteLine($"Eingabe ist nicht im Wertebereich {_min}-{_max}");
+ }
+ else
+ {
+ Console.WriteLine("Eingabe ist keine Nummer");
+ }
+ }
+ }
+
+ public static SVector2 fu_SafeVectorInput(string _text, SVector2 _min, SVector2 _max)
+ {
+ int xSize = fu_SafeNumberInput(_text + " X", _min.X, _max.X);
+ int ySize = fu_SafeNumberInput(_text + " Y", _min.Y, _max.Y);
+
+ return new SVector2(xSize, ySize);
+ }
+
+ public static EDirection fu_SafeDirectionInput(string _text)
+ {
+ string inputS;
+ while (true)
+ {
+ Console.Write(_text + " (n,o,s,w): ");
+ inputS = Console.ReadLine();
+ if (inputS.ToLower() == "n")
+ {
+ return EDirection.UP;
+ }
+ if (inputS.ToLower() == "o")
+ {
+ return EDirection.RIGHT;
+ }
+ if (inputS.ToLower() == "s")
+ {
+ return EDirection.DOWN;
+ }
+ if (inputS.ToLower() == "w")
+ {
+ return EDirection.LEFT;
+ }
+
+ Console.WriteLine("Eingabe ungültig");
+ }
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/LangtonBackend.csproj b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/LangtonBackend.csproj
new file mode 100644
index 0000000..d3f8dbe
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/LangtonBackend.csproj
@@ -0,0 +1,57 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {AD301928-3F49-4A34-9F1F-8336097DAE65}
+ Exe
+ LangtonBackend
+ LangtonBackend
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Program.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Program.cs
new file mode 100644
index 0000000..ced4e00
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Program.cs
@@ -0,0 +1,11 @@
+namespace LangtonBackend
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ CField f = new CField();
+ f.fu_Run();
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Properties/AssemblyInfo.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0bd6f39
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("LangtonBackend")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("LangtonBackend")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("ad301928-3f49-4a34-9f1f-8336097dae65")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Vector2.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Vector2.cs
new file mode 100644
index 0000000..6b7d332
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonBackend/Vector2.cs
@@ -0,0 +1,42 @@
+namespace LangtonBackend
+{
+ public struct SVector2
+ {
+ public int X;
+ public int Y;
+
+ public SVector2(int _x, int _y)
+ {
+ X = _x;
+ Y = _y;
+ }
+
+ public static SVector2 operator +(SVector2 _v1, SVector2 _v2)
+ {
+ return new SVector2(_v1.X + _v2.X, _v1.Y + _v2.Y);
+ }
+
+ public static SVector2 operator +(SVector2 _v1, EDirection _dir)
+ {
+ switch (_dir)
+ {
+ case EDirection.LEFT:
+ return _v1 + new SVector2(-1, 0);
+ case EDirection.UP:
+ return _v1 + new SVector2(0, -1);
+ case EDirection.RIGHT:
+ return _v1 + new SVector2(1, 0);
+ case EDirection.DOWN:
+ return _v1 + new SVector2(0, 1);
+ default:
+ throw new System.ArgumentException($"Direction {_dir} not valid");
+ }
+ }
+
+ public SVector2 fu_DonutClamp(int _worldSize)
+ {
+ return new SVector2((X + _worldSize) % _worldSize,
+ (Y + _worldSize) % _worldSize);
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/App.config b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Direction.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Direction.cs
new file mode 100644
index 0000000..6481d90
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Direction.cs
@@ -0,0 +1,10 @@
+namespace LangtonFrontend
+{
+ public enum EDirection
+ {
+ LEFT,
+ UP,
+ RIGHT,
+ DOWN,
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Field.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Field.cs
new file mode 100644
index 0000000..f0bc613
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Field.cs
@@ -0,0 +1,94 @@
+using System.Linq;
+
+using Console = System.Console;
+using Math = System.Math;
+
+namespace LangtonFrontend
+{
+ internal class CField
+ {
+ private bool[,] mi_field;
+ public EDirection pu_dir { get; private set; }
+ public SVector2 pu_pos { get; private set; }
+
+ public int XSize => mi_field.GetLength(0);
+ public int YSize => mi_field.GetLength(1);
+
+ public CField(string _line)
+ {
+ string[] parts = _line.Split(new[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries);
+ int sqrt = (int)Math.Sqrt(parts.Length);
+
+ mi_field = new bool[sqrt, sqrt];
+ int x, y;
+ for (int i = 0; i < parts.Length; i++)
+ {
+ x = i % sqrt;
+ y = i / sqrt;
+ mi_field[x, y] = parts[i].Last() == 's';
+ if (parts[i].Length > 1)
+ {
+ pu_pos = new SVector2(x, y);
+ char dir = parts[i].First();
+ switch (dir)
+ {
+ case 'n':
+ pu_dir = EDirection.UP;
+ break;
+ case 'o':
+ pu_dir = EDirection.RIGHT;
+ break;
+ case 's':
+ pu_dir = EDirection.DOWN;
+ break;
+ case 'w':
+ pu_dir = EDirection.LEFT;
+ break;
+ }
+ }
+ }
+ }
+
+
+
+ public void fu_Draw()
+ {
+ Console.CursorVisible = false;
+ for (int y = 0; y < mi_field.GetLength(1); y++)
+ {
+ for (int x = 0; x < mi_field.GetLength(0); x++)
+ {
+ Console.SetCursorPosition(x, y);
+ Console.BackgroundColor = mi_field[x, y] ? System.ConsoleColor.Black : System.ConsoleColor.White;
+ if (pu_pos.X == x && pu_pos.Y == y)
+ {
+ Console.ForegroundColor = System.ConsoleColor.Red;
+ Console.Write(fi_CharForDir());
+ Console.ResetColor();
+ }
+ else
+ {
+ Console.Write(' ');
+ }
+ }
+ }
+ }
+
+ private char fi_CharForDir()
+ {
+ switch (pu_dir)
+ {
+ case EDirection.LEFT:
+ return '←';
+ case EDirection.UP:
+ return '↑';
+ case EDirection.RIGHT:
+ return '→';
+ case EDirection.DOWN:
+ return '↓';
+ default:
+ throw new System.ArgumentException($"Direction {pu_dir} not valid");
+ }
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Helper.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Helper.cs
new file mode 100644
index 0000000..062fce3
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Helper.cs
@@ -0,0 +1,60 @@
+using System.IO;
+
+using Console = System.Console;
+
+namespace LangtonFrontend
+{
+ public static class Helper
+ {
+ public static int fu_SafeNumberInput(string _text)
+ {
+ return fu_SafeNumberInput(_text, int.MinValue, int.MaxValue);
+ }
+
+ public static int fu_SafeNumberInput(string _text, int _min, int _max)
+ {
+ string outputText;
+ if (_min == int.MinValue && _max == int.MaxValue)
+ {
+ outputText = _text + ": ";
+ }
+ else
+ {
+ outputText = _text + $" ({_min}-{_max}): ";
+ }
+
+ int returnValue;
+ while (true)
+ {
+ Console.Write(outputText);
+ if (int.TryParse(Console.ReadLine(), out returnValue))
+ {
+ if (returnValue >= _min && returnValue <= _max)
+ {
+ return returnValue;
+ }
+ Console.WriteLine($"Eingabe ist nicht im Wertebereich {_min}-{_max}");
+ }
+ else
+ {
+ Console.WriteLine("Eingabe ist keine Nummer");
+ }
+ }
+ }
+
+ public static string[] fu_SafeFileRead(string _text)
+ {
+ string fileName;
+ while (true)
+ {
+ Console.Write("Gib einen gültigen Dateinamen ein: ");
+ fileName = Console.ReadLine();
+ if (File.Exists(fileName))
+ {
+ return File.ReadAllLines(fileName);
+ }
+ Console.WriteLine("Datei nicht lesbar/verfügbar");
+ }
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/LangtonFrontend.csproj b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/LangtonFrontend.csproj
new file mode 100644
index 0000000..9e8ce06
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/LangtonFrontend.csproj
@@ -0,0 +1,57 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {623833F8-B936-4AEA-9BE0-2DB62C298C01}
+ Exe
+ LangtonFrontend
+ LangtonFrontend
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Program.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Program.cs
new file mode 100644
index 0000000..ce6b726
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Program.cs
@@ -0,0 +1,69 @@
+using System.Threading;
+
+using Console = System.Console;
+
+namespace LangtonFrontend
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Willkommen zu Langtons Ameise - Backend");
+ Console.WriteLine("Sobald das Programm gestartet wurde lässt es sich vorzeitig beenden wenn Escape gedrückt wird");
+ Console.WriteLine("Bevor es losgehen kann benötigen wir ein paar Eingaben");
+ int speed = Helper.fu_SafeNumberInput("Gewünschte Darstellungsgeschwindigkeit in Millisekunden", 1, 1000000);
+
+ string[] lines = Helper.fu_SafeFileRead("Gewünschte Datei");
+
+ CField f = new CField(lines[0]);
+ Console.WriteLine($"Feldgröße: {f.XSize} * {f.YSize}");
+ Console.WriteLine($"Startposition: {f.pu_pos}");
+ Console.WriteLine($"Startrichung: {fi_CharForDir(f.pu_dir)}");
+ Console.WriteLine($"Anzahl der Spielzüge: {lines.Length}");
+
+ Console.WriteLine("Drücke eine beliebige Taste um das Programm zu starten");
+ Console.Read();
+
+ bool isRunning = true;
+
+ Thread inputThread = new Thread(() =>
+ {
+ if (Console.ReadKey(true).Key == System.ConsoleKey.Escape)
+ isRunning = false;
+ });
+ inputThread.Start();
+
+ Console.Clear();
+ Console.SetCursorPosition(0, f.XSize);
+ Console.WriteLine("Drücke Escape zum beenden");
+
+
+ for(int i = 0; i < lines.Length && isRunning; i++)
+ {
+ if (string.IsNullOrEmpty(lines[i]))
+ break;
+
+ f = new CField(lines[i]);
+ f.fu_Draw();
+ Thread.Sleep(speed);
+ }
+ }
+
+ private static char fi_CharForDir(EDirection _dir)
+ {
+ switch (_dir)
+ {
+ case EDirection.LEFT:
+ return 'w';
+ case EDirection.UP:
+ return 'n';
+ case EDirection.RIGHT:
+ return 'o';
+ case EDirection.DOWN:
+ return 's';
+ default:
+ throw new System.ArgumentException($"Direction {_dir} not valid");
+ }
+ }
+ }
+}
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Properties/AssemblyInfo.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b28f602
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("LangtonFrontend")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("LangtonFrontend")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("623833f8-b936-4aea-9be0-2db62c298c01")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Vector2.cs b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Vector2.cs
new file mode 100644
index 0000000..df04449
--- /dev/null
+++ b/katas/LangtonAnt/solutions/UmlauteUeberall/Langton/LangtonFrontend/Vector2.cs
@@ -0,0 +1,19 @@
+namespace LangtonFrontend
+{
+ internal struct SVector2
+ {
+ public int X;
+ public int Y;
+
+ public SVector2(int _x, int _y)
+ {
+ X = _x;
+ Y = _y;
+ }
+
+ public override string ToString()
+ {
+ return $"{X}/{Y}";
+ }
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard.sln b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard.sln
new file mode 100644
index 0000000..bb8811a
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33205.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StrangeChessboard", "StrangeChessboard\StrangeChessboard.csproj", "{E36BA4CE-407E-4EB4-9941-4C830D8C7E70}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E36BA4CE-407E-4EB4-9941-4C830D8C7E70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E36BA4CE-407E-4EB4-9941-4C830D8C7E70}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E36BA4CE-407E-4EB4-9941-4C830D8C7E70}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E36BA4CE-407E-4EB4-9941-4C830D8C7E70}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B9AA5FC1-24C2-4420-A90C-7FE8BD53C9B1}
+ EndGlobalSection
+EndGlobal
diff --git a/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/App.config b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/App.config
new file mode 100644
index 0000000..56efbc7
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/Program.cs b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/Program.cs
new file mode 100644
index 0000000..a688594
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/Program.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Linq;
+
+using Console = System.Console;
+
+namespace StrangeChessboard
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ List cs = new List() { 3, 1, 2, 7, 1 };
+ List rs = new List() { 1, 8, 4, 5, 2 };
+
+ if (cs.Count != rs.Count)
+ {
+ throw new System.InvalidOperationException("Beide Listen müssen gleich lang sein");
+ }
+
+ var result = fu_Calculate(cs, rs);
+
+ Console.WriteLine(result);
+
+ Console.ReadKey();
+ }
+
+ public static (int white, int black) fu_Calculate(List _cs, List _rs)
+ {
+ bool curWhite = true;
+ List whites = new List();
+ List blacks = new List();
+
+ for (int y = 0; y < _rs.Count; y++)
+ {
+ for (int x = 0; x < _cs.Count; x++)
+ {
+ if (curWhite)
+ {
+ whites.Add(_cs[x] * _rs[y]);
+ }
+ else
+ {
+ blacks.Add(_cs[x] * _rs[y]);
+ }
+ curWhite = !curWhite;
+ }
+ }
+
+ return (whites.Sum(), blacks.Sum());
+ }
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/Properties/AssemblyInfo.cs b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..40daf7f
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("StrangeChessboard")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("StrangeChessboard")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("e36ba4ce-407e-4eb4-9941-4c830d8c7e70")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/StrangeChessboard.csproj b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/StrangeChessboard.csproj
new file mode 100644
index 0000000..4366b7e
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/UmlauteUeberall/StrangeChessboard/StrangeChessboard/StrangeChessboard.csproj
@@ -0,0 +1,53 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E36BA4CE-407E-4EB4-9941-4C830D8C7E70}
+ Exe
+ StrangeChessboard
+ StrangeChessboard
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file