diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/App.xaml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/App.xaml
new file mode 100644
index 0000000..841d78b
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/App.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/App.xaml.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/App.xaml.cs
new file mode 100644
index 0000000..9871700
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/App.xaml.cs
@@ -0,0 +1,11 @@
+namespace LangtonAnt;
+
+public partial class App : Application
+{
+ public App()
+ {
+ InitializeComponent();
+
+ MainPage = new AppShell();
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/AppShell.xaml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/AppShell.xaml
new file mode 100644
index 0000000..e70cf8f
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/AppShell.xaml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/AppShell.xaml.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/AppShell.xaml.cs
new file mode 100644
index 0000000..8989673
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/AppShell.xaml.cs
@@ -0,0 +1,9 @@
+namespace LangtonAnt;
+
+public partial class AppShell : Shell
+{
+ public AppShell()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/LangtonAnt.csproj b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/LangtonAnt.csproj
new file mode 100644
index 0000000..9a7799d
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/LangtonAnt.csproj
@@ -0,0 +1,59 @@
+
+
+
+ net7.0-android;net7.0-ios;net7.0-maccatalyst
+ $(TargetFrameworks);net7.0-windows10.0.19041.0
+
+
+ Exe
+ LangtonAnt
+ true
+ true
+ enable
+
+
+ LangtonAnt
+
+
+ com.companyname.langtonant
+ f4625517-8028-4c23-ba09-295e8cd520db
+
+
+ 1.0
+ 1
+
+ 11.0
+ 13.1
+ 21.0
+ 10.0.17763.0
+ 10.0.17763.0
+ 6.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/LangtonAnt.sln b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/LangtonAnt.sln
new file mode 100644
index 0000000..a343e8f
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/LangtonAnt.sln
@@ -0,0 +1,27 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31611.283
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LangtonAnt", "LangtonAnt.csproj", "{538C5CEB-16DD-40C4-A823-27964FCA2E4F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {538C5CEB-16DD-40C4-A823-27964FCA2E4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {538C5CEB-16DD-40C4-A823-27964FCA2E4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {538C5CEB-16DD-40C4-A823-27964FCA2E4F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {538C5CEB-16DD-40C4-A823-27964FCA2E4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {538C5CEB-16DD-40C4-A823-27964FCA2E4F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {538C5CEB-16DD-40C4-A823-27964FCA2E4F}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
+ EndGlobalSection
+EndGlobal
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MainPage.xaml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MainPage.xaml
new file mode 100644
index 0000000..f5cfe54
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MainPage.xaml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MainPage.xaml.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MainPage.xaml.cs
new file mode 100644
index 0000000..057b335
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MainPage.xaml.cs
@@ -0,0 +1,18 @@
+namespace LangtonAnt;
+public partial class MainPage : ContentPage
+{
+ DashboardViewModel viewModel = new DashboardViewModel();
+ public MainPage()
+ {
+ viewModel.Initialize();
+ BindingContext = viewModel;
+ AntDrawable.Matchfield = viewModel.Data;
+ InitializeComponent();
+
+ Loaded += (sender, args) => {
+ viewModel.Data.PropertyChanged += (sender, args) => { if (args.PropertyName == "CurrentResult") antGraphicsView.Invalidate(); };
+ viewModel.LoadDataCommand.Execute(null);
+ };
+ }
+}
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MauiProgram.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MauiProgram.cs
new file mode 100644
index 0000000..fc11d56
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/MauiProgram.cs
@@ -0,0 +1,27 @@
+global using LangtonAnt.Mvvm.Lite;
+global using LangtonAnt.Utils;
+global using LangtonAnt.ViewModels;
+using Microsoft.Extensions.Logging;
+
+namespace LangtonAnt;
+
+public static class MauiProgram
+{
+ public static MauiApp CreateMauiApp()
+ {
+ var builder = MauiApp.CreateBuilder();
+ builder
+ .UseMauiApp()
+ .ConfigureFonts(fonts =>
+ {
+ fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
+ fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
+ });
+
+#if DEBUG
+ builder.Logging.AddDebug();
+#endif
+
+ return builder.Build();
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Mvvm.Lite/BaseViewModel.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Mvvm.Lite/BaseViewModel.cs
new file mode 100644
index 0000000..da9320e
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Mvvm.Lite/BaseViewModel.cs
@@ -0,0 +1,49 @@
+using System.Windows.Input;
+namespace LangtonAnt.Mvvm.Lite;
+///
+/// Abstarct base-klasse für MVVM-ViewModels
+///
+public abstract class BaseViewModel : NotificationBase
+{
+ private bool _isRefreshing = false;
+ private bool _isBusy = false;
+ private string _title;
+
+ public bool IsRefreshing
+ {
+ get => _isRefreshing;
+ protected set
+ {
+ if (_isRefreshing == value)
+ return;
+
+ _isRefreshing = value;
+ RaisePropertyChanged(nameof(IsRefreshing));
+ }
+ }
+ public bool IsBusy
+ {
+ get => _isBusy;
+ protected set
+ {
+ if (_isBusy == value)
+ return;
+
+ _isBusy = value;
+
+ RaisePropertyChanged(nameof(IsBusy));
+ }
+ }
+ public string Title
+ {
+ get => _title;
+ set {
+ if(_title != value)
+ {
+ _title = value;
+ RaisePropertyChanged(nameof(Title));
+ }
+ }
+ }
+ public ICommand LoadDataCommand { get; protected set; }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Mvvm.Lite/NotificationBase.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Mvvm.Lite/NotificationBase.cs
new file mode 100644
index 0000000..15ba1e8
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Mvvm.Lite/NotificationBase.cs
@@ -0,0 +1,43 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace LangtonAnt.Mvvm.Lite;
+
+public abstract class NotificationBase : INotifyPropertyChanged
+{
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ // SetField (Name, value); // where there is a data member
+ protected virtual bool SetProperty(ref T field, T value, [CallerMemberName] string property = null)
+ {
+ if (EqualityComparer.Default.Equals(field, value)) return false;
+ field = value;
+ RaisePropertyChanged(property);
+ return true;
+ }
+
+ // SetField(()=> somewhere.Name = value; somewhere.Name, value) // Advanced case where you rely on another property
+ protected virtual void SetProperty(T currentValue, T newValue, Action doSet, [CallerMemberName] string property = null)
+ {
+ if (EqualityComparer.Default.Equals(currentValue, newValue)) return;
+ doSet.Invoke();
+ RaisePropertyChanged(property);
+ }
+
+ protected void RaisePropertyChanged(string property)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
+ }
+}
+
+public abstract class NotificationBase : NotificationBase where T : class, new()
+{
+ protected readonly T This;
+
+ public static implicit operator T(NotificationBase thing) { return thing.This; }
+
+ protected NotificationBase(T thing = null)
+ {
+ This = thing ?? new T();
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/AndroidManifest.xml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/AndroidManifest.xml
new file mode 100644
index 0000000..e9937ad
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/MainActivity.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/MainActivity.cs
new file mode 100644
index 0000000..8b140c2
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/MainActivity.cs
@@ -0,0 +1,10 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+
+namespace LangtonAnt;
+
+[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
+public class MainActivity : MauiAppCompatActivity
+{
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/MainApplication.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/MainApplication.cs
new file mode 100644
index 0000000..3904cfa
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/MainApplication.cs
@@ -0,0 +1,15 @@
+using Android.App;
+using Android.Runtime;
+
+namespace LangtonAnt;
+
+[Application]
+public class MainApplication : MauiApplication
+{
+ public MainApplication(IntPtr handle, JniHandleOwnership ownership)
+ : base(handle, ownership)
+ {
+ }
+
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/Resources/values/colors.xml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/Resources/values/colors.xml
new file mode 100644
index 0000000..c04d749
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Android/Resources/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #512BD4
+ #2B0B98
+ #2B0B98
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/AppDelegate.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/AppDelegate.cs
new file mode 100644
index 0000000..3500e00
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/AppDelegate.cs
@@ -0,0 +1,9 @@
+using Foundation;
+
+namespace LangtonAnt;
+
+[Register("AppDelegate")]
+public class AppDelegate : MauiUIApplicationDelegate
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/Info.plist b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/Info.plist
new file mode 100644
index 0000000..c96dd0a
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/appicon.appiconset
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/Program.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/Program.cs
new file mode 100644
index 0000000..7820ff2
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/MacCatalyst/Program.cs
@@ -0,0 +1,15 @@
+using ObjCRuntime;
+using UIKit;
+
+namespace LangtonAnt;
+
+public class Program
+{
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, typeof(AppDelegate));
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Tizen/Main.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Tizen/Main.cs
new file mode 100644
index 0000000..0758688
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Tizen/Main.cs
@@ -0,0 +1,16 @@
+using System;
+using Microsoft.Maui;
+using Microsoft.Maui.Hosting;
+
+namespace LangtonAnt;
+
+class Program : MauiApplication
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+
+ static void Main(string[] args)
+ {
+ var app = new Program();
+ app.Run(args);
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Tizen/tizen-manifest.xml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Tizen/tizen-manifest.xml
new file mode 100644
index 0000000..fbbcd73
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Tizen/tizen-manifest.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ maui-appicon-placeholder
+
+
+
+
+ http://tizen.org/privilege/internet
+
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/App.xaml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/App.xaml
new file mode 100644
index 0000000..abf6d1b
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/App.xaml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/App.xaml.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/App.xaml.cs
new file mode 100644
index 0000000..d871d1b
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/App.xaml.cs
@@ -0,0 +1,24 @@
+using Microsoft.UI.Xaml;
+
+// To learn more about WinUI, the WinUI project structure,
+// and more about our project templates, see: http://aka.ms/winui-project-info.
+
+namespace LangtonAnt.WinUI;
+
+///
+/// Provides application-specific behavior to supplement the default Application class.
+///
+public partial class App : MauiWinUIApplication
+{
+ ///
+ /// Initializes the singleton application object. This is the first line of authored code
+ /// executed, and as such is the logical equivalent of main() or WinMain().
+ ///
+ public App()
+ {
+ this.InitializeComponent();
+ }
+
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/Package.appxmanifest b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/Package.appxmanifest
new file mode 100644
index 0000000..e106110
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/Package.appxmanifest
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+ $placeholder$
+ User Name
+ $placeholder$.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/app.manifest b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/app.manifest
new file mode 100644
index 0000000..a8f5fc6
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/Windows/app.manifest
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ true/PM
+ PerMonitorV2, PerMonitor
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/AppDelegate.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/AppDelegate.cs
new file mode 100644
index 0000000..3500e00
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/AppDelegate.cs
@@ -0,0 +1,9 @@
+using Foundation;
+
+namespace LangtonAnt;
+
+[Register("AppDelegate")]
+public class AppDelegate : MauiUIApplicationDelegate
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/Info.plist b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/Info.plist
new file mode 100644
index 0000000..0004a4f
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ LSRequiresIPhoneOS
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/appicon.appiconset
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/Program.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/Program.cs
new file mode 100644
index 0000000..7820ff2
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Platforms/iOS/Program.cs
@@ -0,0 +1,15 @@
+using ObjCRuntime;
+using UIKit;
+
+namespace LangtonAnt;
+
+public class Program
+{
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, typeof(AppDelegate));
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Properties/launchSettings.json b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Properties/launchSettings.json
new file mode 100644
index 0000000..edf8aad
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Windows Machine": {
+ "commandName": "MsixPackage",
+ "nativeDebugging": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/AppIcon/appicon.svg b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/AppIcon/appicon.svg
new file mode 100644
index 0000000..9d63b65
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/AppIcon/appicon.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/AppIcon/appiconfg.svg b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/AppIcon/appiconfg.svg
new file mode 100644
index 0000000..21dfb25
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/AppIcon/appiconfg.svg
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Fonts/OpenSans-Regular.ttf b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Fonts/OpenSans-Regular.ttf
new file mode 100644
index 0000000..e248a95
Binary files /dev/null and b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Fonts/OpenSans-Regular.ttf differ
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Fonts/OpenSans-Semibold.ttf b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Fonts/OpenSans-Semibold.ttf
new file mode 100644
index 0000000..dbc9572
Binary files /dev/null and b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Fonts/OpenSans-Semibold.ttf differ
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Images/ant.svg b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Images/ant.svg
new file mode 100644
index 0000000..fb84211
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Images/ant.svg
@@ -0,0 +1,34 @@
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Images/dotnet_bot.svg b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Images/dotnet_bot.svg
new file mode 100644
index 0000000..abfaff2
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Images/dotnet_bot.svg
@@ -0,0 +1,93 @@
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Raw/AboutAssets.txt b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Raw/AboutAssets.txt
new file mode 100644
index 0000000..15d6244
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Raw/AboutAssets.txt
@@ -0,0 +1,15 @@
+Any raw assets you want to be deployed with your application can be placed in
+this directory (and child directories). Deployment of the asset to your application
+is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
+
+
+
+These files will be deployed with you package and will be accessible using Essentials:
+
+ async Task LoadMauiAsset()
+ {
+ using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
+ using var reader = new StreamReader(stream);
+
+ var contents = reader.ReadToEnd();
+ }
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Splash/splash.svg b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Splash/splash.svg
new file mode 100644
index 0000000..21dfb25
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Splash/splash.svg
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Styles/Colors.xaml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Styles/Colors.xaml
new file mode 100644
index 0000000..245758b
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Styles/Colors.xaml
@@ -0,0 +1,44 @@
+
+
+
+
+ #512BD4
+ #DFD8F7
+ #2B0B98
+ White
+ Black
+ #E1E1E1
+ #C8C8C8
+ #ACACAC
+ #919191
+ #6E6E6E
+ #404040
+ #212121
+ #141414
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #F7B548
+ #FFD590
+ #FFE5B9
+ #28C2D1
+ #7BDDEF
+ #C3F2F4
+ #3E8EED
+ #72ACF1
+ #A7CBF6
+
+
\ No newline at end of file
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Styles/Styles.xaml b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Styles/Styles.xaml
new file mode 100644
index 0000000..dc4a034
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Resources/Styles/Styles.xaml
@@ -0,0 +1,405 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Utils/AntDrawable.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Utils/AntDrawable.cs
new file mode 100644
index 0000000..72eebc1
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/Utils/AntDrawable.cs
@@ -0,0 +1,107 @@
+using LangtonAnt.backend;
+
+namespace LangtonAnt.Utils;
+///
+/// Frontend Realisierung
+/// Hilfsklasse für die Graphische-Ausgabe
+/// rojekt: Langton's Ant Assessment
+/// Autor: Petar Peev i.A. von Oliver Arentzen, advastore SE
+///
+internal class AntDrawable : IDrawable
+{
+ ///
+ /// Zeichnet die Ausgabe auf einem Leinwand
+ ///
+ /// die Leinwand
+ /// das Rechteck zum aktualisieren
+ public void Draw(ICanvas canvas, RectF dirtyRect)
+ {
+ if (Matchfield != null)
+ {
+ // Zell-Eigenschaften ermitteln
+ var rowHeight = (dirtyRect.Height - 1) / Matchfield.EdgeLenght;
+ var columnWidth = (dirtyRect.Width - 1) / Matchfield.EdgeLenght;
+
+ // Feld-Raster zeichnen
+ canvas.StrokeColor = Colors.Black;
+
+ for (int row = 0; row <= Matchfield.EdgeLenght; row++)
+ {
+ canvas.DrawLine(dirtyRect.X, dirtyRect.Y + row * rowHeight + 0.5F,
+ dirtyRect.Width, dirtyRect.Y + row * rowHeight + 0.5F);
+ canvas.DrawLine(dirtyRect.X + row * columnWidth + 0.5F, dirtyRect.Y,
+ dirtyRect.X + row * columnWidth + 0.5F, dirtyRect.Height);
+
+ }
+ // Zellen-Inhalt zeichnen
+ var allCells = Matchfield.CurrentResult?.Split(",");
+ if (allCells != null)
+ {
+ for (int row = 0; row < Matchfield.EdgeLenght; row++)
+ {
+ for (int column = 0; column < Matchfield.EdgeLenght; column++)
+ {
+ var cellIndex = row * Matchfield.EdgeLenght + column;
+ if (cellIndex >= 0 && cellIndex < allCells.Length)
+ {
+ canvas.FillColor = allCells[cellIndex].ToLower().StartsWith("s") ?
+ Colors.Black : Colors.White;
+ canvas.FillRectangle(new RectF(column * columnWidth + 1F, row * rowHeight + 1F, columnWidth - 2, rowHeight - 2));
+ }
+ }
+ }
+ //ToDo: evtl. mit der nächste MAUI Relese https://github.com/dotnet/maui/issues/6742
+ //var image = new Image { Source = ImageSource.FromResource("ant.jpg") };
+ //canvas.DrawImage((Microsoft.Maui.Graphics.IImage)image,dirtyRect.X + Matchfield.CurrentAntPosition.Column * columnWidth, dirtyRect.Y + Matchfield.CurrentAntPosition.Row * rowHeight,rowHeight, columnWidth);
+ drawAntAt(Matchfield.AntCurrentOutlook, dirtyRect.X + Matchfield.CurrentAntPosition.Column * columnWidth, dirtyRect.Y + Matchfield.CurrentAntPosition.Row * rowHeight,
+ columnWidth,rowHeight, canvas);
+ }
+ }
+ }
+ ///
+ /// das Feld mit den aktuellen Daten zum zeichnen
+ ///
+ public static IMatchfield Matchfield { get; set; }
+
+ ///
+ /// Workaround: Ameise schematisch mahlen
+ ///
+ /// die aktuelle Blickrichtung
+ /// Start X
+ /// Start Y
+ /// Breite
+ /// Höhe
+ /// Leinwand
+ private void drawAntAt(Outlook outlook, float x, float y, float width, float height, ICanvas canvas)
+ {
+ var antHeight = 2 * height / 3;
+ var antWidth = 2* width / 3;
+ var heightMargin = (height - antHeight ) / 2;
+ var xStart = 0F;
+ var yStart = 0F;
+ var xEnd = 0F;
+ var yEnd = 0F;
+
+ canvas.StrokeColor = Colors.OrangeRed;
+
+ if (outlook == Outlook.East || outlook == Outlook.West)
+ {
+ xStart = x + heightMargin;
+ yStart = y + height / 2;
+ xEnd = x + height - heightMargin;
+ yEnd = y + height / 2;
+ }
+ else
+ {
+ xStart = x + width / 2;
+ yStart = y + heightMargin;
+ xEnd = x + width / 2;
+ yEnd = y + height - heightMargin;
+ }
+ canvas.DrawLine(xStart, yStart, xEnd, yEnd);
+ if(outlook == Outlook.East || outlook == Outlook.South)
+ canvas.DrawCircle(xEnd, yEnd, 1.5F);
+ else
+ canvas.DrawCircle(xStart, yStart, 1.5F);
+ }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/ViewModels/DashboardViewModel.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/ViewModels/DashboardViewModel.cs
new file mode 100644
index 0000000..192bed9
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/ViewModels/DashboardViewModel.cs
@@ -0,0 +1,24 @@
+using LangtonAnt.backend;
+
+namespace LangtonAnt.ViewModels;
+///
+/// MVVM-ViewModel für das Dasbord
+///
+internal class DashboardViewModel : BaseViewModel
+{
+ ///
+ /// Initialisiert die MVVM-Commands und das LangtonAnt-Feld
+ ///
+ public void Initialize()
+ {
+ Title = "LangtonAnt Dashboard";
+ Data = new Matchfield();
+ LoadDataCommand = new Command(() => Data.StartIteractions());
+ SaveAsFileCommand = new Command(() => { Data.StopIteractions(); Data.SaveToFile("LangtonAnt.cache.txt"); });
+ LoadFromFileCommand = new Command(() => { Data.StopIteractions(); Data.LoadFromFile("LangtonAnt.cache.txt"); });
+ }
+ public IMatchfield Data { get; private set; }
+ public Command SaveAsFileCommand { get; private set; }
+ public Command LoadFromFileCommand { get; private set; }
+
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/Matchfield.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/Matchfield.cs
new file mode 100644
index 0000000..76895f1
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/Matchfield.cs
@@ -0,0 +1,264 @@
+using System.Collections;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+
+namespace LangtonAnt.backend;
+///
+/// Die Langton Ameise Backend
+/// das ist die Implementierung der haupt-Komponente des Backends
+/// Projekt: Langton's Ant Assessment
+/// Autor: Petar Peev i.A. von Oliver Arentzen, advastore SE
+///
+internal class Matchfield : NotificationBase, IMatchfield
+{
+ #region private members
+ private System.Timers.Timer procesTimer;
+ private int _edgeLenght;
+ private CellAddress _antStartPosition;
+ private Outlook _antCurrentOutlook;
+ private Outlook _antStartOutlook;
+ private int _movesCount;
+ private int _delayTime;
+ private int _currentMove;
+ private string _currentResult;
+ private BitArray _grid;
+ private CellAddress _currentAntPosition;
+
+ #endregion
+
+ #region initial values
+ const int InitialEdgeLenght = 20;
+ const Outlook InitialAntStartOutlook = Outlook.East;
+ const int InitialMovesCount = 500;
+ const int IntialDelayTime = 500;
+ #endregion
+
+ ///
+ /// Konstruktor
+ /// Lädt die Standardwerte aus der Initialkonstanten
+ ///
+ public Matchfield()
+ {
+ _edgeLenght = InitialEdgeLenght;
+ _antCurrentOutlook = InitialAntStartOutlook;
+ _antStartOutlook = InitialAntStartOutlook;
+ _movesCount= InitialMovesCount;
+ _delayTime = IntialDelayTime;
+ }
+
+ #region properties
+
+ ///
+ /// die Kantenlänge des Feldes
+ /// wird initaliziert duch die Konstante InitialEdgeLenght
+ /// die Veränderung des Eigenschafts führt zu eine neue Initializierung des Feldes
+ ///
+ public int EdgeLenght { get => _edgeLenght; set { if (_edgeLenght != value) SetValueAndRefresh(ref _edgeLenght, value); } }
+ ///
+ /// die Startposition der Ameise
+ /// wird initaliziert duch das Helfte der Kantenlänge
+ ///
+ public CellAddress AnpStartPosition { get => _antStartPosition; set { if (_antStartPosition != value) SetProperty(ref _antStartPosition, value); } }
+ ///
+ /// die Start-Blickrichtung der Ameise
+ /// wird initaliziert duch Konstante InitialAntStartOutlook
+ /// die Veränderung des Eigenschafts führt zu eine neue Initializierung des Feldes
+ ///
+ public Outlook AntStartOutlook { get => _antStartOutlook; set { if (_antStartOutlook != value) { AntCurrentOutlook = value; SetValueAndRefresh(ref _antStartOutlook, value); } } }
+ ///
+ /// die aktelle Blickrichtung der Ameise
+ /// aktualisiert sich nach jedem Zug
+ ///
+ public Outlook AntCurrentOutlook { get => _antCurrentOutlook; set { if (_antCurrentOutlook != value) SetProperty(ref _antCurrentOutlook, value); } }
+ ///
+ /// die maximale Anzahl der Züge
+ /// wird initaliziert duch Konstante InitialMovesCount
+ /// die Veränderung des Eigenschafts führt zu eine neue Initializierung des Feldes
+ /// nach dem Erreichen des Wertes werden die Iterationen angehalten
+ ///
+ public int MaxMovesCount { get => _movesCount; set { if (_movesCount != value) SetValueAndRefresh(ref _movesCount, value); } }
+ ///
+ /// die aktelle Anzahl der Züge
+ /// aktualisiert sich nach jedem Zug
+ ///
+ public int CurrentMovesCount { get => _currentMove; set { if (_currentMove != value) SetProperty(ref _currentMove, value); } }
+ ///
+ ///die Zuggeschwindigkeit in Milisecons
+ /// wird initaliziert duch Konstante IntialDelayTime
+ /// die Veränderung des Eigenschafts führt zu eine neue Initializierung des Feldes
+ ///
+ public int DelayTime { get => _delayTime; set { if (_delayTime != value) SetValueAndRefresh(ref _delayTime, value); } }
+ ///
+ /// die Ausgabe des Backend
+ /// aktualisiert sich nach jedem Zug
+ ///
+ public string CurrentResult { get => _currentResult; set { SetProperty(ref _currentResult, value); } }
+ ///
+ /// die die aktuelle Position der Ameise
+ /// aktualisiert sich nach jedem Zug
+ ///
+ public CellAddress CurrentAntPosition { get => _currentAntPosition; set { SetProperty(ref _currentAntPosition, value); } }
+ ///
+ /// eine Liste alle möglichen Blickrichtungen
+ ///
+ public ObservableCollection OutlookItems { get; private set; } = new ObservableCollection(Enum.GetNames(typeof(Outlook)));
+ ///
+ /// die aktelle Blickrichtung der Ameise als string
+ ///
+ public string AntSelectedStartOutlook { get => Enum.GetName(typeof(Outlook), _antStartOutlook); set { AntStartOutlook = (Outlook)Enum.Parse(typeof(Outlook), value); } }
+ ///
+ /// Kalkuliert den aktuellen Grid-Index
+ ///
+ private int _currentGridIndex => _currentAntPosition.Row * _edgeLenght + _currentAntPosition.Column;
+ #endregion
+
+ ///
+ /// Initializiert das Feld, aktualisiert die Startposition und startet die Iterationen (die Züge)
+ ///
+ public void StartIteractions()
+ {
+ procesTimer?.Stop();
+ Task.Delay(TimeSpan.FromSeconds(1));
+ CurrentMovesCount = 0;
+ CurrentAntPosition = new CellAddress { Column = _edgeLenght / 2, Row = _edgeLenght / 2 };
+ AnpStartPosition = new CellAddress { Column = _edgeLenght / 2, Row = _edgeLenght / 2 };
+ _grid = new BitArray(_edgeLenght * _edgeLenght);
+ StartTimeTicker();
+ RaisePropertyChanged(nameof(CurrentResult));
+ }
+ ///
+ /// Haltet die Züge an
+ ///
+ public void StopIteractions()
+ {
+ procesTimer?.Stop();
+ }
+ ///
+ /// Speichert die aktuelle Ausgabe in einer text-Datei in der AppDataDirectory
+ ///
+ /// Der Dateiname
+ public async void SaveToFile(string fileName)
+ {
+ try
+ {
+ await FileHelper.WriteTextFile(Path.Combine(FileSystem.Current.AppDataDirectory, fileName), CurrentResult);
+ }
+ catch (Exception exception)
+ {
+ Debug.WriteLine(exception.Message);
+ // ToDo: Error handling like LocalNotificationCenter.Current.Show(request);
+ //throw new IOException(exception.Message);
+ }
+ }
+ ///
+ /// Lädt die gespeicherte Ausgabe aus einer text-Datei aus der AppDataDirectory
+ ///
+ /// Der Dateiname
+ public async void LoadFromFile(string fileName)
+ {
+ try
+ {
+ var filePath = Path.Combine(FileSystem.Current.AppDataDirectory, fileName);
+ if (FileHelper.FileExists(filePath))
+ CurrentResult = await FileHelper.ReadTextFile(filePath);
+ }
+ catch (Exception exception)
+ {
+ Debug.WriteLine(exception.Message);
+ // ToDo: Error handling like LocalNotificationCenter.Current.Show(request);
+ //throw new IOException(exception.Message);
+ }
+ }
+
+ #region private methods
+ ///
+ /// Setzt das Vert eines Eigenschafts und initiliziert des Feldes neu
+ ///
+ /// der Typ der Eigenschafts
+ /// die Eigenschaft
+ /// das Wert zum Speichern
+ private void SetValueAndRefresh(ref T field, T value)
+ {
+ SetProperty(ref field, value);
+ StartIteractions();
+ }
+ ///
+ /// Initialisiert der Timer und startet die Züge
+ ///
+ private void StartTimeTicker()
+ {
+ if (procesTimer != null)
+ procesTimer.Elapsed -= ProcesTimer_Elapsed;
+
+ procesTimer = new System.Timers.Timer(_delayTime);
+ procesTimer.Elapsed += ProcesTimer_Elapsed;
+ procesTimer.AutoReset = true;
+ procesTimer.Enabled = true;
+ }
+ ///
+ /// Time-Ticks handler
+ ///
+ /// die Teimer-Komponente
+ /// Time-Tick Argumente
+ private void ProcesTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
+ {
+ Debug.WriteLine(DateTime.Now.ToLongTimeString());
+ moveNext();
+ if (_currentMove >= _movesCount) procesTimer.Stop();
+ }
+ ///
+ /// Macht den neuen Zug:
+ /// - Ermitelt die neue Blickrichtung
+ /// - Ändert die Farbe der aktuellen Zelle
+ /// - Erhöht die Anzahl der Züge
+ /// - Setzt die neue Position der Ameise
+ /// - Aktualisiert die Ausgabe
+ ///
+ private void moveNext()
+ {
+ CurrentMovesCount++;
+ if(_currentGridIndex >= 0 && _currentGridIndex < _grid.Length)
+ {
+ // Farbe ändern
+ var currentCell = _grid[_currentGridIndex];
+ _grid[_currentGridIndex] = !currentCell;
+ // Position ermitteln
+ switch (_antCurrentOutlook)
+ {
+ case Outlook.North:
+ AntCurrentOutlook = currentCell ? Outlook.West : Outlook.East;
+ _currentAntPosition.Column += currentCell ? -1 : 1;
+ break;
+ case Outlook.East:
+ AntCurrentOutlook = currentCell ? Outlook.North : Outlook.South;
+ _currentAntPosition.Row += currentCell ? -1 : 1;
+ break;
+ case Outlook.South:
+ AntCurrentOutlook = currentCell ? Outlook.East : Outlook.West;
+ _currentAntPosition.Column += currentCell ? 1 : -1;
+ break;
+ case Outlook.West:
+ AntCurrentOutlook = currentCell ? Outlook.South : Outlook.North;
+ _currentAntPosition.Row += currentCell ? 1 : -1;
+ break;
+ default:
+ break;
+ }
+ // Schutz für die Grenz-Fälle
+ _currentAntPosition.Row = Math.Max(0, _currentAntPosition.Row);
+ _currentAntPosition.Column = Math.Max(0, _currentAntPosition.Column);
+ // Ausgabe aktualisieren
+ var toString = string.Join(",", _grid.Cast().Select(b => b ? "s" : "w"));
+ CurrentResult = toString.Insert(_currentGridIndex * 2 + 1, GetAntOutlookAsChar());
+ }
+ }
+ ///
+ /// Hilfsmethode. Konwertiert die aktuelle Blickrichtung in Char (n, o, s, w) DE-Lokalization
+ ///
+ /// Blickrichtung als Char
+ private string GetAntOutlookAsChar()
+ {
+ return Enum.GetName(typeof(Outlook), _antCurrentOutlook).ToLower().Replace("east", "ost").FirstOrDefault().ToString();
+ }
+ #endregion
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/CellAddress.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/CellAddress.cs
new file mode 100644
index 0000000..271aaed
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/CellAddress.cs
@@ -0,0 +1,10 @@
+
+namespace LangtonAnt.backend;
+///
+/// Klasse für die Adresszelle
+///
+internal class CellAddress
+{
+ public int Row { get; set; }
+ public int Column { get; set; }
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/Enums.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/Enums.cs
new file mode 100644
index 0000000..63c2f46
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/Enums.cs
@@ -0,0 +1,11 @@
+namespace LangtonAnt.backend;
+///
+/// Blickrichtungen als Enum
+///
+enum Outlook
+{
+ North,
+ East,
+ South,
+ West,
+}
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/FileHelper.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/FileHelper.cs
new file mode 100644
index 0000000..34c8987
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/FileHelper.cs
@@ -0,0 +1,44 @@
+namespace LangtonAnt.backend;
+///
+/// Die Langton Ameise
+/// Hilfsklasse für File-IO
+/// Projekt: Langton's Ant Assessment
+/// Autor: Petar Peev i.A. von Oliver Arentzen, advastore SE
+///
+internal static class FileHelper
+{
+ ///
+ /// Lädt den Inhalt einer Textdatei
+ ///
+ /// Path zu der Datei
+ ///
+ public static async Task ReadTextFile(string filePath)
+ {
+ using Stream fileStream = System.IO.File.OpenRead(filePath);
+ using StreamReader reader = new StreamReader(fileStream);
+ return await reader.ReadToEndAsync();
+ }
+ ///
+ /// Speichert ein Text-Konten als Text-Datei
+ ///
+ /// Path zu der Datei
+ /// Text-Kontent
+ ///
+ public static async Task WriteTextFile(string filePath, string content)
+ {
+ using Stream fileStream = System.IO.File.OpenWrite(filePath);
+ using StreamWriter writer = new StreamWriter(fileStream);
+ await writer.WriteAsync(content);
+ await writer.FlushAsync();
+ }
+ ///
+ /// Check ob eine Datei existiert
+ ///
+ /// Path zu der Datei
+ /// Treu fals die Datei existiert
+ public static bool FileExists(string filePath)
+ {
+ return System.IO.File.Exists(filePath);
+ }
+}
+
diff --git a/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/IMatchfield.cs b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/IMatchfield.cs
new file mode 100644
index 0000000..9b0a205
--- /dev/null
+++ b/katas/LangtonAnt/solutions/petar.peev/LangtonAnt/backend/base/IMatchfield.cs
@@ -0,0 +1,27 @@
+using System.ComponentModel;
+
+namespace LangtonAnt.backend;
+///
+/// Die Langton Ameise Backend
+/// das Interface der haupt-Komponente des Backends
+/// Realisiert die Entkoppelung der Komponenten
+/// Projekt: Langton's Ant Assessment
+/// Autor: Petar Peev i.A. von Oliver Arentzen, advastore SE
+///
+internal interface IMatchfield
+{
+ int EdgeLenght { get; set; }
+ CellAddress AnpStartPosition { get; set; }
+ CellAddress CurrentAntPosition { get; set; }
+ Outlook AntCurrentOutlook { get; set; }
+ int MaxMovesCount { get; set; }
+ int CurrentMovesCount { get; set; }
+ int DelayTime { get; set; }
+ string CurrentResult { get; }
+ void StartIteractions();
+ void StopIteractions();
+ void SaveToFile(string fileName);
+ void LoadFromFile(string fileName);
+
+ event PropertyChangedEventHandler PropertyChanged;
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/App.xaml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/App.xaml
new file mode 100644
index 0000000..380fec4
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/App.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/App.xaml.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/App.xaml.cs
new file mode 100644
index 0000000..7169606
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/App.xaml.cs
@@ -0,0 +1,11 @@
+namespace StrangeChessboard;
+
+public partial class App : Application
+{
+ public App()
+ {
+ InitializeComponent();
+
+ MainPage = new AppShell();
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/AppShell.xaml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/AppShell.xaml
new file mode 100644
index 0000000..923cc49
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/AppShell.xaml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/AppShell.xaml.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/AppShell.xaml.cs
new file mode 100644
index 0000000..bb4f2f7
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/AppShell.xaml.cs
@@ -0,0 +1,9 @@
+namespace StrangeChessboard;
+
+public partial class AppShell : Shell
+{
+ public AppShell()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MainPage.xaml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MainPage.xaml
new file mode 100644
index 0000000..f26bea7
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MainPage.xaml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MainPage.xaml.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MainPage.xaml.cs
new file mode 100644
index 0000000..d2337f8
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MainPage.xaml.cs
@@ -0,0 +1,53 @@
+using StrangeChessboard.StrangeChessboard;
+using System.Diagnostics;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace StrangeChessboard;
+
+public partial class MainPage : ContentPage
+{
+ int count = 0;
+
+ public MainPage()
+ {
+ InitializeComponent();
+ }
+
+ private void OnCounterClicked(object sender, EventArgs e)
+ {
+ var test = new Solution();
+ test.Initialize();
+ var result = test.Calculate();
+ ShowResult(test, result);
+ }
+
+ private void BoardBtn_Generic_Clicked(object sender, EventArgs e)
+ {
+ int.TryParse(this.Range.Text, out var range);
+ if(range > 0) {
+ try
+ {
+ var test = new Solution();
+ test.Initialize(range);
+ var result = test.Calculate();
+ ShowResult(test, result);
+ }
+ catch (Exception ex)
+ {
+ labelResult.Text = ex.Message;
+ labelCheck.Text = "";
+ labelColumns.Text = "";
+ labelRows.Text = "";
+ }
+ }
+ }
+
+ private void ShowResult(Solution test, (int,int) result)
+ {
+ labelResult.Text = $"{result.Item1.ToString()} + {result.Item2.ToString()} = {(result.Item1 + result.Item2).ToString()}";
+ labelCheck.Text = (test.ColumnItems.ToArray().Sum() * test.RowItems.ToArray().Sum()).ToString();
+ labelColumns.Text = $"[{string.Join(",", test.ColumnItems)}]";
+ labelRows.Text = $"[{string.Join(",", test.RowItems)}]";
+ }
+}
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MauiProgram.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MauiProgram.cs
new file mode 100644
index 0000000..991e696
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/MauiProgram.cs
@@ -0,0 +1,24 @@
+using Microsoft.Extensions.Logging;
+
+namespace StrangeChessboard;
+
+public static class MauiProgram
+{
+ public static MauiApp CreateMauiApp()
+ {
+ var builder = MauiApp.CreateBuilder();
+ builder
+ .UseMauiApp()
+ .ConfigureFonts(fonts =>
+ {
+ fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
+ fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
+ });
+
+#if DEBUG
+ builder.Logging.AddDebug();
+#endif
+
+ return builder.Build();
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/AndroidManifest.xml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/AndroidManifest.xml
new file mode 100644
index 0000000..e9937ad
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/MainActivity.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/MainActivity.cs
new file mode 100644
index 0000000..f5dbb43
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/MainActivity.cs
@@ -0,0 +1,10 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+
+namespace StrangeChessboard;
+
+[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
+public class MainActivity : MauiAppCompatActivity
+{
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/MainApplication.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/MainApplication.cs
new file mode 100644
index 0000000..e5288fe
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/MainApplication.cs
@@ -0,0 +1,15 @@
+using Android.App;
+using Android.Runtime;
+
+namespace StrangeChessboard;
+
+[Application]
+public class MainApplication : MauiApplication
+{
+ public MainApplication(IntPtr handle, JniHandleOwnership ownership)
+ : base(handle, ownership)
+ {
+ }
+
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/Resources/values/colors.xml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/Resources/values/colors.xml
new file mode 100644
index 0000000..c04d749
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Android/Resources/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #512BD4
+ #2B0B98
+ #2B0B98
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/AppDelegate.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/AppDelegate.cs
new file mode 100644
index 0000000..6d3c0a9
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/AppDelegate.cs
@@ -0,0 +1,9 @@
+using Foundation;
+
+namespace StrangeChessboard;
+
+[Register("AppDelegate")]
+public class AppDelegate : MauiUIApplicationDelegate
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/Info.plist b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/Info.plist
new file mode 100644
index 0000000..c96dd0a
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/Info.plist
@@ -0,0 +1,30 @@
+
+
+
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/appicon.appiconset
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/Program.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/Program.cs
new file mode 100644
index 0000000..f629307
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/MacCatalyst/Program.cs
@@ -0,0 +1,15 @@
+using ObjCRuntime;
+using UIKit;
+
+namespace StrangeChessboard;
+
+public class Program
+{
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, typeof(AppDelegate));
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Tizen/Main.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Tizen/Main.cs
new file mode 100644
index 0000000..5d02c35
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Tizen/Main.cs
@@ -0,0 +1,16 @@
+using System;
+using Microsoft.Maui;
+using Microsoft.Maui.Hosting;
+
+namespace StrangeChessboard;
+
+class Program : MauiApplication
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+
+ static void Main(string[] args)
+ {
+ var app = new Program();
+ app.Run(args);
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Tizen/tizen-manifest.xml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Tizen/tizen-manifest.xml
new file mode 100644
index 0000000..3558267
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Tizen/tizen-manifest.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ maui-appicon-placeholder
+
+
+
+
+ http://tizen.org/privilege/internet
+
+
+
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/App.xaml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/App.xaml
new file mode 100644
index 0000000..edc9446
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/App.xaml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/App.xaml.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/App.xaml.cs
new file mode 100644
index 0000000..9565ee4
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/App.xaml.cs
@@ -0,0 +1,24 @@
+using Microsoft.UI.Xaml;
+
+// To learn more about WinUI, the WinUI project structure,
+// and more about our project templates, see: http://aka.ms/winui-project-info.
+
+namespace StrangeChessboard.WinUI;
+
+///
+/// Provides application-specific behavior to supplement the default Application class.
+///
+public partial class App : MauiWinUIApplication
+{
+ ///
+ /// Initializes the singleton application object. This is the first line of authored code
+ /// executed, and as such is the logical equivalent of main() or WinMain().
+ ///
+ public App()
+ {
+ this.InitializeComponent();
+ }
+
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/Package.appxmanifest b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/Package.appxmanifest
new file mode 100644
index 0000000..c44213c
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/Package.appxmanifest
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+ $placeholder$
+ User Name
+ $placeholder$.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/app.manifest b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/app.manifest
new file mode 100644
index 0000000..e28e6b5
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/Windows/app.manifest
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ true/PM
+ PerMonitorV2, PerMonitor
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/AppDelegate.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/AppDelegate.cs
new file mode 100644
index 0000000..6d3c0a9
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/AppDelegate.cs
@@ -0,0 +1,9 @@
+using Foundation;
+
+namespace StrangeChessboard;
+
+[Register("AppDelegate")]
+public class AppDelegate : MauiUIApplicationDelegate
+{
+ protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/Info.plist b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/Info.plist
new file mode 100644
index 0000000..0004a4f
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ LSRequiresIPhoneOS
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/appicon.appiconset
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/Program.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/Program.cs
new file mode 100644
index 0000000..f629307
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Platforms/iOS/Program.cs
@@ -0,0 +1,15 @@
+using ObjCRuntime;
+using UIKit;
+
+namespace StrangeChessboard;
+
+public class Program
+{
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, typeof(AppDelegate));
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Properties/launchSettings.json b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Properties/launchSettings.json
new file mode 100644
index 0000000..edf8aad
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Windows Machine": {
+ "commandName": "MsixPackage",
+ "nativeDebugging": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/AppIcon/appicon.svg b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/AppIcon/appicon.svg
new file mode 100644
index 0000000..9d63b65
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/AppIcon/appicon.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/AppIcon/appiconfg.svg b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/AppIcon/appiconfg.svg
new file mode 100644
index 0000000..21dfb25
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/AppIcon/appiconfg.svg
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Fonts/OpenSans-Regular.ttf b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Fonts/OpenSans-Regular.ttf
new file mode 100644
index 0000000..e248a95
Binary files /dev/null and b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Fonts/OpenSans-Regular.ttf differ
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Fonts/OpenSans-Semibold.ttf b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Fonts/OpenSans-Semibold.ttf
new file mode 100644
index 0000000..dbc9572
Binary files /dev/null and b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Fonts/OpenSans-Semibold.ttf differ
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Images/dotnet_bot.svg b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Images/dotnet_bot.svg
new file mode 100644
index 0000000..abfaff2
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Images/dotnet_bot.svg
@@ -0,0 +1,93 @@
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Raw/AboutAssets.txt b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Raw/AboutAssets.txt
new file mode 100644
index 0000000..15d6244
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Raw/AboutAssets.txt
@@ -0,0 +1,15 @@
+Any raw assets you want to be deployed with your application can be placed in
+this directory (and child directories). Deployment of the asset to your application
+is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
+
+
+
+These files will be deployed with you package and will be accessible using Essentials:
+
+ async Task LoadMauiAsset()
+ {
+ using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
+ using var reader = new StreamReader(stream);
+
+ var contents = reader.ReadToEnd();
+ }
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Splash/splash.svg b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Splash/splash.svg
new file mode 100644
index 0000000..21dfb25
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Splash/splash.svg
@@ -0,0 +1,8 @@
+
+
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Styles/Colors.xaml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Styles/Colors.xaml
new file mode 100644
index 0000000..245758b
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Styles/Colors.xaml
@@ -0,0 +1,44 @@
+
+
+
+
+ #512BD4
+ #DFD8F7
+ #2B0B98
+ White
+ Black
+ #E1E1E1
+ #C8C8C8
+ #ACACAC
+ #919191
+ #6E6E6E
+ #404040
+ #212121
+ #141414
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #F7B548
+ #FFD590
+ #FFE5B9
+ #28C2D1
+ #7BDDEF
+ #C3F2F4
+ #3E8EED
+ #72ACF1
+ #A7CBF6
+
+
\ No newline at end of file
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Styles/Styles.xaml b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Styles/Styles.xaml
new file mode 100644
index 0000000..dc4a034
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/Resources/Styles/Styles.xaml
@@ -0,0 +1,405 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard.csproj b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard.csproj
new file mode 100644
index 0000000..450857b
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard.csproj
@@ -0,0 +1,55 @@
+
+
+
+ net7.0-android;net7.0-ios;net7.0-maccatalyst
+ $(TargetFrameworks);net7.0-windows10.0.19041.0
+
+
+ Exe
+ StrangeChessboard
+ true
+ true
+ enable
+
+
+ StrangeChessboard
+
+
+ com.companyname.strangechessboard
+ e90aed66-6a42-4983-b6fb-e69bae5142f7
+
+
+ 1.0
+ 1
+
+ 11.0
+ 13.1
+ 21.0
+ 10.0.17763.0
+ 10.0.17763.0
+ 6.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard.sln b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard.sln
new file mode 100644
index 0000000..90ecda6
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard.sln
@@ -0,0 +1,27 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31611.283
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StrangeChessboard", "StrangeChessboard.csproj", "{0AF5ACE3-3A8A-47E5-9AB2-1695BFBF294C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0AF5ACE3-3A8A-47E5-9AB2-1695BFBF294C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AF5ACE3-3A8A-47E5-9AB2-1695BFBF294C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0AF5ACE3-3A8A-47E5-9AB2-1695BFBF294C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {0AF5ACE3-3A8A-47E5-9AB2-1695BFBF294C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0AF5ACE3-3A8A-47E5-9AB2-1695BFBF294C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0AF5ACE3-3A8A-47E5-9AB2-1695BFBF294C}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
+ EndGlobalSection
+EndGlobal
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard/ArrayExtensions.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard/ArrayExtensions.cs
new file mode 100644
index 0000000..feb20ee
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard/ArrayExtensions.cs
@@ -0,0 +1,17 @@
+namespace StrangeChessboard.StrangeChessboard;
+///
+/// Helper-Klasse für das Ermitteln von Gerade und Ungerade Items einer Liste
+///
+internal static class ArrayExtensions
+{
+ // Ungerade Items
+ internal static int[] GetOddItems(this int[] original)
+ {
+ return original.Where((iten, index) => index % 2 != 0).ToArray();
+ }
+ // Gerade Items
+ internal static int[] GetRegularItems(this int[] original)
+ {
+ return original.Where((iten, index) => index % 2 == 0).ToArray();
+ }
+}
diff --git a/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard/Solution.cs b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard/Solution.cs
new file mode 100644
index 0000000..045e697
--- /dev/null
+++ b/katas/StrangeChessboard/solutions/petar.peev/StrangeChessboard/StrangeChessboard/Solution.cs
@@ -0,0 +1,71 @@
+
+using System.Diagnostics;
+
+namespace StrangeChessboard.StrangeChessboard;
+///
+/// Das seltsame Schachbrett Implementationsklasse
+/// Projekt: Langton's Ant Assessment
+/// Autor: Petar Peev i.A. von Oliver Arentzen, advastore SE
+///
+internal class Solution
+{
+ #region private members
+ private const int _maxRange = 3000;
+ private int[] _columnItems, _rowItems;
+ #endregion
+
+ ///
+ /// Initializiert neue Reihenhöhen und Spaltenbreiten für das Schachbrett
+ ///
+ /// Spalten/Reihen- Anzahl des Tests
+ /// Es wird ein OutOfRange generiert falls die Spaltenanzahl größer als 3000 ins
+ public void Initialize(int rangeSize)
+ {
+ if (rangeSize <= 0 || rangeSize > _maxRange) throw new ArgumentOutOfRangeException(nameof(rangeSize));
+ _columnItems = new int[rangeSize];
+ _rowItems = new int[rangeSize];
+ var random = new Random();
+ for (int i = 0; i < _columnItems.Length; i++) { _columnItems[i] = random.Next(1, 10); _rowItems[i] = random.Next(1, 10); }
+ }
+ ///
+ /// Initializiert das Beispiel aus der Aufgabe-Seite zur Kontrolle
+ ///
+ public void Initialize()
+ {
+ _columnItems = new int[] { 3, 1, 2, 7, 1 };
+ _rowItems = new int[] { 1, 8, 4, 5, 2 };
+ }
+ ///
+ /// Kalkuliert die weiße und die schwarze Flächen
+ ///
+ /// Kalkulationsresult als Tupel
+ public (int,int) Calculate()
+ {
+ var whiteArea = AccumulateMultiple(_columnItems.GetRegularItems(), _rowItems.GetRegularItems()) +
+ AccumulateMultiple(_columnItems.GetOddItems(), _rowItems.GetOddItems());
+
+ var blackArea = AccumulateMultiple(_columnItems.GetRegularItems(), _rowItems.GetOddItems()) +
+ AccumulateMultiple(_columnItems.GetOddItems(), _rowItems.GetRegularItems());
+
+ // Denbug-Check ToDo: Löschen
+ Debug.Assert(whiteArea + blackArea == _columnItems.ToArray().Sum() * _rowItems.ToArray().Sum(), "Calculation is Ok");
+
+ return (whiteArea, blackArea);
+ }
+ public int[] ColumnItems => _columnItems;
+ public int[] RowItems => _rowItems;
+ ///
+ /// Kalkuliert die Fläche aus der eingegebenen Breiten/Höhen (volle Schleife)
+ ///
+ ///
+ ///
+ ///
+ private int AccumulateMultiple(IEnumerable columns, IEnumerable rows)
+ {
+ var sum = 0;
+ foreach (var column in columns)
+ foreach (var row in rows)
+ sum += column * row;
+ return sum;
+ }
+}