diff --git a/.github/workflows/CSharpBible.yml b/.github/workflows/CSharpBible.yml
index a601fb628..80e82e2a4 100644
--- a/.github/workflows/CSharpBible.yml
+++ b/.github/workflows/CSharpBible.yml
@@ -1,115 +1,51 @@
-# This workflow uses actions that are not certified by GitHub.
-# They are provided by a third-party and are governed by
-# separate terms of service, privacy policy, and support
-# documentation.
-
-# This workflow will build, test, sign and package a WPF or Windows Forms desktop application
-# built on .NET Core.
-# To learn how to migrate your existing application to .NET Core,
-# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework
-#
-# To configure this workflow:
-#
-# 1. Configure environment variables
-# GitHub sets default environment variables for every workflow run.
-# Replace the variables relative to your project in the "env" section below.
-#
-# 2. Signing
-# Generate a signing certificate in the Windows Application
-# Packaging Project or add an existing signing certificate to the project.
-# Next, use PowerShell to encode the .pfx file using Base64 encoding
-# by running the following Powershell script to generate the output string:
-#
-# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
-# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'
-#
-# Open the output file, SigningCertificate_Encoded.txt, and copy the
-# string inside. Then, add the string to the repo as a GitHub secret
-# and name it "Base64_Encoded_Pfx."
-# For more information on how to configure your signing certificate for
-# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing
-#
-# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key".
-# See "Build the Windows Application Packaging project" below to see how the secret is used.
-#
-# For more information on GitHub Actions, refer to https://github.com/features/actions
-# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
-# refer to https://github.com/microsoft/github-actions-for-desktop-apps
-
-name: .NET Core Desktop
+name: CSharpBible CI3
on:
push:
- branches: [ "master" ]
+ paths:
+ - "CSharpBible/**"
pull_request:
- branches: [ "master" ]
+ paths:
+ - "CSharpBible/**"
jobs:
-
- build:
-
- strategy:
- matrix:
- configuration: [Debug, Release]
-
- runs-on: windows-latest # For a list of available runner types, refer to
- # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
-
- env:
- Solution_Name: CSharpBible.sln # Replace with your solution name, i.e. MyWpfApp.sln.
- Test_Project_Path: Tests\Test.csproj # Replace with the path to your test project, i.e. MyWpfApp.Tests\MyWpfApp.Tests.csproj.
- Wap_Project_Directory: CSharpBible # Replace with the Wap project directory relative to the solution, i.e. MyWpfApp.Package.
- Wap_Project_Path: CSharpBible # Replace with the path to your Wap project, i.e. MyWpf.App.Package\MyWpfApp.Package.wapproj.
-
+ build-test:
+ runs-on: windows-latest
+ defaults:
+ run:
+ working-directory: CSharpBible
steps:
- - name: Checkout
- uses: actions/checkout@v3
- with:
- fetch-depth: 0
-
- # Install the .NET Core workload
- - name: Install .NET Core
- uses: actions/setup-dotnet@v3
- with:
- dotnet-version: 6.0.x
-
- # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
- - name: Setup MSBuild.exe
- uses: microsoft/setup-msbuild@v1.0.2
-
- # Execute all unit tests in the solution
- - name: Execute unit tests
- run: dotnet test
-
- # Restore the application to populate the obj folder with RuntimeIdentifiers
- - name: Restore the application
- run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
- env:
- Configuration: ${{ matrix.configuration }}
-
- # Decode the base 64 encoded pfx and save the Signing_Certificate
- - name: Decode the pfx
- run: |
- $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}")
- $certificatePath = Join-Path -Path $env:Wap_Project_Directory -ChildPath GitHubActionsWorkflow.pfx
- [IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte)
-
- # Create the app package by building and packaging the Windows Application Packaging project
- - name: Create the app package
- run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }}
- env:
- Appx_Bundle: Always
- Appx_Bundle_Platforms: x86|x64
- Appx_Package_Build_Mode: StoreUpload
- Configuration: ${{ matrix.configuration }}
-
- # Remove the pfx
- - name: Remove the pfx
- run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx
-
- # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact
- - name: Upload build artifacts
- uses: actions/upload-artifact@v3
- with:
- name: MSIX Package
- path: ${{ env.Wap_Project_Directory }}\AppPackages
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup .NET 8.0
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: "8.0.x"
+
+ - name: Remove private projects
+ run: |
+ dotnet sln CSharpBible.sln remove "Mobile/MauiApp1/MauiApp1.csproj"
+ dotnet sln CSharpBible.sln remove "Simulation/AGVFktTests/AGVFktTests.csproj"
+ dotnet sln CSharpBible.sln remove "Simulation/AGVFkt/AGVFkt.csproj"
+ dotnet sln CSharpBible.sln remove "DB/ADO_Test/ADO_Test.csproj"
+ dotnet sln CSharpBible.sln remove "Libraries/CSFreeVision_/CSFreeVision.csproj"
+ dotnet sln CSharpBible.sln remove "Mobile/DXMauiApp1/DXMauiApp1.csproj"
+ dotnet sln CSharpBible.sln remove "Web/MyComponent/Client/MyComponent.Client.csproj"
+ dotnet sln CSharpBible.sln remove "Web/MyComponent/Server/MyComponent.Server.csproj"
+ dotnet sln CSharpBible.sln remove "Web/MyComponent/Shared/MyComponent.csproj"
+ dotnet sln CSharpBible.sln remove "WinUI/App1/App1/App1.csproj"
+ dotnet sln CSharpBible.sln remove "App2/App2.csproj"
+ dotnet sln CSharpBible.sln remove "../PackageDwnLd.csproj"
+ dotnet sln CSharpBible.sln remove "Web/BlazorApp1/BlazorApp1.csproj"
+ dotnet sln CSharpBible.sln remove "Web/WebApp1/BlazorApp2/BlazorApp2.csproj"
+ dotnet sln CSharpBible.sln remove "Web/WebApp1/WebApplication1/WebApplication1/WebApplication1.csproj"
+
+ - name: Restore
+ run: dotnet restore CSharpBible.sln -p:TargetFramework=net8.0-windows
+
+ - name: Build
+ run: dotnet build CSharpBible.sln --configuration Release --no-restore -p:TargetFramework=net8.0-windows
+
+ - name: Test
+ run: dotnet test CSharpBible.sln --configuration Release --no-build --verbosity normal -p:TargetFramework=net8.0-windows
diff --git a/.github/workflows/Teststatements.yml b/.github/workflows/Teststatements.yml
new file mode 100644
index 000000000..ec5a8018d
--- /dev/null
+++ b/.github/workflows/Teststatements.yml
@@ -0,0 +1,35 @@
+name: TestStatemens CI0
+
+on:
+ push:
+ paths:
+ - "TestStatements/**"
+ pull_request:
+ paths:
+ - "TestStatements/**"
+
+jobs:
+ build-test:
+ runs-on: windows-latest
+ defaults:
+ run:
+ working-directory: TestStatements
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup .NET 8.0
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: "8.0.x"
+
+ - name: Remove private projects
+ run: |
+
+ - name: Restore
+ run: dotnet restore TestStatements.sln -p:TargetFramework=net8.0-windows
+
+ - name: Build
+ run: dotnet build TestStatements.sln --configuration Release --no-restore -p:TargetFramework=net8.0-windows
+ - name: Test
+ run: dotnet test TestStatements.sln --configuration Release --no-build --verbosity normal -p:TargetFramework=net8.0-windows
diff --git a/.gitignore b/.gitignore
index 9c1706033..0b4b38c24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.vs
+.gitignore
bin
obj
*.db
@@ -24,7 +25,7 @@ obj
/CSharpBible/Libraries/CSFreeVision_
/CSharpBible/Libraries/MathLibraryTests/TestResults
/CSharpBible/Graphics/PermutationTests/TestResults
-/CSharpBible/MVVM_Tutorial/UWP_00_Test
+/CSharpBible/MVVM_Tutorial
/CSharpBible/WinUI/App1
/TestStatements/Help
/CSharpBible/Games/SharpHack.Wpf/tiles.png
diff --git a/Avalonia_Apps/Libraries/BaseLib/Interfaces/IConsole.cs b/Avalonia_Apps/Libraries/BaseLib/Interfaces/IConsole.cs
index 709b8e83c..51a405c64 100644
--- a/Avalonia_Apps/Libraries/BaseLib/Interfaces/IConsole.cs
+++ b/Avalonia_Apps/Libraries/BaseLib/Interfaces/IConsole.cs
@@ -149,6 +149,7 @@ public interface IConsole
/// The next line of characters from the input stream, or an empty string if no input is available.
///
string ReadLine();
+ void ResetColor();
///
/// Sets the position of the cursor within the console buffer.
diff --git a/Avalonia_Apps/Libraries/BaseLib/Models/ConsoleProxy.cs b/Avalonia_Apps/Libraries/BaseLib/Models/ConsoleProxy.cs
index 62bba77c8..0b2ee1214 100644
--- a/Avalonia_Apps/Libraries/BaseLib/Models/ConsoleProxy.cs
+++ b/Avalonia_Apps/Libraries/BaseLib/Models/ConsoleProxy.cs
@@ -6,57 +6,62 @@ namespace BaseLib.Models;
public class ConsoleProxy : IConsole
{
- MethodInfo _writeLineS = typeof(Console).GetMethod(nameof(Console.WriteLine), [typeof(string)])!;
- MethodInfo _beep = typeof(Console).GetMethod(nameof(Console.Beep), [typeof(int), typeof(int)])!;
+ protected MethodInfo _writeLineS = typeof(Console).GetMethod(nameof(Console.WriteLine), [typeof(string)])!;
+ protected MethodInfo _beep = typeof(Console).GetMethod(nameof(Console.Beep), [typeof(int), typeof(int)])!;
#if NET5_0_OR_GREATER
- MethodInfo _GetCursorPosition = typeof(Console).GetMethod(nameof(Console.GetCursorPosition), [])!;
+ protected MethodInfo _GetCursorPosition = typeof(Console).GetMethod(nameof(Console.GetCursorPosition), [])!;
#else
- MethodInfo _CursorLeft = typeof(Console).GetMethod(nameof(Console.CursorLeft), [])!;
- MethodInfo _CursorTop = typeof(Console).GetMethod(nameof(Console.CursorTop), [])!;
+ protected MethodInfo _CursorLeft = typeof(Console).GetMethod(nameof(Console.CursorLeft), [])!;
+ protected MethodInfo _CursorTop = typeof(Console).GetMethod(nameof(Console.CursorTop), [])!;
#endif
- MethodInfo _ReadKey = typeof(Console).GetMethod(nameof(Console.ReadKey), [])!;
- MethodInfo _Readline = typeof(Console).GetMethod(nameof(Console.ReadLine), [])!;
- MethodInfo _setCursorPosition = typeof(Console).GetMethod(nameof(Console.SetCursorPosition), [typeof(int), typeof(int)])!;
- MethodInfo _writeCh = typeof(Console).GetMethod(nameof(Console.Write), [typeof(char)])!;
- MethodInfo _writeS = typeof(Console).GetMethod(nameof(Console.Write), [typeof(string)])!;
- MethodInfo _clear = typeof(Console).GetMethod(nameof(Console.Clear), [])!;
-
- PropertyInfo _ForegroundColor = typeof(Console).GetProperty(nameof(Console.ForegroundColor))!;
- PropertyInfo _BackgroundColor = typeof(Console).GetProperty(nameof(Console.BackgroundColor))!;
- PropertyInfo _IsOutputRedirected = typeof(Console).GetProperty(nameof(Console.IsOutputRedirected))!;
- PropertyInfo _KeyAvailable = typeof(Console).GetProperty(nameof(Console.KeyAvailable))!;
- PropertyInfo _LargestWindowHeight = typeof(Console).GetProperty(nameof(Console.LargestWindowHeight))!;
- PropertyInfo _Title = typeof(Console).GetProperty(nameof(Console.Title))!;
- PropertyInfo _WindowHeight = typeof(Console).GetProperty(nameof(Console.WindowHeight))!;
- PropertyInfo _WindowWidth = typeof(Console).GetProperty(nameof(Console.WindowWidth))!;
- PropertyInfo _CursorVisible = typeof(Console).GetProperty(nameof(Console.CursorVisible))!;
- PropertyInfo _BufferWidth = typeof(Console).GetProperty(nameof(Console.BufferWidth))!;
- PropertyInfo _BufferHeight = typeof(Console).GetProperty(nameof(Console.BufferHeight))!;
-
- public ConsoleColor ForegroundColor { get => _ForegroundColor?.GetValue(null) as ConsoleColor? ?? ConsoleColor.White; set => _ForegroundColor?.SetValue(null,value); }
- public ConsoleColor BackgroundColor { get => _BackgroundColor?.GetValue(null) as ConsoleColor? ?? ConsoleColor.Black; set => _BackgroundColor?.SetValue(null, value); }
- public bool IsOutputRedirected => _IsOutputRedirected?.GetValue(null) as bool? ?? false;
- public bool KeyAvailable => _KeyAvailable?.GetValue(null) as bool? ?? false;
- public int LargestWindowHeight => _LargestWindowHeight?.GetValue(null) as int? ?? 0;
- public string Title { get => _Title?.GetValue(null) as string ?? string.Empty; set => _Title?.SetValue(null, value); }
- public int WindowHeight { get => _WindowHeight?.GetValue(null) as int? ?? 0; set => _WindowHeight?.SetValue(null, value); }
- public int WindowWidth { get => _WindowWidth?.GetValue(null) as int? ?? 0; set => _WindowWidth?.SetValue(null, value); }
- public bool CursorVisible { get => _CursorVisible?.GetValue(null) as bool? ?? false; set => _CursorVisible?.SetValue(null, value); }
- public int BufferWidth => _BufferWidth?.GetValue(null) as int? ?? 0;
- public int BufferHeight => _BufferHeight?.GetValue(null) as int? ?? 0;
-
-
- public void Beep(int freq, int len) => _beep?.Invoke(null, [freq, len]);
- public void Clear() => _clear?.Invoke(null, []);
+ protected MethodInfo _ReadKey = typeof(Console).GetMethod(nameof(Console.ReadKey), [])!;
+ protected MethodInfo _Readline = typeof(Console).GetMethod(nameof(Console.ReadLine), [])!;
+ protected MethodInfo _setCursorPosition = typeof(Console).GetMethod(nameof(Console.SetCursorPosition), [typeof(int), typeof(int)])!;
+ protected MethodInfo _writeCh = typeof(Console).GetMethod(nameof(Console.Write), [typeof(char)])!;
+ protected MethodInfo _writeS = typeof(Console).GetMethod(nameof(Console.Write), [typeof(string)])!;
+ protected MethodInfo _clear = typeof(Console).GetMethod(nameof(Console.Clear), [])!;
+ protected MethodInfo _resetColor = typeof(Console).GetMethod(nameof(Console.ResetColor), [])!;
+
+ protected PropertyInfo _ForegroundColor = typeof(Console).GetProperty(nameof(Console.ForegroundColor))!;
+ protected PropertyInfo _BackgroundColor = typeof(Console).GetProperty(nameof(Console.BackgroundColor))!;
+ protected PropertyInfo _IsOutputRedirected = typeof(Console).GetProperty(nameof(Console.IsOutputRedirected))!;
+ protected PropertyInfo _KeyAvailable = typeof(Console).GetProperty(nameof(Console.KeyAvailable))!;
+ protected PropertyInfo _LargestWindowHeight = typeof(Console).GetProperty(nameof(Console.LargestWindowHeight))!;
+ protected PropertyInfo _Title = typeof(Console).GetProperty(nameof(Console.Title))!;
+ protected PropertyInfo _WindowHeight = typeof(Console).GetProperty(nameof(Console.WindowHeight))!;
+ protected PropertyInfo _WindowWidth = typeof(Console).GetProperty(nameof(Console.WindowWidth))!;
+ protected PropertyInfo _CursorVisible = typeof(Console).GetProperty(nameof(Console.CursorVisible))!;
+ protected PropertyInfo _BufferWidth = typeof(Console).GetProperty(nameof(Console.BufferWidth))!;
+ protected PropertyInfo _BufferHeight = typeof(Console).GetProperty(nameof(Console.BufferHeight))!;
+
+ protected object? instance = default;
+ public ConsoleColor ForegroundColor { get => _ForegroundColor?.GetValue(instance) as ConsoleColor? ?? ConsoleColor.White; set => _ForegroundColor?.SetValue(instance,value); }
+ public ConsoleColor BackgroundColor { get => _BackgroundColor?.GetValue(instance) as ConsoleColor? ?? ConsoleColor.Black; set => _BackgroundColor?.SetValue(instance, value); }
+ public bool IsOutputRedirected => _IsOutputRedirected?.GetValue(instance) as bool? ?? false;
+ public bool KeyAvailable => _KeyAvailable?.GetValue(instance) as bool? ?? false;
+ public int LargestWindowHeight => _LargestWindowHeight?.GetValue(instance) as int? ?? 0;
+ public string Title { get => _Title?.GetValue(instance) as string ?? string.Empty; set => _Title?.SetValue(instance, value); }
+ public int WindowHeight { get => _WindowHeight?.GetValue(instance) as int? ?? 0; set => _WindowHeight?.SetValue(instance, value); }
+ public int WindowWidth { get => _WindowWidth?.GetValue(instance) as int? ?? 0; set => _WindowWidth?.SetValue(instance, value); }
+ public bool CursorVisible { get => _CursorVisible?.GetValue(instance) as bool? ?? false; set => _CursorVisible?.SetValue(instance, value); }
+ public int BufferWidth => _BufferWidth?.GetValue(instance) as int? ?? 0;
+ public int BufferHeight => _BufferHeight?.GetValue(instance) as int? ?? 0;
+
+
+ public void Beep(int freq, int len) => _beep?.Invoke(instance, [freq, len]);
+ public void Clear() => _clear?.Invoke(instance, []);
#if NET5_0_OR_GREATER
- public (int Left, int Top) GetCursorPosition() => _GetCursorPosition?.Invoke(null, []) as (int, int)? ?? (0, 0);
+ public (int Left, int Top) GetCursorPosition() => _GetCursorPosition?.Invoke(instance, []) as (int, int)? ?? (0, 0);
#else
- public (int Left, int Top) GetCursorPosition() => (_CursorLeft?.Invoke(null, []) as int? ?? 0, _CursorTop?.Invoke(null, []) as int? ?? 0);
+ public (int Left, int Top) GetCursorPosition() => (_CursorLeft?.Invoke(instance, []) as int? ?? 0, _CursorTop?.Invoke(instance, []) as int? ?? 0);
#endif
- public ConsoleKeyInfo? ReadKey() => _ReadKey?.Invoke(null, []) as ConsoleKeyInfo?;
- public string ReadLine() => _Readline?.Invoke(null, [])?.ToString() ?? string.Empty;
- public void SetCursorPosition(int left, int top) => _setCursorPosition?.Invoke(null, [left, top]);
- public void Write(char ch) => _writeCh?.Invoke(null, [ch]);
- public void Write(string? st) => _writeS?.Invoke(null, [st]);
- public void WriteLine(string? v) => _writeLineS?.Invoke(null, [v]);
+ public ConsoleKeyInfo? ReadKey() => _ReadKey?.Invoke(instance, []) as ConsoleKeyInfo?;
+ public string ReadLine() => _Readline?.Invoke(instance, [])?.ToString() ?? string.Empty;
+
+ public void ResetColor() => _resetColor?.Invoke(instance, []);
+
+ public void SetCursorPosition(int left, int top) => _setCursorPosition?.Invoke(instance, [left, top]);
+ public void Write(char ch) => _writeCh?.Invoke(instance, [ch]);
+ public void Write(string? st) => _writeS?.Invoke(instance, [st]);
+ public void WriteLine(string? v) => _writeLineS?.Invoke(instance, [v]);
}
diff --git a/CSharpBible/CSharpBible.sln b/CSharpBible/CSharpBible.sln
index 2eaf51596..7b314ff76 100644
--- a/CSharpBible/CSharpBible.sln
+++ b/CSharpBible/CSharpBible.sln
@@ -427,7 +427,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MVVM_00_TemplateTests", "MV
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MVVM_06_Converters_4_net", "MVVM_Tutorial\MVVM_06_Converters_4\MVVM_06_Converters_4_net.csproj", "{70AD3FCB-F529-4E08-BE39-E56C940EA114}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MVVM_16_Usercontrol1_net", "MVVM_Tutorial\MVVM_16_Usercontrol1\MVVM_16_Usercontrol1_net.csproj", "{CDC8B1F7-3C94-4686-9EE0-6841231E6144}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MVVM_16_Usercontrol1_net", "MVVM_Tutorial\MVVM_16_Usercontrol1\MVVM_16_UserControl1_net.csproj", "{CDC8B1F7-3C94-4686-9EE0-6841231E6144}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Simulation", "Simulation", "{0DF8EC71-8008-41CF-9A87-946604FBD24D}"
ProjectSection(SolutionItems) = preProject
diff --git a/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.cs b/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.cs
index cea8ad438..0005b7e9c 100644
--- a/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.cs
+++ b/CSharpBible/ConsoleApps/TestConsoleTests/TestConsoleTests.cs
@@ -144,7 +144,7 @@ public void ReadKeyTest()
///
/// Defines the test method SetCursorPositionTest.
///
- [DataTestMethod()]
+ [TestMethod()]
[DataRow("0,0",0,0)]
[DataRow("0,1", 0, 1)]
[DataRow("1,0", 1, 0)]
diff --git a/CSharpBible/Games/Arkanoid.Base/Arkanoid.Base.csproj b/CSharpBible/Games/Arkanoid.Base/Arkanoid.Base.csproj
index 28ead3f4a..1705ad3c5 100644
--- a/CSharpBible/Games/Arkanoid.Base/Arkanoid.Base.csproj
+++ b/CSharpBible/Games/Arkanoid.Base/Arkanoid.Base.csproj
@@ -15,5 +15,10 @@
$(TargetFrameworks);net10.0
+
+
+
+
+
diff --git a/CSharpBible/Games/Arkanoid.Base/GameEngine.cs b/CSharpBible/Games/Arkanoid.Base/GameEngine.cs
index d728522cf..ac6cb6a0c 100644
--- a/CSharpBible/Games/Arkanoid.Base/GameEngine.cs
+++ b/CSharpBible/Games/Arkanoid.Base/GameEngine.cs
@@ -4,15 +4,42 @@
namespace Arkanoid.Base;
+///
+/// Provides the core game loop mechanics for the Arkanoid-style game,
+/// including state updates, collision handling, and level setup.
+///
+///
+/// This engine operates on a simple fixed-field coordinate system and updates
+/// the in-place. It is intentionally lightweight and
+/// deterministic for predictable gameplay behavior.
+///
public class GameEngine
{
+ ///
+ /// Gets the current mutable game state, including ball, paddle, bricks, score, and lives.
+ ///
public GameState State { get; } = new();
+ ///
+ /// Initializes a new instance of the class
+ /// and creates the default level layout.
+ ///
public GameEngine()
{
CreateDefaultLevel();
}
+ ///
+ /// Moves the paddle horizontally according to player input and elapsed time.
+ ///
+ ///
+ /// The horizontal input direction, typically in the range [-1, 1],
+ /// where negative values move left and positive values move right.
+ ///
+ /// The elapsed time since the last update, in seconds.
+ ///
+ /// The paddle position is clamped so it cannot leave the horizontal bounds of the field.
+ ///
public void MovePaddle(float direction, float deltaTime)
{
var dx = State.Paddle.Speed * direction * deltaTime;
@@ -20,6 +47,14 @@ public void MovePaddle(float direction, float deltaTime)
State.Paddle.Position = new Vector2(newX, State.Paddle.Position.Y);
}
+ ///
+ /// Advances the simulation by the specified time step.
+ ///
+ /// The elapsed time since the last update, in seconds.
+ ///
+ /// If the game is over, no further updates are performed.
+ /// This method updates the ball position and resolves collisions.
+ ///
public void Update(float deltaTime)
{
if (State.IsGameOver) return;
@@ -31,6 +66,16 @@ public void Update(float deltaTime)
HandleCollisions();
}
+ ///
+ /// Detects and resolves collisions between the ball and walls, paddle, and bricks.
+ ///
+ ///
+ /// - Wall collisions reflect velocity components as needed.
+ /// - Falling below the field reduces lives and resets the ball and paddle.
+ /// - Paddle collisions reflect the ball upward when moving downward.
+ /// - Brick collisions reflect vertical velocity and reduce hit points for breakable bricks.
+ /// - If all bricks are destroyed, the game ends.
+ ///
private void HandleCollisions()
{
var b = State.Ball;
@@ -86,6 +131,12 @@ private void HandleCollisions()
State.IsGameOver = true;
}
+ ///
+ /// Resets the paddle and ball to their default starting positions and velocity.
+ ///
+ ///
+ /// This is invoked after losing a life or when initializing a level.
+ ///
private void ResetBallAndPaddle()
{
State.Paddle.Position = new Vector2(State.FieldWidth / 2 - State.Paddle.Width / 2, State.FieldHeight - 2);
@@ -93,6 +144,13 @@ private void ResetBallAndPaddle()
State.Ball.Velocity = new Vector2(15, -20);
}
+ ///
+ /// Creates the default level layout consisting of a rectangular grid of bricks.
+ ///
+ ///
+ /// The layout uses a fixed number of rows and columns and distributes bricks evenly
+ /// across the field width. All bricks are initialized as breakable with one hit point.
+ ///
private void CreateDefaultLevel()
{
State.Bricks.Clear();
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/Ball.cs b/CSharpBible/Games/Arkanoid.Base/Models/Ball.cs
new file mode 100644
index 000000000..fef28322d
--- /dev/null
+++ b/CSharpBible/Games/Arkanoid.Base/Models/Ball.cs
@@ -0,0 +1,34 @@
+namespace Arkanoid.Base.Models;
+///
+/// The ball object in the Arkanoid game.
+///
+///
+public class Ball : IGameObject
+{
+ ///
+ /// Gets or sets the current world-space position of the ball in game units.
+ ///
+ ///
+ /// The position represents the center of the ball and is typically updated each frame
+ /// based on and elapsed time.
+ ///
+ public Vector2 Position { get; set; } = new(10, 10);
+
+ ///
+ /// Gets or sets the linear velocity of the ball in game units per second.
+ ///
+ ///
+ /// Positive X moves the ball to the right, and positive Y moves it upward, assuming a
+ /// conventional Cartesian coordinate system.
+ ///
+ public Vector2 Velocity { get; set; } = new(10, -10); // units per second
+
+ ///
+ /// Gets or sets the radius of the ball in game units.
+ ///
+ ///
+ /// The radius is used for collision detection and rendering. The ball's diameter is
+ /// 2 * Radius.
+ ///
+ public float Radius { get; set; } = 0.5f;
+}
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/Brick.cs b/CSharpBible/Games/Arkanoid.Base/Models/Brick.cs
new file mode 100644
index 000000000..4dcd6b7a1
--- /dev/null
+++ b/CSharpBible/Games/Arkanoid.Base/Models/Brick.cs
@@ -0,0 +1,51 @@
+namespace Arkanoid.Base.Models;
+
+///
+/// Represents a single brick in the game arena, including its position, size, type,
+/// durability, and destruction state.
+///
+///
+/// A brick can be breakable or unbreakable depending on its . The
+/// value defines how many hits are required to destroy it.
+/// The property reflects whether the brick should be
+/// considered removed from play.
+///
+public class Brick : IGameObject
+{
+ ///
+ /// Gets or sets the top-left position of the brick in world coordinates.
+ ///
+ public Vector2 Position { get; set; } = new(0, 0);
+
+ ///
+ /// Gets or sets the width of the brick in world units.
+ ///
+ public float Width { get; set; } = 3f;
+
+ ///
+ /// Gets or sets the height of the brick in world units.
+ ///
+ public float Height { get; set; } = 1f;
+
+ ///
+ /// Gets or sets the brick's type, which determines its behavior (e.g., breakable or unbreakable).
+ ///
+ public BrickType Type { get; set; }
+
+ ///
+ /// Gets or sets the current hit points of the brick.
+ ///
+ ///
+ /// When this value reaches zero or below, the brick is considered destroyed
+ /// unless it is of type .
+ ///
+ public int HitPoints { get; set; } = 1;
+
+ ///
+ /// Gets a value indicating whether the brick is destroyed and should be removed from play.
+ ///
+ ///
+ /// Unbreakable bricks are never destroyed even if is zero or negative.
+ ///
+ public bool IsDestroyed => HitPoints <= 0 && Type != BrickType.Unbreakable;
+}
\ No newline at end of file
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/BrickType.cs b/CSharpBible/Games/Arkanoid.Base/Models/BrickType.cs
new file mode 100644
index 000000000..f7f21c797
--- /dev/null
+++ b/CSharpBible/Games/Arkanoid.Base/Models/BrickType.cs
@@ -0,0 +1,23 @@
+namespace Arkanoid.Base.Models;
+
+///
+/// Defines the available brick categories used by the game logic, rendering, and collision handling
+/// to determine durability and behavior when hit by a ball.
+///
+public enum BrickType
+{
+ ///
+ /// A standard brick that is destroyed after a single hit.
+ ///
+ Normal,
+
+ ///
+ /// A reinforced brick that requires multiple hits to break.
+ ///
+ Strong,
+
+ ///
+ /// An indestructible brick that never breaks when hit.
+ ///
+ Unbreakable
+}
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/GameObjects.cs b/CSharpBible/Games/Arkanoid.Base/Models/GameObjects.cs
deleted file mode 100644
index e28600a7e..000000000
--- a/CSharpBible/Games/Arkanoid.Base/Models/GameObjects.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Collections.Generic;
-
-namespace Arkanoid.Base.Models;
-
-public enum BrickType
-{
- Normal,
- Strong,
- Unbreakable
-}
-
-public record Vector2(float X, float Y);
-
-public class Paddle
-{
- public Vector2 Position { get; set; } = new(10, 20);
- public float Width { get; set; } = 6f;
- public float Speed { get; set; } = 25f; // units per second
-}
-
-public class Ball
-{
- public Vector2 Position { get; set; } = new(10, 10);
- public Vector2 Velocity { get; set; } = new(10, -10); // units per second
- public float Radius { get; set; } = 0.5f;
-}
-
-public class Brick
-{
- public Vector2 Position { get; set; }
- public float Width { get; set; } = 3f;
- public float Height { get; set; } = 1f;
- public BrickType Type { get; set; }
- public int HitPoints { get; set; } = 1;
- public bool IsDestroyed => HitPoints <= 0 && Type != BrickType.Unbreakable;
-}
-
-public class GameState
-{
- public Paddle Paddle { get; } = new();
- public Ball Ball { get; } = new();
- public List Bricks { get; } = new();
- public int Score { get; set; }
- public int Lives { get; set; } = 3;
- public float FieldWidth { get; set; } = 80;
- public float FieldHeight { get; set; } = 40;
- public bool IsGameOver { get; set; }
-}
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/GameState.cs b/CSharpBible/Games/Arkanoid.Base/Models/GameState.cs
new file mode 100644
index 000000000..0ee604c9f
--- /dev/null
+++ b/CSharpBible/Games/Arkanoid.Base/Models/GameState.cs
@@ -0,0 +1,83 @@
+namespace Arkanoid.Base.Models;
+
+///
+/// Represents the complete mutable state of an Arkanoid game session, including
+/// player control, ball physics, level geometry, scoring, and terminal flags.
+///
+///
+/// This type is intended to be the single source of truth for the game loop,
+/// allowing rendering and simulation to read and update a unified model.
+///
+public class GameState
+{
+ ///
+ /// Gets the player's paddle, which is responsible for reflecting the ball.
+ ///
+ ///
+ /// The paddle position and size are typically updated by player input and
+ /// used during collision checks with the ball.
+ ///
+ public Paddle Paddle { get; } = new();
+
+ ///
+ /// Gets the active ball instance used for movement, collisions, and scoring.
+ ///
+ ///
+ /// The ball's position and velocity are advanced each tick of the game loop
+ /// and are evaluated against the field bounds, paddle, and bricks.
+ ///
+ public Ball Ball { get; } = new();
+
+ ///
+ /// Gets the collection of bricks currently present in the playfield.
+ ///
+ ///
+ /// Bricks are typically removed when hit by the ball and may contribute
+ /// to the score or trigger power-ups in extended implementations.
+ ///
+ public List Bricks { get; } = new();
+
+ ///
+ /// Gets or sets the player's current score.
+ ///
+ ///
+ /// This value is generally increased when the ball destroys bricks or
+ /// completes objectives, and may be used for high score tracking.
+ ///
+ public int Score { get; set; }
+
+ ///
+ /// Gets or sets the number of remaining lives.
+ ///
+ ///
+ /// A life is typically lost when the ball exits the bottom boundary of the field.
+ /// When this value reaches zero, the game is considered over.
+ ///
+ public int Lives { get; set; } = 3;
+
+ ///
+ /// Gets or sets the width of the playable field in game units.
+ ///
+ ///
+ /// Used to clamp paddle movement and to reflect the ball from the left and right walls.
+ ///
+ public float FieldWidth { get; set; } = 80;
+
+ ///
+ /// Gets or sets the height of the playable field in game units.
+ ///
+ ///
+ /// Used to determine the top boundary for ball reflection and the bottom
+ /// boundary for life loss.
+ ///
+ public float FieldHeight { get; set; } = 40;
+
+ ///
+ /// Gets or sets a value indicating whether the game has ended.
+ ///
+ ///
+ /// This flag is typically set when reaches zero or when
+ /// all bricks have been cleared, depending on game rules.
+ ///
+ public bool IsGameOver { get; set; }
+}
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/IGameObject.cs b/CSharpBible/Games/Arkanoid.Base/Models/IGameObject.cs
new file mode 100644
index 000000000..e9e51160e
--- /dev/null
+++ b/CSharpBible/Games/Arkanoid.Base/Models/IGameObject.cs
@@ -0,0 +1,14 @@
+namespace Arkanoid.Base.Models;
+///
+/// Interface IGameObject
+///
+public interface IGameObject
+{
+ ///
+ /// Gets or sets the position.
+ ///
+ ///
+ /// The position.
+ ///
+ Vector2 Position { get; set; }
+}
\ No newline at end of file
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/Paddle.cs b/CSharpBible/Games/Arkanoid.Base/Models/Paddle.cs
new file mode 100644
index 000000000..60ee3568d
--- /dev/null
+++ b/CSharpBible/Games/Arkanoid.Base/Models/Paddle.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+
+namespace Arkanoid.Base.Models;
+
+///
+/// Represents the player-controlled paddle used to deflect the ball in the game.
+///
+///
+/// The paddle is modeled as a horizontal segment positioned in world coordinates.
+/// Movement is typically constrained to the horizontal axis by input handling elsewhere.
+///
+public class Paddle : IGameObject
+{
+ ///
+ /// Gets or sets the world-space position of the paddle's reference point.
+ ///
+ ///
+ /// The exact interpretation of the reference point (e.g., center or left edge)
+ /// is defined by the rendering and collision systems that consume this model.
+ ///
+ public Vector2 Position { get; set; } = new(10, 20);
+
+ ///
+ /// Gets or sets the paddle width expressed in world units.
+ ///
+ ///
+ /// This value is used for collision checks and rendering to determine the paddle's span.
+ ///
+ public float Width { get; set; } = 6f;
+
+ ///
+ /// Gets or sets the movement speed of the paddle in world units per second.
+ ///
+ ///
+ /// Higher values allow faster horizontal movement when input is applied.
+ ///
+ public float Speed { get; set; } = 25f; // units per second
+}
diff --git a/CSharpBible/Games/Arkanoid.Base/Models/Vector2.cs b/CSharpBible/Games/Arkanoid.Base/Models/Vector2.cs
new file mode 100644
index 000000000..278f9d64a
--- /dev/null
+++ b/CSharpBible/Games/Arkanoid.Base/Models/Vector2.cs
@@ -0,0 +1,14 @@
+namespace Arkanoid.Base.Models;
+
+///
+/// Represents a two-dimensional vector with single-precision floating-point components,
+/// commonly used to describe positions, directions, or sizes in 2D space.
+///
+///
+/// The horizontal component of the vector, where positive values typically indicate movement or offset to the right.
+///
+///
+/// The vertical component of the vector, where positive values typically indicate movement or offset downward in screen space,
+/// depending on the coordinate system used by the game.
+///
+public record Vector2(float X, float Y);
\ No newline at end of file
diff --git a/CSharpBible/Games/Arkanoid.Cons/Arkanoid.Cons.csproj b/CSharpBible/Games/Arkanoid.Cons/Arkanoid.Cons.csproj
index 8118714f1..aeb6601b0 100644
--- a/CSharpBible/Games/Arkanoid.Cons/Arkanoid.Cons.csproj
+++ b/CSharpBible/Games/Arkanoid.Cons/Arkanoid.Cons.csproj
@@ -15,6 +15,11 @@
$(TargetFrameworks);net10.0
+
+
+
+
+
diff --git a/CSharpBible/Games/BoxFlight/ViewModels/BoxFlightViewModel.cs b/CSharpBible/Games/BoxFlight/ViewModels/BoxFlightViewModel.cs
index c729f0bac..68b81a521 100644
--- a/CSharpBible/Games/BoxFlight/ViewModels/BoxFlightViewModel.cs
+++ b/CSharpBible/Games/BoxFlight/ViewModels/BoxFlightViewModel.cs
@@ -36,7 +36,7 @@ public BoxFlightViewModel(IGameWorld world)
{
_world = world;
- int width = 640, height = 360;
+ int width = 1280, height = 720;
Frame = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);
MiniMap = new WriteableBitmap(400, 400, 96, 96, PixelFormats.Bgra32, null);
_render = new RenderEntry[width];
@@ -128,7 +128,7 @@ private void DrawRenderEntries(int bd2)
for (int x = 0; x < _render.Length; x++)
{
var re = _render[x];
- if (re.Height > re.Shad / 2)
+ if (re.Shad !=0 && re.Height > re.Shad / 2)
DrawVLine(buffer, stride, x, bd2 + re.Shad, bd2 + re.Shad / 2, Colors.Black);
int c1 = Math.Clamp(re.Light, 0, 255);
diff --git a/CSharpBible/Games/BoxFlight/World/GameWorld.cs b/CSharpBible/Games/BoxFlight/World/GameWorld.cs
index d93f45ce2..9b352a558 100644
--- a/CSharpBible/Games/BoxFlight/World/GameWorld.cs
+++ b/CSharpBible/Games/BoxFlight/World/GameWorld.cs
@@ -71,17 +71,15 @@ public void Step(int time, bool stereo, int scrollOffset, int focusX, int maxHei
var lCv2 = new Vector(lCv1.Y, -lCv1.X);
_cMove = _cPoint - cMoveOld;
+
_cPoint.X -= Math.Truncate(_cPoint.X / 400.0) * 400.0;
_cPoint.Y -= Math.Truncate(_cPoint.Y / 400.0) * 400.0;
- var sPnt = _cPoint;
- if (stereo) { _cPoint.X += _cView.Y * 0.4; _cPoint.Y += -_cView.X * 0.4; }
- else { _cPoint.X += -_cView.Y * 0.4; _cPoint.Y += _cView.X * 0.4; }
- sPnt.X += _cView.X; sPnt.Y += _cView.Y;
foreach (var o in Objects)
{
- o.Visible = false; o.Hit = false;
+ o.Visible = false;
+ o.Hit = false;
if (o.Size <= 0) continue;
var vp = new Vector(o.Pos.X, o.Pos.Y) + (Vector)_cPoint + new Vector(400, 400);
vp -= new Vector(Math.Floor(vp.X / 400.0) * 400.0, Math.Floor(vp.Y / 400.0) * 400.0);
@@ -95,20 +93,38 @@ public void Step(int time, bool stereo, int scrollOffset, int focusX, int maxHei
o.Visible = vis;
}
+
int half = render.Length / 2;
int hrc2 = half / 2;
int obj = -1;
- for (int j = 0; j < render.Length; j++)
+ Parallel.For (0,render.Length, (j)=>
{
+ var sPnt = _cPoint;
double s, c;
- if (j <= half) { s = Math.Sin((hrc2 - j) * 0.6 / hrc2); c = Math.Cos((hrc2 - j) * 0.6 / hrc2); }
- else { s = Math.Sin((-j + hrc2 * 3) * 0.6 / hrc2); c = Math.Cos((-j + hrc2 * 3) * 0.6 / hrc2); }
+ if (stereo)
+ if (j <= half)
+ {
+ sPnt.X -= _cView.Y * 0.4;
+ sPnt.Y += _cView.X * 0.4;
+ s = Math.Sin((hrc2 - j) * 0.6 / hrc2);
+ c = Math.Cos((hrc2 - j) * 0.6 / hrc2);
+ }
+ else
+ {
+ sPnt.X += _cView.Y * 0.4;
+ sPnt.Y -= _cView.X * 0.4;
+ s = Math.Sin((-j + hrc2 * 3) * 0.6 / hrc2);
+ c = Math.Cos((-j + hrc2 * 3) * 0.6 / hrc2);
+ }
+ else
+ {
+ s = Math.Sin((half - j) * 0.6 / half);
+ c = Math.Cos((half - j) * 0.6 / half);
+ }
var renDir = new Vector(_cView.X * c + _cView.Y * s, -_cView.X * s + _cView.Y * c);
render[j] = Trace(maxHeight, sPnt, obj, renDir, j == focusX);
- }
+ });
- if (stereo) { _cPoint.X += -_cView.Y * 0.8; _cPoint.Y += _cView.X * 0.8; }
- else { _cPoint.X += _cView.Y * 0.8; _cPoint.Y += -_cView.X * 0.8; }
cPoint2 = _cPoint2; cPoint3 = _cPoint3;
}
@@ -118,10 +134,10 @@ private RenderEntry Trace(int maxHeight, Point sPnt, int obj, Vector renDir, boo
float rDistQ, r;
double rDist; double rr = 0; int hObj = obj;
var entry = new RenderEntry { Oo1 = -1, Oo2 = -1, Light = 0, Height = 0, Light2 = 0, Height2 = 0, Shad = 0 };
- if (obj >= 0 && Objects[obj].HitTest(_cPoint, renDir, out rDistQ, out r) && rDistQ > 2 && rDistQ < 300) { rDist = rDistQ; rr = r; }
+ if (obj >= 0 && Objects[obj].HitTest(sPnt, renDir, out rDistQ, out r) && rDistQ > 2 && rDistQ < 300) { rDist = rDistQ; rr = r; }
else { obj = -1; rDist = 300.0; }
- ObjHit(_cPoint, renDir, -1, ref obj, ref rDist, ref rr);
+ ObjHit(sPnt, renDir, -1, ref obj, ref rDist, ref rr);
if (obj >= 0)
{
var o = Objects[obj];
@@ -155,7 +171,8 @@ private RenderEntry Trace(int maxHeight, Point sPnt, int obj, Vector renDir, boo
int lsobj = hObj; double shDist = 300.0; double shRr = 0.0;
ObjHit(sPnt, renDir, -1, ref lsobj, ref shDist, ref shRr);
- if (lsobj >= 0) entry.Shad = (int)(maxHeight / (shDist + 1.0)); else entry.Shad = 0;
+ // if (lsobj >= 0) entry.Shad = (int)(maxHeight / (shDist + 1.0)); else
+ entry.Shad = 0;
return entry;
}
diff --git a/CSharpBible/Games/DetectiveGame.Console/ViewModels/GameViewModel.cs b/CSharpBible/Games/DetectiveGame.Console/ViewModels/GameViewModel.cs
index 68246ebdb..0d211d610 100644
--- a/CSharpBible/Games/DetectiveGame.Console/ViewModels/GameViewModel.cs
+++ b/CSharpBible/Games/DetectiveGame.Console/ViewModels/GameViewModel.cs
@@ -26,7 +26,7 @@ public partial class GameViewModel : ObservableObject, IGameViewModel
[ObservableProperty]
private string _currentTitle = "Detektivspiel";
- public bool CanInteract => _state != null && !_state.Finished;
+ public bool CanInteract => State != null && !State.Finished;
public Action DisplayHelp { get ; set; }
@@ -42,7 +42,8 @@ private void Start()
Players.Clear();
History.Clear();
State = ((IGameSetup)_service).CreateNew(new[] { "Alice", "Bob", "Carol" });
- foreach (var p in _state.Players)
+ if (State != null)
+ foreach (var p in State.Players)
Players.Add(p.Name);
History.Add("Spiel gestartet");
UpdateTitle();
@@ -51,22 +52,22 @@ private void Start()
[RelayCommand(CanExecute = nameof(CanInteract))]
private void Suggest()
{
- if (_state == null) return;
- var cur = State.Players[_state.CurrentPlayerIndex];
- var person = GameData.Persons.First();
- var weapon = GameData.Weapons.First();
- var room = GameData.Rooms.First();
- var sug = _service.MakeSuggestion(_state, cur.Id, person, weapon, room);
- History.Add($"V: {cur.Name}: {person.Name}/{weapon.Name}/{room.Name} -> {(sug.RefutingPlayerId is int id ? $"von {_state.Players.First(p=>p.Id==id).Name}" : "Keiner")}");
+ if (State == null) return;
+ var cur = State.Players[State.CurrentPlayerIndex];
+ var person = GameData.Persons[0];
+ var weapon = GameData.Weapons[0];
+ var room = GameData.Rooms[0];
+ var sug = _service.MakeSuggestion(State, cur.Id, person, weapon, room);
+ History.Add($"V: {cur.Name}: {person.Name}/{weapon.Name}/{room.Name} -> {(sug.RefutingPlayerId is int id ? $"von {State.Players.First(p=>p.Id==id).Name}" : "Keiner")}");
UpdateTitle();
}
[RelayCommand(CanExecute = nameof(CanInteract))]
private void Accuse()
{
- if (_state == null) return;
- var cur = State.Players[_state.CurrentPlayerIndex];
- var ok = _service.MakeAccusation(_state, cur.Id, GameData.Persons.First(), GameData.Weapons.First(), GameData.Rooms.First());
+ if (State == null) return;
+ var cur = State.Players[State.CurrentPlayerIndex];
+ var ok = _service.MakeAccusation(State, cur.Id, GameData.Persons.First(), GameData.Weapons.First(), GameData.Rooms.First());
History.Add(ok ? $"{cur.Name} gewinnt" : $"{cur.Name} falsch (inaktiv)");
UpdateTitle();
}
@@ -90,9 +91,9 @@ private void UpdateTitle()
if (State == null)
CurrentTitle = "Detektivspiel";
else if (State.Finished)
- CurrentTitle = $"Ende – Sieger {_state.WinnerPlayerId}";
+ CurrentTitle = $"Ende – Sieger {State.WinnerPlayerId}";
else
- CurrentTitle = $"Zug: {_state.Players[_state.CurrentPlayerIndex].Name}";
+ CurrentTitle = $"Zug: {State.Players[State.CurrentPlayerIndex].Name}";
}
}
diff --git a/CSharpBible/Games/DetectiveGame.Console/Views/SuggestionDialog.cs b/CSharpBible/Games/DetectiveGame.Console/Views/SuggestionDialog.cs
index da84771cc..89d796b9f 100644
--- a/CSharpBible/Games/DetectiveGame.Console/Views/SuggestionDialog.cs
+++ b/CSharpBible/Games/DetectiveGame.Console/Views/SuggestionDialog.cs
@@ -104,6 +104,6 @@ public void Hide()
public void Show()
{
Visible = true;
- (Parent as IGroupControl).BringToFront(this);
+ (Parent as IGroupControl)?.BringToFront(this);
}
}
diff --git a/CSharpBible/Games/Directory.Packages.props b/CSharpBible/Games/Directory.Packages.props
index eb83fa4d5..56c7ac5db 100644
--- a/CSharpBible/Games/Directory.Packages.props
+++ b/CSharpBible/Games/Directory.Packages.props
@@ -1,7 +1,9 @@
-
+
-
-
+
+
+
+
\ No newline at end of file
diff --git a/CSharpBible/Games/Galaxia_Base/Models/CorActions/DoubleJump.cs b/CSharpBible/Games/Galaxia_Base/Models/CorActions/DoubleJump.cs
index c095cbafe..7f154a09c 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/CorActions/DoubleJump.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/CorActions/DoubleJump.cs
@@ -16,7 +16,7 @@ public class DoubleJump : JumpAction, ICorAction
///
/// Das Ziel-Sternensystem für den Hyperjump.
///
- public IStarsystem TargetStarsystem { get; }
+ public IStarsystem? TargetStarsystem { get; }
///
/// Erstellt eine neue DoubleJump-Aktion.
@@ -24,7 +24,7 @@ public class DoubleJump : JumpAction, ICorAction
/// Die ausführende Corporation.
/// Die springende Flotte.
/// Das Ziel-Sternensystem.
- public DoubleJump(ICorporation corporation, IFleet fleet1, IFleet fleet2, IStarsystem targetStarsystem):base(corporation,fleet1)
+ public DoubleJump(ICorporation corporation, IFleet fleet1, IFleet fleet2, IStarsystem? targetStarsystem):base(corporation,fleet1)
{
Fleet2 = fleet2;
TargetStarsystem = targetStarsystem;
@@ -37,7 +37,7 @@ public DoubleJump(ICorporation corporation, IFleet fleet1, IFleet fleet2, IStars
public override bool Execute()
{
// Überprüfe, ob die Flotte zur Corporation gehört und sich im Hyperspace befindet
- if (Fleet.Owner != Corporation || Fleet.Container is not IHyperSlot hs )
+ if (Fleet?.Owner != Corporation || Fleet.Container is not IHyperSlot hs )
return false;
// Überprüfe, ob die Flotte zur Corporation gehört und sich im Hyperspace befindet
@@ -58,7 +58,7 @@ public override bool Execute()
// Die Flotte verlässt den HyperSlot und wird dem Zielsystem zugewiesen
// Dies kann je nach Implementierung variieren
TargetStarsystem.Sector.SetFleet(Fleet);
- TargetStarsystem.Sector.Fleet.Join(Fleet2);
+ TargetStarsystem.Sector.Fleet?.Join(Fleet2);
TargetStarsystem.SetFleet(Fleet);
return true;
}
diff --git a/CSharpBible/Games/Galaxia_Base/Models/CorActions/EmbarkFleet.cs b/CSharpBible/Games/Galaxia_Base/Models/CorActions/EmbarkFleet.cs
index 11ce31eff..8a3321cbe 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/CorActions/EmbarkFleet.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/CorActions/EmbarkFleet.cs
@@ -25,7 +25,7 @@ public class EmbarkFleet : ICorAction
///
/// Das Sternensystem, aus dem die Flotte startet.
///
- public IStarsystem SourceStarsystem { get; }
+ public IStarsystem? SourceStarsystem { get; }
///
/// Erstellt eine neue EmbarkFleet-Aktion.
@@ -33,7 +33,7 @@ public class EmbarkFleet : ICorAction
/// Die ausführende Corporation.
/// Die einzuschiffende Flotte.
/// Das Start-Sternensystem.
- public EmbarkFleet(ICorporation corporation, IFleet fleet, IStarsystem sourceStarsystem,float fleetSize =0f)
+ public EmbarkFleet(ICorporation corporation, IFleet? fleet, IStarsystem? sourceStarsystem,float fleetSize =0f)
{
Corporation = corporation;
Fleet = fleet;
@@ -52,13 +52,13 @@ public bool Execute()
return false;
// Versuche, die Flotte ins Hyperspace-System einzuschiffen
- if ((FleetSize > 1f) && (Fleet.Size > FleetSize))
+ if ((FleetSize > 1f) && (Fleet!.Size > FleetSize))
{
// Nicht genug Platz in den HyperSlots
- return Corporation.hyperspace.Embark(Fleet.Split(FleetSize));
+ return Corporation.hyperspace.Embark(Fleet.Split(FleetSize)!);
}
else
- return Corporation.hyperspace.Embark(Fleet);
+ return Corporation.hyperspace.Embark(Fleet!);
}
}
}
\ No newline at end of file
diff --git a/CSharpBible/Games/Galaxia_Base/Models/CorActions/JumpAction.cs b/CSharpBible/Games/Galaxia_Base/Models/CorActions/JumpAction.cs
index fd1c80e13..5a07e16ba 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/CorActions/JumpAction.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/CorActions/JumpAction.cs
@@ -1,11 +1,10 @@
using Galaxia.Models.Interfaces;
-namespace Galaxia.Models.CorActions
+namespace Galaxia.Models.CorActions;
+
+public abstract class JumpAction(ICorporation corporation, IFleet? fleet) : ICorAction
{
- public abstract class JumpAction(ICorporation corporation, IFleet? fleet) : ICorAction
- {
- public ICorporation Corporation => corporation;
- public IFleet? Fleet => fleet;
- public abstract bool Execute();
- }
+ public ICorporation Corporation => corporation;
+ public IFleet? Fleet => fleet;
+ public abstract bool Execute();
}
\ No newline at end of file
diff --git a/CSharpBible/Games/Galaxia_Base/Models/CorActions/SingleJump.cs b/CSharpBible/Games/Galaxia_Base/Models/CorActions/SingleJump.cs
index 14e33a12b..221703672 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/CorActions/SingleJump.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/CorActions/SingleJump.cs
@@ -8,20 +8,11 @@ namespace Galaxia.Models.CorActions
///
public class SingleJump : JumpAction, ICorAction
{
- ///
- /// Die Corporation, die die Aktion ausführt.
- ///
- public ICorporation Corporation { get; }
-
- ///
- /// Die Flotte, die den Hyperjump ausführen soll.
- ///
- public IFleet Fleet { get; }
///
/// Das Ziel-Sternensystem für den Hyperjump.
///
- public IStarsystem TargetStarsystem { get; }
+ public IStarsystem? TargetStarsystem { get; }
///
/// Erstellt eine neue SingleJump-Aktion.
@@ -29,7 +20,7 @@ public class SingleJump : JumpAction, ICorAction
/// Die ausführende Corporation.
/// Die springende Flotte.
/// Das Ziel-Sternensystem.
- public SingleJump(ICorporation corporation, IFleet fleet, IStarsystem targetStarsystem):base(corporation,fleet)
+ public SingleJump(ICorporation corporation, IFleet? fleet, IStarsystem? targetStarsystem):base(corporation,fleet)
{
TargetStarsystem = targetStarsystem;
}
@@ -41,7 +32,7 @@ public SingleJump(ICorporation corporation, IFleet fleet, IStarsystem targetStar
public override bool Execute()
{
// Überprüfe, ob die Flotte zur Corporation gehört und sich im Hyperspace befindet
- if (Fleet.Owner != Corporation || Fleet.Container is not IHyperSlot hs )
+ if (Fleet?.Owner != Corporation || Fleet.Container is not IHyperSlot hs )
return false;
// Überprüfe, ob das Zielsystem erreichbar ist (optional, je nach Spielmechanik)
diff --git a/CSharpBible/Games/Galaxia_Base/Models/Corporation.cs b/CSharpBible/Games/Galaxia_Base/Models/Corporation.cs
index 9e1b59929..a924286a8 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/Corporation.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/Corporation.cs
@@ -77,7 +77,7 @@ public IList GetPossibleActions()
// Test if a double jump is possible (2 ships in hyperspace and combined reachable sectors)
if (!Actions.Any(a => a is JumpAction) && hyperspace.CombReachableSectors().Count() > 0)
{
- possibleActions.Add(new DoubleJump(this, hyperspace.HyperSlots[0].Fleet, hyperspace.HyperSlots[1].Fleet, null));
+ possibleActions.Add(new DoubleJump(this, hyperspace.HyperSlots[0].Fleet!, hyperspace.HyperSlots[1].Fleet!, null));
}
// test if a Hyperslot is free or gets free this turn -> Embark is possible
diff --git a/CSharpBible/Games/Galaxia_Base/Models/Interfaces/ICorAction.cs b/CSharpBible/Games/Galaxia_Base/Models/Interfaces/ICorAction.cs
index d93c5e527..ae19db31d 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/Interfaces/ICorAction.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/Interfaces/ICorAction.cs
@@ -7,7 +7,7 @@ public interface ICorAction
///
/// The corporation.
ICorporation Corporation { get; }
- IFleet Fleet { get; }
+ IFleet? Fleet { get; }
///
/// Executes this instance.
diff --git a/CSharpBible/Games/Galaxia_Base/Models/Interfaces/Point3d.cs b/CSharpBible/Games/Galaxia_Base/Models/Interfaces/Point3d.cs
index e24f3e442..da9f03e68 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/Interfaces/Point3d.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/Interfaces/Point3d.cs
@@ -2,9 +2,11 @@
namespace Galaxia.Models.Interfaces;
+#pragma warning disable CS0659 // Typ überschreibt Object.Equals(object o), überschreibt jedoch nicht Object.GetHashCode()
public struct Point3d
+#pragma warning restore CS0659 // Typ überschreibt Object.Equals(object o), überschreibt jedoch nicht Object.GetHashCode()
{
- internal static readonly Point3d Zero;
+ internal static readonly Point3d Zero=new();
public int X { get; }
public int Y { get; }
diff --git a/CSharpBible/Games/Galaxia_Base/Models/Starsystem.cs b/CSharpBible/Games/Galaxia_Base/Models/Starsystem.cs
index d47c69bc5..ad5634c7c 100644
--- a/CSharpBible/Games/Galaxia_Base/Models/Starsystem.cs
+++ b/CSharpBible/Games/Galaxia_Base/Models/Starsystem.cs
@@ -41,7 +41,7 @@ public bool SetFleet(IFleet? fleet)
if (Fleet != null)
{
if (!Fleet.Owner.Stars.Contains(this) && Fleet.Owner.Home != this)
- fleet.Owner.Stars.Remove(this);
+ Fleet.Owner.Stars.Remove(this);
}
Fleet = fleet;
diff --git a/CSharpBible/Games/Game_Base/Game_Base.csproj b/CSharpBible/Games/Game_Base/Game_Base.csproj
index 39198c3b8..e6e47afcc 100644
--- a/CSharpBible/Games/Game_Base/Game_Base.csproj
+++ b/CSharpBible/Games/Game_Base/Game_Base.csproj
@@ -7,7 +7,14 @@
-
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
+
+
+
diff --git a/CSharpBible/Games/Games.sln b/CSharpBible/Games/Games.sln
index 83a20c7ee..af2ac8c9f 100644
--- a/CSharpBible/Games/Games.sln
+++ b/CSharpBible/Games/Games.sln
@@ -252,6 +252,9 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpHack.WPF2D", "SharpHack.WPF2D\SharpHack.WPF2D.csproj", "{9F55A149-DA32-BB7C-D552-73C3ECDF7C8B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestStatements", "TestStatements", "{D44D28AA-A653-4BFC-A3CF-0CC30230A191}"
+ ProjectSection(SolutionItems) = preProject
+ ..\..\TestStatements\Solution_net.props = ..\..\TestStatements\Solution_net.props
+ EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginBase", "..\..\TestStatements\PluginBase\PluginBase.csproj", "{0E45D0C0-4231-737D-1CCF-E1C23B5656E8}"
EndProject
@@ -261,6 +264,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OtherPlugin", "..\..\TestSt
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sokoban.Plugin", "Sokoban.Plugin\Sokoban.Plugin.csproj", "{D193A2C2-F42F-4172-9960-CF81051C12E9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Werner_Flaschbier.Console2", "Werner_Flaschbier.Console2\Werner_Flaschbier.Console2.csproj", "{1895981C-B544-4BE4-EC3C-9B1034F2024E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpHack.View.FirstPerson", "SharpHack.View.FirstPerson\SharpHack.View.FirstPerson.csproj", "{5601DCD5-5E75-9131-38B3-7C6275E4F1BC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpHack.ViewModel.Tests", "SharpHack.ViewModel.Tests\SharpHack.ViewModel.Tests.csproj", "{A49A6D4E-4C50-8328-9779-18BFA42DB0A7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1471,6 +1480,42 @@ Global
{D193A2C2-F42F-4172-9960-CF81051C12E9}.Release|x64.Build.0 = Release|Any CPU
{D193A2C2-F42F-4172-9960-CF81051C12E9}.Release|x86.ActiveCfg = Release|Any CPU
{D193A2C2-F42F-4172-9960-CF81051C12E9}.Release|x86.Build.0 = Release|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Debug|x64.Build.0 = Debug|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Debug|x86.Build.0 = Debug|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Release|x64.ActiveCfg = Release|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Release|x64.Build.0 = Release|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Release|x86.ActiveCfg = Release|Any CPU
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E}.Release|x86.Build.0 = Release|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Debug|x64.Build.0 = Debug|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Debug|x86.Build.0 = Debug|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Release|x64.ActiveCfg = Release|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Release|x64.Build.0 = Release|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Release|x86.ActiveCfg = Release|Any CPU
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC}.Release|x86.Build.0 = Release|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Debug|x64.Build.0 = Debug|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Debug|x86.Build.0 = Debug|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Release|x64.ActiveCfg = Release|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Release|x64.Build.0 = Release|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Release|x86.ActiveCfg = Release|Any CPU
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1564,6 +1609,9 @@ Global
{CE53A7C0-B60F-08B3-1E98-F00307A06E3F} = {D44D28AA-A653-4BFC-A3CF-0CC30230A191}
{E953E2A6-54ED-57D7-8C8C-5FA30B2E58AF} = {D44D28AA-A653-4BFC-A3CF-0CC30230A191}
{D193A2C2-F42F-4172-9960-CF81051C12E9} = {EAA6A4C4-78C2-412B-A322-0D3FA6691D50}
+ {1895981C-B544-4BE4-EC3C-9B1034F2024E} = {7337A459-E02B-4BD0-8271-807FD3E16A1B}
+ {5601DCD5-5E75-9131-38B3-7C6275E4F1BC} = {AC84E02A-08F3-46BF-9672-3BA37D5BB067}
+ {A49A6D4E-4C50-8328-9779-18BFA42DB0A7} = {AC84E02A-08F3-46BF-9672-3BA37D5BB067}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {51252E6F-E712-436A-B391-1C5243F65ABE}
diff --git a/CSharpBible/Games/MidiSwing.MVVM/MidiSwing.MVVM.csproj b/CSharpBible/Games/MidiSwing.MVVM/MidiSwing.MVVM.csproj
index 2f871f341..fb8e4cf3a 100644
--- a/CSharpBible/Games/MidiSwing.MVVM/MidiSwing.MVVM.csproj
+++ b/CSharpBible/Games/MidiSwing.MVVM/MidiSwing.MVVM.csproj
@@ -8,6 +8,13 @@
true
+
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.AI/SharpHack.AI.csproj b/CSharpBible/Games/SharpHack.AI/SharpHack.AI.csproj
index f23578f99..388c0b5aa 100644
--- a/CSharpBible/Games/SharpHack.AI/SharpHack.AI.csproj
+++ b/CSharpBible/Games/SharpHack.AI/SharpHack.AI.csproj
@@ -1,11 +1,27 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+ Sokoban
+ AnyCPU;x64
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.AITests/SharpHack.AITests.csproj b/CSharpBible/Games/SharpHack.AITests/SharpHack.AITests.csproj
index 51aefe53a..59561df96 100644
--- a/CSharpBible/Games/SharpHack.AITests/SharpHack.AITests.csproj
+++ b/CSharpBible/Games/SharpHack.AITests/SharpHack.AITests.csproj
@@ -7,6 +7,12 @@
false
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.Base/Interfaces/IContainerItem.cs b/CSharpBible/Games/SharpHack.Base/Interfaces/IContainerItem.cs
index 6c7e5aff5..dfb7e7c0b 100644
--- a/CSharpBible/Games/SharpHack.Base/Interfaces/IContainerItem.cs
+++ b/CSharpBible/Games/SharpHack.Base/Interfaces/IContainerItem.cs
@@ -1,4 +1,5 @@
using SharpHack.Base.Model;
+using System.Collections.Generic;
namespace SharpHack.Base.Interfaces;
diff --git a/CSharpBible/Games/SharpHack.Base/Interfaces/ICreature.cs b/CSharpBible/Games/SharpHack.Base/Interfaces/ICreature.cs
index 2c16947b4..f7483912d 100644
--- a/CSharpBible/Games/SharpHack.Base/Interfaces/ICreature.cs
+++ b/CSharpBible/Games/SharpHack.Base/Interfaces/ICreature.cs
@@ -1,4 +1,5 @@
using SharpHack.Base.Model;
+using System.Collections.Generic;
namespace SharpHack.Base.Interfaces
{
diff --git a/CSharpBible/Games/SharpHack.Base/Interfaces/IGameObject.cs b/CSharpBible/Games/SharpHack.Base/Interfaces/IGameObject.cs
index 09b930d1e..859fe76e4 100644
--- a/CSharpBible/Games/SharpHack.Base/Interfaces/IGameObject.cs
+++ b/CSharpBible/Games/SharpHack.Base/Interfaces/IGameObject.cs
@@ -1,14 +1,14 @@
using SharpHack.Base.Model;
+using System;
-namespace SharpHack.Base.Interfaces
+namespace SharpHack.Base.Interfaces;
+
+public interface IGameObject
{
- public interface IGameObject
- {
- ConsoleColor Color { get; set; }
- string Description { get; set; }
- Guid Id { get; }
- string Name { get; set; }
- Point Position { get; set; }
- char Symbol { get; set; }
- }
+ ConsoleColor Color { get; set; }
+ string Description { get; set; }
+ Guid Id { get; }
+ string Name { get; set; }
+ Point Position { get; set; }
+ char Symbol { get; set; }
}
\ No newline at end of file
diff --git a/CSharpBible/Games/SharpHack.Base/Interfaces/IGamePersist.cs b/CSharpBible/Games/SharpHack.Base/Interfaces/IGamePersist.cs
index 0d276c4a5..9241642ac 100644
--- a/CSharpBible/Games/SharpHack.Base/Interfaces/IGamePersist.cs
+++ b/CSharpBible/Games/SharpHack.Base/Interfaces/IGamePersist.cs
@@ -1,4 +1,5 @@
using SharpHack.Base.Model;
+using System.Collections.Generic;
namespace SharpHack.Base.Interfaces;
diff --git a/CSharpBible/Games/SharpHack.Base/Interfaces/ITile.cs b/CSharpBible/Games/SharpHack.Base/Interfaces/ITile.cs
index f6acc35bb..8439a162a 100644
--- a/CSharpBible/Games/SharpHack.Base/Interfaces/ITile.cs
+++ b/CSharpBible/Games/SharpHack.Base/Interfaces/ITile.cs
@@ -1,5 +1,6 @@
using SharpHack.Base.Data;
using SharpHack.Base.Model;
+using System.Collections.Generic;
namespace SharpHack.Base.Interfaces;
diff --git a/CSharpBible/Games/SharpHack.Base/SharpHack.Base.csproj b/CSharpBible/Games/SharpHack.Base/SharpHack.Base.csproj
index cd6db5978..49b654132 100644
--- a/CSharpBible/Games/SharpHack.Base/SharpHack.Base.csproj
+++ b/CSharpBible/Games/SharpHack.Base/SharpHack.Base.csproj
@@ -1,8 +1,20 @@
-
-
- net10.0
- enable
- enable
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.BaseCreatures/SharpHack.BaseCreatures.csproj b/CSharpBible/Games/SharpHack.BaseCreatures/SharpHack.BaseCreatures.csproj
index 0401b2193..761cc8606 100644
--- a/CSharpBible/Games/SharpHack.BaseCreatures/SharpHack.BaseCreatures.csproj
+++ b/CSharpBible/Games/SharpHack.BaseCreatures/SharpHack.BaseCreatures.csproj
@@ -1,9 +1,17 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
diff --git a/CSharpBible/Games/SharpHack.BaseItems/SharpHack.BaseItems.csproj b/CSharpBible/Games/SharpHack.BaseItems/SharpHack.BaseItems.csproj
index 15462413b..a7baa2e57 100644
--- a/CSharpBible/Games/SharpHack.BaseItems/SharpHack.BaseItems.csproj
+++ b/CSharpBible/Games/SharpHack.BaseItems/SharpHack.BaseItems.csproj
@@ -1,9 +1,17 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
diff --git a/CSharpBible/Games/SharpHack.BaseItemsTests/SharpHack.BaseItemsTests.csproj b/CSharpBible/Games/SharpHack.BaseItemsTests/SharpHack.BaseItemsTests.csproj
index 7583d6412..d6e9103be 100644
--- a/CSharpBible/Games/SharpHack.BaseItemsTests/SharpHack.BaseItemsTests.csproj
+++ b/CSharpBible/Games/SharpHack.BaseItemsTests/SharpHack.BaseItemsTests.csproj
@@ -1,13 +1,20 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
- false
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
+
diff --git a/CSharpBible/Games/SharpHack.BaseTests/SharpHack.BaseTests.csproj b/CSharpBible/Games/SharpHack.BaseTests/SharpHack.BaseTests.csproj
index 09920bec8..ba89292ed 100644
--- a/CSharpBible/Games/SharpHack.BaseTests/SharpHack.BaseTests.csproj
+++ b/CSharpBible/Games/SharpHack.BaseTests/SharpHack.BaseTests.csproj
@@ -1,13 +1,20 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
- false
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
+
diff --git a/CSharpBible/Games/SharpHack.Combat/SharpHack.Combat.csproj b/CSharpBible/Games/SharpHack.Combat/SharpHack.Combat.csproj
index c9df3d96e..1a62f0f72 100644
--- a/CSharpBible/Games/SharpHack.Combat/SharpHack.Combat.csproj
+++ b/CSharpBible/Games/SharpHack.Combat/SharpHack.Combat.csproj
@@ -1,12 +1,20 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
+
diff --git a/CSharpBible/Games/SharpHack.CombatTests/SharpHack.CombatTests.csproj b/CSharpBible/Games/SharpHack.CombatTests/SharpHack.CombatTests.csproj
index 7be22461d..f483ab9fd 100644
--- a/CSharpBible/Games/SharpHack.CombatTests/SharpHack.CombatTests.csproj
+++ b/CSharpBible/Games/SharpHack.CombatTests/SharpHack.CombatTests.csproj
@@ -1,17 +1,24 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
- false
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
-
-
-
-
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.Engine/GameSession.cs b/CSharpBible/Games/SharpHack.Engine/GameSession.cs
index 64532e06b..f21083acb 100644
--- a/CSharpBible/Games/SharpHack.Engine/GameSession.cs
+++ b/CSharpBible/Games/SharpHack.Engine/GameSession.cs
@@ -5,6 +5,8 @@
using SharpHack.Base.Data;
using SharpHack.Engine.Pathfinding;
using SharpHack.BaseItems.Model;
+using System.Collections.Generic;
+using System;
namespace SharpHack.Engine;
diff --git a/CSharpBible/Games/SharpHack.Engine/Pathfinding/AStarPathfinder.cs b/CSharpBible/Games/SharpHack.Engine/Pathfinding/AStarPathfinder.cs
index d284f6d90..5f27b1810 100644
--- a/CSharpBible/Games/SharpHack.Engine/Pathfinding/AStarPathfinder.cs
+++ b/CSharpBible/Games/SharpHack.Engine/Pathfinding/AStarPathfinder.cs
@@ -14,8 +14,11 @@ public static class AStarPathfinder
{
return null;
}
-
+#if NET5_0_OR_GREATER
var open = new PriorityQueue();
+#else
+ var open = new SimplePriorityQueue();
+#endif
var cameFrom = new Dictionary();
var gScore = new Dictionary
{
diff --git a/CSharpBible/Games/SharpHack.Engine/Pathfinding/SimplePriorityQueue.cs b/CSharpBible/Games/SharpHack.Engine/Pathfinding/SimplePriorityQueue.cs
new file mode 100644
index 000000000..ea4a8c53b
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.Engine/Pathfinding/SimplePriorityQueue.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+
+namespace SharpHack.Engine.Pathfinding;
+
+public class SimplePriorityQueue where TPriority : IComparable
+{
+ private readonly List<(TElement Element, TPriority Priority)> _nodes = new();
+
+ public int Count => _nodes.Count;
+
+ public void Enqueue(TElement element, TPriority priority)
+ {
+ _nodes.Add((element, priority));
+ var i = _nodes.Count - 1;
+ while (i > 0)
+ {
+ var parent = (i - 1) / 2;
+ if (_nodes[parent].Priority.CompareTo(_nodes[i].Priority) <= 0) break;
+ (_nodes[parent], _nodes[i]) = (_nodes[i], _nodes[parent]);
+ i = parent;
+ }
+ }
+
+ public TElement Dequeue()
+ {
+ if (_nodes.Count == 0) throw new InvalidOperationException("Queue ist leer.");
+
+ var result = _nodes[0].Element;
+ _nodes[0] = _nodes[_nodes.Count - 1];
+ _nodes.RemoveAt(_nodes.Count - 1);
+
+ var i = 0;
+ while (true)
+ {
+ var left = i * 2 + 1;
+ var right = i * 2 + 2;
+ var smallest = i;
+
+ if (left < _nodes.Count && _nodes[left].Priority.CompareTo(_nodes[smallest].Priority) < 0)
+ smallest = left;
+ if (right < _nodes.Count && _nodes[right].Priority.CompareTo(_nodes[smallest].Priority) < 0)
+ smallest = right;
+
+ if (smallest == i) break;
+ (_nodes[i], _nodes[smallest]) = (_nodes[smallest], _nodes[i]);
+ i = smallest;
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/CSharpBible/Games/SharpHack.Engine/SharpHack.Engine.csproj b/CSharpBible/Games/SharpHack.Engine/SharpHack.Engine.csproj
index 3447ad059..02a2f09f4 100644
--- a/CSharpBible/Games/SharpHack.Engine/SharpHack.Engine.csproj
+++ b/CSharpBible/Games/SharpHack.Engine/SharpHack.Engine.csproj
@@ -1,16 +1,29 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
-
-
-
-
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
diff --git a/CSharpBible/Games/SharpHack.EngineTests/SharpHack.EngineTests.csproj b/CSharpBible/Games/SharpHack.EngineTests/SharpHack.EngineTests.csproj
index c1fcefb4e..57f9bc0b9 100644
--- a/CSharpBible/Games/SharpHack.EngineTests/SharpHack.EngineTests.csproj
+++ b/CSharpBible/Games/SharpHack.EngineTests/SharpHack.EngineTests.csproj
@@ -1,17 +1,24 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
- false
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
-
-
-
-
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPMapGenerator.cs b/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPMapGenerator.cs
index 33cab31a9..32d5608ab 100644
--- a/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPMapGenerator.cs
+++ b/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPMapGenerator.cs
@@ -6,7 +6,8 @@
using Point = SharpHack.Base.Model.Point;
using SharpHack.Base.Data;
using SharpHack.Base.Interfaces;
-using SharpHack.Engine.Pathfinding; // Resolve ambiguity with System.Drawing.Point
+using SharpHack.Engine.Pathfinding;
+using System.Linq; // Resolve ambiguity with System.Drawing.Point
namespace SharpHack.LevelGen.BSP;
@@ -61,8 +62,13 @@ private void CreateStart(BSPNode root, Map map, Point point)
int w = _random.Next(MinRoomSize, Math.Max(MinRoomSize, node.Bounds.Width - 2));
int h = _random.Next(MinRoomSize, Math.Max(MinRoomSize, node.Bounds.Height - 2));
// make sure the random room contains the point
+#if NET5_0_OR_GREATER
int x = Math.Clamp(point.X - w / 2, node.Bounds.X, node.Bounds.Right - w);
int y = Math.Clamp(point.Y - h / 2, node.Bounds.Y, node.Bounds.Bottom - h);
+#else
+ int x = Math.Max(node.Bounds.X, Math.Min(point.X - w / 2, node.Bounds.Right - w));
+ int y = Math.Max(node.Bounds.Y, Math.Min(point.Y - h / 2, node.Bounds.Bottom - h));
+#endif
node.Room = new Rectangle(x, y, w, h);
for (int rx = x; rx < x + w; rx++)
{
@@ -209,7 +215,11 @@ private static (Point door, Point outside) PickRoomDoorAndOutside(Rectangle room
{
bool toRight = dx >= 0;
int doorX = toRight ? room.Right : room.Left-1;
+#if NET5_0_OR_GREATER
int doorY = Math.Clamp(otherCenterY, room.Top + 1, room.Bottom - 1);
+#else
+ int doorY = Math.Max(room.Top + 1, Math.Min(otherCenterY, room.Bottom - 1));
+#endif
var door = new Point(doorX, doorY);
var outside = new Point(doorX + (toRight ? 1 : -1), doorY);
return (door, outside);
@@ -218,7 +228,11 @@ private static (Point door, Point outside) PickRoomDoorAndOutside(Rectangle room
{
bool toDown = dy >= 0;
int doorY = toDown ? room.Bottom : room.Top-1;
+#if NET5_0_OR_GREATER
int doorX = Math.Clamp(otherCenterX, room.Left + 1, room.Right - 1);
+#else
+ int doorX = Math.Max(room.Left + 1, Math.Min(otherCenterX, room.Right - 1));
+#endif
var door = new Point(doorX, doorY);
var outside = new Point(doorX, doorY + (toDown ? 1 : -1));
return (door, outside);
@@ -323,7 +337,15 @@ private void CreateCorridor(BSPNode node, IMap map, Point start, Point end, List
blocked = true;
room.Inflate(-1, -1);
var d = (room.X + room.Width / 2 - end.X, room.Y + room.Height / 2 - end.Y);
- d = Math.Abs(d.Item1)>Math.Abs(d.Item2)?(Math.Clamp(d.Item1, -1, 1), 0):(0, Math.Clamp(d.Item2, -1, 1));
+#if NET5_0_OR_GREATER
+ d = Math.Abs(d.Item1)>Math.Abs(d.Item2)?
+ (Math.Clamp(d.Item1, -1, 1), 0):
+ (0, Math.Clamp(d.Item2, -1, 1));
+#else
+ d = Math.Abs(d.Item1)>Math.Abs(d.Item2)?
+ (d.Item1<0?-1:d.Item1>0?1:0, 0):
+ (0, d.Item2<0?-1:d.Item2>0?1:0);
+#endif
room.Offset(d.Item1, d.Item2);
if (d.Item1 * (end.X - x) + d.Item2 * (end.Y - y) < 3)
{
@@ -333,7 +355,12 @@ private void CreateCorridor(BSPNode node, IMap map, Point start, Point end, List
{
var rm = (room.X + room.Width / 2 - x, room.Y + room.Height / 2 - y);
// we are about to carve into a room wall, compute, to get around it.
+#if NET5_0_OR_GREATER
(x, y) = (x + Math.Clamp((rm.Item1 * 2 + 1) * -Math.Abs(d.Item2), -1, 1), y + Math.Clamp((rm.Item2 * 2 + 1) * -Math.Abs(d.Item1), -1, 1));
+#else
+ (x, y) = (x + ((rm.Item1 * 2 + 1) * -Math.Abs(d.Item2) < 0 ? -1 : ((rm.Item1 * 2 + 1) * -Math.Abs(d.Item2) > 0 ? 1 : 0)),
+ y + ((rm.Item2 * 2 + 1) * -Math.Abs(d.Item1) < 0 ? -1 : ((rm.Item2 * 2 + 1) * -Math.Abs(d.Item1) > 0 ? 1 : 0)));
+#endif
}
else
(x, y) = (x - d.Item1, y - d.Item2);
diff --git a/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPRoomMazeMapGenerator.cs b/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPRoomMazeMapGenerator.cs
index 8e0bc1337..c1bb8fa98 100644
--- a/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPRoomMazeMapGenerator.cs
+++ b/CSharpBible/Games/SharpHack.LevelGen/BSP/BSPRoomMazeMapGenerator.cs
@@ -340,7 +340,11 @@ private void ApplyDoors(Map map, List doorCandidates)
private static int ClampEven(int value, int min, int max)
{
+#if NET5_0_OR_GREATER
int v = Math.Clamp(value, min, max);
+#else
+ int v = Math.Max(min, Math.Min(max, value));
+#endif
if ((v & 1) == 1)
{
if (v + 1 <= max) v++;
diff --git a/CSharpBible/Games/SharpHack.LevelGen/SharpHack.LevelGen.csproj b/CSharpBible/Games/SharpHack.LevelGen/SharpHack.LevelGen.csproj
index 585be23d6..9e11dfb86 100644
--- a/CSharpBible/Games/SharpHack.LevelGen/SharpHack.LevelGen.csproj
+++ b/CSharpBible/Games/SharpHack.LevelGen/SharpHack.LevelGen.csproj
@@ -1,16 +1,28 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
-
-
-
-
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
diff --git a/CSharpBible/Games/SharpHack.LevelGenTests/SharpHack.LevelGenTests.csproj b/CSharpBible/Games/SharpHack.LevelGenTests/SharpHack.LevelGenTests.csproj
index 2809b428e..7764ff80e 100644
--- a/CSharpBible/Games/SharpHack.LevelGenTests/SharpHack.LevelGenTests.csproj
+++ b/CSharpBible/Games/SharpHack.LevelGenTests/SharpHack.LevelGenTests.csproj
@@ -1,17 +1,24 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
- false
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
-
-
-
-
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.Magic/SharpHack.Magic.csproj b/CSharpBible/Games/SharpHack.Magic/SharpHack.Magic.csproj
index c9df3d96e..3878bc2bc 100644
--- a/CSharpBible/Games/SharpHack.Magic/SharpHack.Magic.csproj
+++ b/CSharpBible/Games/SharpHack.Magic/SharpHack.Magic.csproj
@@ -1,16 +1,24 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
-
-
-
-
-
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.MapExport/SharpHack.MapExport.csproj b/CSharpBible/Games/SharpHack.MapExport/SharpHack.MapExport.csproj
index 06d75777a..367b8ee67 100644
--- a/CSharpBible/Games/SharpHack.MapExport/SharpHack.MapExport.csproj
+++ b/CSharpBible/Games/SharpHack.MapExport/SharpHack.MapExport.csproj
@@ -1,4 +1,4 @@
-
+
Exe
net10.0-windows
@@ -6,6 +6,12 @@
true
enable
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.Persist/InMemoryGamePersist.cs b/CSharpBible/Games/SharpHack.Persist/InMemoryGamePersist.cs
index 8a21f8672..7b1dfb5f7 100644
--- a/CSharpBible/Games/SharpHack.Persist/InMemoryGamePersist.cs
+++ b/CSharpBible/Games/SharpHack.Persist/InMemoryGamePersist.cs
@@ -1,5 +1,6 @@
using SharpHack.Base.Interfaces;
using SharpHack.Base.Model;
+using System.Collections.Generic;
namespace SharpHack.Persist;
diff --git a/CSharpBible/Games/SharpHack.Persist/SharpHack.Persist.csproj b/CSharpBible/Games/SharpHack.Persist/SharpHack.Persist.csproj
index f23578f99..638b1784a 100644
--- a/CSharpBible/Games/SharpHack.Persist/SharpHack.Persist.csproj
+++ b/CSharpBible/Games/SharpHack.Persist/SharpHack.Persist.csproj
@@ -1,11 +1,25 @@
-
+
+
+
+ Library
+ net462;net472;net48;net481;net6.0;net7.0;net8.0
+
+
+
-
- net10.0
- enable
- enable
+
+ $(TargetFrameworks);net9.0
+
+
+ $(TargetFrameworks);net10.0
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.Server/SharpHack.Server.csproj b/CSharpBible/Games/SharpHack.Server/SharpHack.Server.csproj
index 5b022d74a..5dfc74145 100644
--- a/CSharpBible/Games/SharpHack.Server/SharpHack.Server.csproj
+++ b/CSharpBible/Games/SharpHack.Server/SharpHack.Server.csproj
@@ -9,8 +9,11 @@
+
+
+
diff --git a/CSharpBible/Games/SharpHack.Terminal/SharpHack.Terminal.csproj b/CSharpBible/Games/SharpHack.Terminal/SharpHack.Terminal.csproj
index 42ca14001..220eb6968 100644
--- a/CSharpBible/Games/SharpHack.Terminal/SharpHack.Terminal.csproj
+++ b/CSharpBible/Games/SharpHack.Terminal/SharpHack.Terminal.csproj
@@ -7,6 +7,12 @@
enable
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/App.xaml b/CSharpBible/Games/SharpHack.View.FirstPerson/App.xaml
new file mode 100644
index 000000000..a9f70bb6a
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/App.xaml
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/App.xaml.cs b/CSharpBible/Games/SharpHack.View.FirstPerson/App.xaml.cs
new file mode 100644
index 000000000..4b20616d4
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/App.xaml.cs
@@ -0,0 +1,65 @@
+using System.Windows;
+using Microsoft.Extensions.DependencyInjection;
+using SharpHack.ViewModel;
+using SharpHack.Engine;
+using SharpHack.LevelGen.BSP;
+using SharpHack.Combat;
+using SharpHack.AI;
+using BaseLib.Models;
+using BaseLib.Models.Interfaces;
+using SharpHack.Base.Interfaces;
+using SharpHack.Persist;
+
+namespace SharpHack.View.FirstPerson;
+
+///
+/// Interaction logic for App.xaml
+///
+public partial class App : Application
+{
+ private ServiceProvider _serviceProvider;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public App()
+ {
+ ServiceCollection services = new ServiceCollection();
+ ConfigureServices(services);
+ _serviceProvider = services.BuildServiceProvider();
+ }
+
+ ///
+ /// Configures the services for the application.
+ ///
+ /// The service collection to add services to.
+ private void ConfigureServices(ServiceCollection services)
+ {
+ // Core Services
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+
+ // Game Session
+ services.AddSingleton();
+
+ // ViewModel
+ services.AddSingleton();
+
+ // View
+ services.AddSingleton();
+ }
+
+ ///
+ /// Raises the event.
+ ///
+ /// A that contains the event data.
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ var mainWindow = _serviceProvider.GetRequiredService();
+ mainWindow.Show();
+ }
+}
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/MainWindow.xaml b/CSharpBible/Games/SharpHack.View.FirstPerson/MainWindow.xaml
new file mode 100644
index 000000000..fd9e4f2c0
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/MainWindow.xaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/MainWindow.xaml.cs b/CSharpBible/Games/SharpHack.View.FirstPerson/MainWindow.xaml.cs
new file mode 100644
index 000000000..0555a69e2
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/MainWindow.xaml.cs
@@ -0,0 +1,20 @@
+using System.Windows;
+using SharpHack.ViewModel;
+
+namespace SharpHack.View.FirstPerson;
+
+///
+/// Interaction logic for MainWindow.xaml
+///
+public partial class MainWindow : Window
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The view model.
+ public MainWindow(FirstPersonGameViewModel viewModel)
+ {
+ InitializeComponent();
+ DataContext = viewModel;
+ }
+}
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/Properties/Resources.Designer.cs b/CSharpBible/Games/SharpHack.View.FirstPerson/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..f1917bf4c
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/Properties/Resources.Designer.cs
@@ -0,0 +1,90 @@
+//------------------------------------------------------------------------------
+//
+// Dieser Code wurde von einem Tool generiert.
+// Laufzeitversion:4.0.30319.42000
+//
+// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+// der Code erneut generiert wird.
+//
+//------------------------------------------------------------------------------
+
+namespace SharpHack.View.FirstPerson.Properties {
+ using System;
+
+
+ ///
+ /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+ ///
+ // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+ // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+ // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+ // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SharpHack.View.FirstPerson.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+ /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Zeichenfolge, die SharpHack First Person ähnelt.
+ ///
+ public static string AppTitle {
+ get {
+ return ResourceManager.GetString("AppTitle", resourceCulture);
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Zeichenfolge, die HP: ähnelt.
+ ///
+ public static string HPLabel {
+ get {
+ return ResourceManager.GetString("HPLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Zeichenfolge, die Level: ähnelt.
+ ///
+ public static string LevelLabel {
+ get {
+ return ResourceManager.GetString("LevelLabel", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/Properties/Resources.resx b/CSharpBible/Games/SharpHack.View.FirstPerson/Properties/Resources.resx
new file mode 100644
index 000000000..1e55a5757
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/Properties/Resources.resx
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ SharpHack First Person
+
+
+ HP:
+
+
+ Level:
+
+
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/SharpHack.View.FirstPerson.csproj b/CSharpBible/Games/SharpHack.View.FirstPerson/SharpHack.View.FirstPerson.csproj
new file mode 100644
index 000000000..421bb029a
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/SharpHack.View.FirstPerson.csproj
@@ -0,0 +1,39 @@
+
+
+ WinExe
+ net10.0-windows
+ enable
+ true
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+ PublicResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/Views/FirstPersonView.xaml b/CSharpBible/Games/SharpHack.View.FirstPerson/Views/FirstPersonView.xaml
new file mode 100644
index 000000000..61e9e51ba
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/Views/FirstPersonView.xaml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.View.FirstPerson/Views/FirstPersonView.xaml.cs b/CSharpBible/Games/SharpHack.View.FirstPerson/Views/FirstPersonView.xaml.cs
new file mode 100644
index 000000000..a919d9881
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.View.FirstPerson/Views/FirstPersonView.xaml.cs
@@ -0,0 +1,17 @@
+using System.Windows.Controls;
+
+namespace SharpHack.View.FirstPerson.Views;
+
+///
+/// Interaction logic for FirstPersonView.xaml
+///
+public partial class FirstPersonView : UserControl
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public FirstPersonView()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/CSharpBible/Games/SharpHack.ViewModel.Tests/FirstPersonGameViewModelTests.cs b/CSharpBible/Games/SharpHack.ViewModel.Tests/FirstPersonGameViewModelTests.cs
new file mode 100644
index 000000000..6686ae3b4
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.ViewModel.Tests/FirstPersonGameViewModelTests.cs
@@ -0,0 +1,81 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NSubstitute;
+using SharpHack.Base.Model;
+using SharpHack.Base.Interfaces;
+using SharpHack.Engine;
+using SharpHack.ViewModel;
+using BaseLib.Models.Interfaces;
+
+namespace SharpHack.ViewModel.Tests;
+
+[TestClass]
+public class FirstPersonGameViewModelTests
+{
+ private GameSession _session;
+ private IRandom _random;
+ private IMapGenerator _generator;
+ private ICombatSystem _combat;
+ private IEnemyAI _ai;
+ private IGamePersist _persist;
+
+ private FirstPersonGameViewModel _vm;
+
+ [TestInitialize]
+ public void Setup()
+ {
+ _random = Substitute.For();
+ _generator = Substitute.For();
+ _combat = Substitute.For();
+ _ai = Substitute.For();
+ _persist = Substitute.For();
+
+ var map = Substitute.For();
+ map.Width.Returns(10);
+ map.Height.Returns(10);
+ _generator.Generate(Arg.Any(), Arg.Any(), Arg.Any()).Returns(map);
+
+ _session = new GameSession(_generator, _persist ,_random, _combat, _ai);
+ _vm = new FirstPersonGameViewModel(_session);
+ }
+
+ [TestMethod]
+ public void RotateLeft_ChangesDirectionCorrecty()
+ {
+ // Act
+ _vm.FacingDirection = Direction.North;
+ _vm.RotateLeft();
+
+ // Assert
+ Assert.AreEqual(Direction.West, _vm.FacingDirection);
+ }
+
+ [TestMethod]
+ public void RotateRight_ChangesDirectionCorrecty()
+ {
+ // Act
+ _vm.FacingDirection = Direction.North;
+ _vm.RotateRight();
+
+ // Assert
+ Assert.AreEqual(Direction.East, _vm.FacingDirection);
+ }
+
+ [TestMethod]
+ public void GetRelativeTile_NorthFacing_ReturnsCorrectTile()
+ {
+ // Arrange
+ _vm.FacingDirection = Direction.North;
+ var playerPos = new Point(5, 5);
+ _vm.Player.Position.Returns(playerPos);
+
+ var targetTile = Substitute.For();
+ _vm.Map.IsValid(5, 4).Returns(true);
+ _vm.Map[5, 4].Returns(targetTile);
+
+ // Act
+ var result = _vm.GetRelativeTile(1, 0); // 1 block forward
+
+ // Assert
+ Assert.AreSame(targetTile, result);
+ }
+}
diff --git a/CSharpBible/Games/SharpHack.ViewModel.Tests/SharpHack.ViewModel.Tests.csproj b/CSharpBible/Games/SharpHack.ViewModel.Tests/SharpHack.ViewModel.Tests.csproj
new file mode 100644
index 000000000..3e7db26ab
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.ViewModel.Tests/SharpHack.ViewModel.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+ net10.0
+ enable
+ enable
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CSharpBible/Games/SharpHack.ViewModel/FirstPersonGameViewModel.cs b/CSharpBible/Games/SharpHack.ViewModel/FirstPersonGameViewModel.cs
new file mode 100644
index 000000000..3dd325444
--- /dev/null
+++ b/CSharpBible/Games/SharpHack.ViewModel/FirstPersonGameViewModel.cs
@@ -0,0 +1,107 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using SharpHack.Base.Interfaces;
+using SharpHack.Base.Model;
+using SharpHack.Engine;
+
+namespace SharpHack.ViewModel;
+
+///
+/// ViewModel for the first-person view of the dungeon.
+///
+public partial class FirstPersonGameViewModel : GameViewModel
+{
+ [ObservableProperty]
+ private Direction _facingDirection = Direction.North;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The game session.
+ public FirstPersonGameViewModel(GameSession session) : base(session)
+ {
+ }
+
+ ///
+ /// Rotates the player left.
+ ///
+ [RelayCommand]
+ public void RotateLeft()
+ {
+ FacingDirection = FacingDirection switch
+ {
+ Direction.North => Direction.West,
+ Direction.West => Direction.South,
+ Direction.South => Direction.East,
+ Direction.East => Direction.North,
+ _ => FacingDirection
+ };
+ }
+
+ ///
+ /// Rotates the player right.
+ ///
+ [RelayCommand]
+ public void RotateRight()
+ {
+ FacingDirection = FacingDirection switch
+ {
+ Direction.North => Direction.East,
+ Direction.East => Direction.South,
+ Direction.South => Direction.West,
+ Direction.West => Direction.North,
+ _ => FacingDirection
+ };
+ }
+
+ ///
+ /// Moves the player forward in the current facing direction.
+ ///
+ [RelayCommand]
+ public void MoveForward()
+ {
+ Move(FacingDirection);
+ }
+
+ ///
+ /// Gets the tile at the relative position from the player.
+ ///
+ /// Distance forward.
+ /// Distance to the right (negative for left).
+ /// The tile at the relative position.
+ public ITile? GetRelativeTile(int forward, int right)
+ {
+ var playerPos = Player.Position;
+ int dx = 0, dy = 0;
+
+ switch (FacingDirection)
+ {
+ case Direction.North:
+ dx = right;
+ dy = -forward;
+ break;
+ case Direction.South:
+ dx = -right;
+ dy = forward;
+ break;
+ case Direction.East:
+ dx = forward;
+ dy = right;
+ break;
+ case Direction.West:
+ dx = -forward;
+ dy = -right;
+ break;
+ }
+
+ int targetX = playerPos.X + dx;
+ int targetY = playerPos.Y + dy;
+
+ if (Map.IsValid(targetX, targetY))
+ {
+ return Map[targetX, targetY];
+ }
+
+ return null;
+ }
+}
diff --git a/CSharpBible/Games/SharpHack.Wpf/SharpHack.Wpf.csproj b/CSharpBible/Games/SharpHack.Wpf/SharpHack.Wpf.csproj
index 8aa3934ce..b5e483086 100644
--- a/CSharpBible/Games/SharpHack.Wpf/SharpHack.Wpf.csproj
+++ b/CSharpBible/Games/SharpHack.Wpf/SharpHack.Wpf.csproj
@@ -5,6 +5,7 @@
enable
true
+
diff --git a/CSharpBible/Games/SharpHack.sln b/CSharpBible/Games/SharpHack.sln
index cf24c60e4..2d61941fe 100644
--- a/CSharpBible/Games/SharpHack.sln
+++ b/CSharpBible/Games/SharpHack.sln
@@ -144,6 +144,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sokoban_BaseTests", "Sokoba
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpHack.WPF2D", "SharpHack.WPF2D\SharpHack.WPF2D.csproj", "{9F55A149-DA32-BB7C-D552-73C3ECDF7C8B}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpHack.ViewModel.Tests", "SharpHack.ViewModel.Tests\SharpHack.ViewModel.Tests.csproj", "{C3C3599E-120E-4703-955E-85B6C9321934}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpHack.View.FirstPerson", "SharpHack.View.FirstPerson\SharpHack.View.FirstPerson.csproj", "{0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -802,6 +806,30 @@ Global
{9F55A149-DA32-BB7C-D552-73C3ECDF7C8B}.Release|x64.Build.0 = Release|Any CPU
{9F55A149-DA32-BB7C-D552-73C3ECDF7C8B}.Release|x86.ActiveCfg = Release|Any CPU
{9F55A149-DA32-BB7C-D552-73C3ECDF7C8B}.Release|x86.Build.0 = Release|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Debug|x64.Build.0 = Debug|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Debug|x86.Build.0 = Debug|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Release|x64.ActiveCfg = Release|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Release|x64.Build.0 = Release|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Release|x86.ActiveCfg = Release|Any CPU
+ {C3C3599E-120E-4703-955E-85B6C9321934}.Release|x86.Build.0 = Release|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Debug|x64.Build.0 = Debug|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Debug|x86.Build.0 = Debug|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Release|x64.ActiveCfg = Release|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Release|x64.Build.0 = Release|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Release|x86.ActiveCfg = Release|Any CPU
+ {0D4F4CA3-56D7-4D2E-AE37-2D9BCD85F7AB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/CSharpBible/Games/Sokoban.Plugin/MiniSokoCommand.cs b/CSharpBible/Games/Sokoban.Plugin/MiniSokoCommand.cs
new file mode 100644
index 000000000..5efceb74c
--- /dev/null
+++ b/CSharpBible/Games/Sokoban.Plugin/MiniSokoCommand.cs
@@ -0,0 +1,131 @@
+using BaseLib.Interfaces;
+using ConsoleDisplay.View;
+using Microsoft.Extensions.Logging;
+using PluginBase.Interfaces;
+using Sokoban.Models;
+using Sokoban.Plugin;
+using Sokoban.Properties;
+using Sokoban.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Sokoban;
+
+public class MiniSokoCommand : ICommand
+{
+ private IEnvironment _env;
+ private IRandom? _rnd;
+ private ILogger? _logger;
+ private ISysTime? _time;
+ private IConsole? _console;
+ private Display _display;
+ private Game _game;
+
+ public string Name => "sokoban-mini";
+
+ public string Description => Resources.cmdDescription2;
+
+ public int Execute(object? param = null)
+ {
+ _logger?.LogDebug($"{nameof(SokoCommand)}.{nameof(Execute)}");
+ if (_console != null)
+ {
+ _console.Clear();
+ _game = new Game();
+ _game.Init();
+ _display = new Display(_console, 3, 3,_game.PFSize.Width,_game.PFSize.Height);
+ _game.visSetMessage = (msg) =>
+ {
+ _console.SetCursorPosition(0, 15);
+ _console.WriteLine(msg);
+ };
+ _game.visShow = (ua) =>
+ {
+ _display.Clear();
+ for (int y = 0; y < _game.PFSize.Height; y++)
+ {
+ for (int x = 0; x < _game.PFSize.Width; x++)
+ {
+ var tile = _game.GetTile(new Point(x, y));
+ ConsoleColor color = tile switch
+ {
+ TileDef.Wall => ConsoleColor.DarkGray,
+ TileDef.Floor => ConsoleColor.Black,
+ TileDef.Destination => ConsoleColor.Yellow,
+ _ => ConsoleColor.Black,
+ };
+ _display.PutPixel(x, y, color);
+ }
+ }
+ foreach (var stone in _game.Stones)
+ {
+ _display.PutPixel(stone.Position.X, stone.Position.Y, ConsoleColor.Blue);
+ }
+ if (_game.player != null)
+ {
+ _display.PutPixel(_game.player.Position.X, _game.player.Position.Y, ConsoleColor.Green);
+ }
+ _display.Update();
+ };
+ _game.visUpdate = () =>
+ {
+ // Optional: Implement if needed
+ };
+ _game.visGetUserAction = (ua) =>
+ {
+ _console.SetCursorPosition(0, 14);
+ _console.WriteLine("Use W/A/S/D to move, Q to quit.");
+ while (true)
+ {
+ var keyInfo = _console.ReadKey();
+ if (keyInfo.HasValue)
+ {
+ var key = keyInfo.Value.Key;
+ return key switch
+ {
+ ConsoleKey.W => UserAction.GoNorth,
+ ConsoleKey.UpArrow => UserAction.GoNorth,
+ ConsoleKey.A => UserAction.GoWest,
+ ConsoleKey.LeftArrow => UserAction.GoWest,
+ ConsoleKey.S => UserAction.GoSouth,
+ ConsoleKey.DownArrow => UserAction.GoSouth,
+ ConsoleKey.D => UserAction.GoEast,
+ ConsoleKey.RightArrow => UserAction.GoEast,
+ ConsoleKey.Q => UserAction.Quit,
+ _ => null,
+ };
+ }
+ }
+ };
+
+ while (LabDefs.SLevels.Length > _game.level)
+ {
+ var action = _game.Run();
+ if (action == UserAction.Quit)
+ {
+ break;
+ }
+ }
+
+ _game.Cleanup();
+ }
+ else
+ {
+ _logger?.LogError("Console service is not available.");
+ }
+ return 0;
+ }
+
+ public void Initialize(IEnvironment env)
+ {
+ _env = env;
+ _rnd = _env.GetService();
+ _logger = _env.GetService();
+ _time = _env.GetService();
+ _console = _env.GetService();
+ }
+}
diff --git a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.Designer.cs b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.Designer.cs
index 3b1c11adb..34a7ac193 100644
--- a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.Designer.cs
+++ b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.Designer.cs
@@ -69,6 +69,15 @@ public static string cmdDescription {
}
}
+ ///
+ /// Sucht eine lokalisierte Zeichenfolge, die A Sokoban game (mini) ähnelt.
+ ///
+ public static string cmdDescription2 {
+ get {
+ return ResourceManager.GetString("cmdDescription2", resourceCulture);
+ }
+ }
+
///
/// Sucht eine lokalisierte Zeichenfolge, die A test ! ähnelt.
///
diff --git a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.de.resx b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.de.resx
index 9d56166ce..14c3225ec 100644
--- a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.de.resx
+++ b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.de.resx
@@ -124,4 +124,8 @@
Ein Sokoban-Spiel
Description of test-command
+
+ Ein Sokoban-Spiel (Mini)
+ Description of test-command
+
\ No newline at end of file
diff --git a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.en.resx b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.en.resx
index 2383f1f07..a38671e7c 100644
--- a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.en.resx
+++ b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.en.resx
@@ -124,4 +124,8 @@
A Sokoban game
Description of test-command
+
+ A Sokoban game (mini)
+ Description of test-command
+
\ No newline at end of file
diff --git a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.fr.resx b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.fr.resx
index 642c2a87a..88f30fced 100644
--- a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.fr.resx
+++ b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.fr.resx
@@ -124,4 +124,8 @@
A Sokoban game
Description of test-command
+
+ A Sokoban game (mini)
+ Description of test-command
+
\ No newline at end of file
diff --git a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.resx b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.resx
index 2383f1f07..a38671e7c 100644
--- a/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.resx
+++ b/CSharpBible/Games/Sokoban.Plugin/Properties/Resources.resx
@@ -124,4 +124,8 @@
A Sokoban game
Description of test-command
+
+ A Sokoban game (mini)
+ Description of test-command
+
\ No newline at end of file
diff --git a/CSharpBible/Games/Sokoban.Server/Program.cs b/CSharpBible/Games/Sokoban.Server/Program.cs
index a4a798ebc..f4803b754 100644
--- a/CSharpBible/Games/Sokoban.Server/Program.cs
+++ b/CSharpBible/Games/Sokoban.Server/Program.cs
@@ -6,6 +6,7 @@
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
+using System.Reflection;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
@@ -16,6 +17,9 @@ namespace Sokoban.Server;
///
public static class Program
{
+ private static readonly string SOKOSERVER_TLS_CERT_PATH= "SOKOSERVER_TLS_CERT_PATH";
+ private static readonly string SOKOSERVER_TLS_CERT_PASSWORD = "SOKOSERVER_TLS_CERT_PASSWORD";
+ private static readonly string SOKOSERVER_TLS = "SOKOSERVER_TLS";
public static async Task Main(string[] args)
{
@@ -30,11 +34,11 @@ public static async Task Main(string[] args)
var listener = new TcpListener(IPAddress.Any, port);
listener.Start();
- System.Console.WriteLine($"SharpHack server listening on 0.0.0.0:{port}");
+ System.Console.WriteLine($"{Assembly.GetExecutingAssembly().GetName().Name} server listening on 0.0.0.0:{port}");
if (useTls)
{
System.Console.WriteLine("TLS enabled: connect with an SSL/TLS capable client, then use TELNET/RAW over the secure channel.");
- System.Console.WriteLine($"Certificate: {(string.IsNullOrWhiteSpace(certPath) ? "" : certPath)}");
+ System.Console.WriteLine($"Certificate: {(string.IsNullOrWhiteSpace(certPath) ? $"" : certPath)}");
}
else
{
@@ -178,19 +182,19 @@ private static void ParseArgs(string[] args, ref int port, ref bool useTls, ref
if (!useTls)
{
- var envTls = Environment.GetEnvironmentVariable("SHARPHACK_TLS") ?? Environment.GetEnvironmentVariable("SHARPHACK_SSL");
+ var envTls = Environment.GetEnvironmentVariable(SOKOSERVER_TLS) ?? Environment.GetEnvironmentVariable("SHARPHACK_SSL");
if (!string.IsNullOrWhiteSpace(envTls) && (envTls.Equals("1") || envTls.Equals("true", StringComparison.OrdinalIgnoreCase) || envTls.Equals("yes", StringComparison.OrdinalIgnoreCase)))
{
useTls = true;
}
}
- certPath ??= Environment.GetEnvironmentVariable("SHARPHACK_TLS_CERT_PATH");
- certPassword ??= Environment.GetEnvironmentVariable("SHARPHACK_TLS_CERT_PASSWORD");
+ certPath ??= Environment.GetEnvironmentVariable(SOKOSERVER_TLS_CERT_PATH);
+ certPassword ??= Environment.GetEnvironmentVariable(SOKOSERVER_TLS_CERT_PASSWORD);
if (useTls && string.IsNullOrWhiteSpace(certPath))
{
- throw new InvalidOperationException("TLS is enabled but no certificate was provided. Use --cert or set SHARPHACK_TLS_CERT_PATH.");
+ throw new InvalidOperationException($"TLS is enabled but no certificate was provided. Use --cert or set {SOKOSERVER_TLS_CERT_PATH}.");
}
}
diff --git a/CSharpBible/Games/Sokoban.Server/Sokoban.Server.csproj b/CSharpBible/Games/Sokoban.Server/Sokoban.Server.csproj
index 13255fa4b..b56b76480 100644
--- a/CSharpBible/Games/Sokoban.Server/Sokoban.Server.csproj
+++ b/CSharpBible/Games/Sokoban.Server/Sokoban.Server.csproj
@@ -14,8 +14,8 @@
-
+
diff --git a/CSharpBible/Games/Sokoban/Program.cs b/CSharpBible/Games/Sokoban/Program.cs
index b5408ce7d..a84680939 100644
--- a/CSharpBible/Games/Sokoban/Program.cs
+++ b/CSharpBible/Games/Sokoban/Program.cs
@@ -50,7 +50,7 @@ public static void Cleanup()
public static void Run()
{
UserAction? direction = null;
- while (direction!=UserAction.Quit && LabDefs.SLevels.Length > _SokobanGame.level)
+ while (direction!=UserAction.Quit && LabDefs.SLevels.Length > _SokobanGame?.level)
{
direction = _SokobanGame?.Run();
}
diff --git a/CSharpBible/Games/Sokoban_Base/Sokoban_Base.csproj b/CSharpBible/Games/Sokoban_Base/Sokoban_Base.csproj
index 54e62e3ef..5b8e9d0c0 100644
--- a/CSharpBible/Games/Sokoban_Base/Sokoban_Base.csproj
+++ b/CSharpBible/Games/Sokoban_Base/Sokoban_Base.csproj
@@ -60,7 +60,7 @@
-
+
diff --git a/CSharpBible/Games/Sokoban_BaseTests/Models/StoneTests.cs b/CSharpBible/Games/Sokoban_BaseTests/Models/StoneTests.cs
index 8c5df47fc..3010c116e 100644
--- a/CSharpBible/Games/Sokoban_BaseTests/Models/StoneTests.cs
+++ b/CSharpBible/Games/Sokoban_BaseTests/Models/StoneTests.cs
@@ -1,5 +1,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sokoban.Models;
+using Sokoban.Models.Interfaces;
using System.Drawing;
namespace Sokoban.Models.Tests
@@ -38,8 +39,8 @@ public void SetupTest()
[DataRow(1, 1, Direction.East, false)]
public void TestMoveTest(int x,int y,Direction d,bool xExp)
{
- if (y>0)
- pf[new Point(x,y)].Item = testItem;
+ if (y>0 && pf[new Point(x, y)] is IField fld )
+ fld.Item = testItem;
else if (x > 0)
new Floor(Point.Empty,null).Item = testItem;
Assert.AreEqual(xExp,testItem.TestMove(d));
@@ -56,8 +57,8 @@ public void TestMoveTest(int x,int y,Direction d,bool xExp)
[DataRow(1, 1, Direction.East, false)]
public void TryMoveTest(int x, int y, Direction d, bool xExp)
{
- if (y > 0)
- pf[new Point(x, y)].Item = testItem;
+ if (y > 0 && pf[new Point(x, y)] is IField fld)
+ fld.Item = testItem;
else if (x>0)
new Floor(Point.Empty,null).Item = testItem;
Assert.AreEqual(xExp, testItem.TryMove(d));
diff --git a/CSharpBible/Games/Sudoku_Base/Models/UndoInformation.cs b/CSharpBible/Games/Sudoku_Base/Models/UndoInformation.cs
index 4528b60ea..05797738b 100644
--- a/CSharpBible/Games/Sudoku_Base/Models/UndoInformation.cs
+++ b/CSharpBible/Games/Sudoku_Base/Models/UndoInformation.cs
@@ -27,14 +27,14 @@ public void Redo()
}
else if (ov is int i && xf && f!.Value == i || ov == null && xf)
{
- f.Value = nv as int?;
+ f!.Value = nv as int?;
}
else if (nv is IList li && xf)
{
- f.PossibleValues.Clear();
+ f?.PossibleValues.Clear();
foreach (var l in li)
{
- f.PossibleValues.Add(l);
+ f?.PossibleValues.Add(l);
}
}
}
@@ -51,14 +51,14 @@ public void Undo()
}
else if (nv is int i && xf && f!.Value == i || nv == null && xf)
{
- f.Value = ov as int?;
+ f!.Value = ov as int?;
}
else if (ov is IList li && xf)
{
- f.PossibleValues.Clear();
+ f?.PossibleValues.Clear();
foreach (var l in li)
{
- f.PossibleValues.Add(l);
+ f?.PossibleValues.Add(l);
}
}
}
diff --git a/CSharpBible/Games/Sudoku_BaseTests/Models/SudokuFieldTests.cs b/CSharpBible/Games/Sudoku_BaseTests/Models/SudokuFieldTests.cs
index 81500f9e9..45f5c79f9 100644
--- a/CSharpBible/Games/Sudoku_BaseTests/Models/SudokuFieldTests.cs
+++ b/CSharpBible/Games/Sudoku_BaseTests/Models/SudokuFieldTests.cs
@@ -82,7 +82,7 @@ public void ReadFromStreamTest(byte[] bytes, SudokuField field)
// Act
testModel.ReadFromStream(stream);
// Assert
- AssertAreEqual(field, testModel, []);
+ AssertAreEqual(field, testModel, [nameof(testModel.PossibleValues)]);
}
[TestMethod()]
diff --git a/CSharpBible/Games/Tetris_Base/View/Visual.cs b/CSharpBible/Games/Tetris_Base/View/Visual.cs
index 39f58eebe..985b077eb 100644
--- a/CSharpBible/Games/Tetris_Base/View/Visual.cs
+++ b/CSharpBible/Games/Tetris_Base/View/Visual.cs
@@ -31,7 +31,6 @@ public static class Visual
/// The display2
///
static public Display display2 = new Display(18, 2, 6, 6);
- private static bool flag;
///
/// Gets or sets the console.
diff --git a/CSharpBible/Games/TileSetAnimator.Tests/TileSetAnimator.Tests.csproj b/CSharpBible/Games/TileSetAnimator.Tests/TileSetAnimator.Tests.csproj
index 885c5aef2..b0d45bcf7 100644
--- a/CSharpBible/Games/TileSetAnimator.Tests/TileSetAnimator.Tests.csproj
+++ b/CSharpBible/Games/TileSetAnimator.Tests/TileSetAnimator.Tests.csproj
@@ -8,6 +8,13 @@
enable
+
+
+
+
+
+
+
diff --git a/CSharpBible/Games/TileSetAnimator/TileSetAnimator.csproj b/CSharpBible/Games/TileSetAnimator/TileSetAnimator.csproj
index 214539916..d28784a93 100644
--- a/CSharpBible/Games/TileSetAnimator/TileSetAnimator.csproj
+++ b/CSharpBible/Games/TileSetAnimator/TileSetAnimator.csproj
@@ -8,6 +8,12 @@
preview
true
+
+
+
+
+
+
diff --git a/CSharpBible/Games/VTileEdit/Models/VisTileData.cs b/CSharpBible/Games/VTileEdit/Models/VisTileData.cs
index 2188af055..fd0ffd2ef 100644
--- a/CSharpBible/Games/VTileEdit/Models/VisTileData.cs
+++ b/CSharpBible/Games/VTileEdit/Models/VisTileData.cs
@@ -16,7 +16,9 @@
namespace VTileEdit.Models;
+#pragma warning disable CS0659 // Typ überschreibt Object.Equals(object o), überschreibt jedoch nicht Object.GetHashCode()
public class VisTileData : ITileDef
+#pragma warning restore CS0659 // Typ überschreibt Object.Equals(object o), überschreibt jedoch nicht Object.GetHashCode()
{
private sealed class TileEntry
{
@@ -293,9 +295,10 @@ public bool LoadFromStream(Stream stream, EStreamType eStreamType)
{
Dictionary? data = [];
var lst = JsonSerializer.Deserialize>>>(new StreamReader(stream).ReadToEnd());
- KeyTypeStr = lst.Item1 ?? "";
- _size = lst.Item2;
- foreach (var itm in lst.Item3)
+ KeyTypeStr = lst?.Item1 ?? "";
+ _size = lst?.Item2 ?? default;
+ if (lst?.Item3 != null)
+ foreach (var itm in lst!.Item3)
{
data.Add(itm.Item1, new TileEntry(itm.Item2, TileInfo.Default));
}
@@ -446,6 +449,7 @@ public bool WriteToStream(Stream stream, EStreamType eStreamType)
return new Json2Data.TileEntry(
(int)(object)v.Key,
+
tags.ToArray(),
tile.lines,
tile.colors.Select(c => (byte)(((int)c.bgr) * 16 + (byte)c.fgr)).ToArray(),
diff --git a/CSharpBible/Games/VTileEditTests/Models/VisTileDataTests.cs b/CSharpBible/Games/VTileEditTests/Models/VisTileDataTests.cs
index ca62efb26..98b6b2dde 100644
--- a/CSharpBible/Games/VTileEditTests/Models/VisTileDataTests.cs
+++ b/CSharpBible/Games/VTileEditTests/Models/VisTileDataTests.cs
@@ -655,7 +655,7 @@ private static string Decompress(string input)
return reader.ReadToEnd();
}
}
- catch (Exception ex)
+ catch (Exception)
{
return input;
}
@@ -673,7 +673,7 @@ private static byte[] DecompressBinary(string input)
return reader.ToArray();
}
}
- catch (Exception ex)
+ catch (Exception)
{
return Encoding.UTF8.GetBytes( input);
}
diff --git a/CSharpBible/Games/Werner_Flaschbier.Console2/Program.cs b/CSharpBible/Games/Werner_Flaschbier.Console2/Program.cs
new file mode 100644
index 000000000..719cf2566
--- /dev/null
+++ b/CSharpBible/Games/Werner_Flaschbier.Console2/Program.cs
@@ -0,0 +1,56 @@
+using BaseLib.Helper;
+using BaseLib.Interfaces;
+using BaseLib.Models;
+using ConsoleDisplay.View;
+using Microsoft.Extensions.DependencyInjection;
+using System.Threading;
+using Werner_Flaschbier.Console2.View;
+using Werner_Flaschbier_Base.Model;
+using Werner_Flaschbier_Base.ViewModels;
+
+namespace Werner_Flaschbier.Console2;
+
+public class Programm
+{
+ private IWernerGame? game;
+ private IVisual? visual;
+
+ private void OnStartUp()
+ {
+ var sc = new ServiceCollection()
+ .AddSingleton()
+ .AddTransient()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton();
+
+ var sp = sc.BuildServiceProvider();
+
+ IoC.Configure(sp);
+ }
+
+ public static void Main(params string[] args)
+ {
+ var program = new Programm();
+ program.Initialize(args);
+ program.Run();
+ }
+
+ public void Run()
+ {
+ while (game!.isRunning)
+ {
+ visual?.CheckUserAction();
+ var delay = game.GameStep();
+ Thread.Sleep(delay);
+ }
+ }
+
+ public void Initialize(string[] args)
+ {
+ OnStartUp();
+
+ game = IoC.GetRequiredService();
+ visual = IoC.GetRequiredService();
+ }
+}
diff --git a/CSharpBible/Games/Werner_Flaschbier.Console2/View/IVisual.cs b/CSharpBible/Games/Werner_Flaschbier.Console2/View/IVisual.cs
new file mode 100644
index 000000000..9248641d3
--- /dev/null
+++ b/CSharpBible/Games/Werner_Flaschbier.Console2/View/IVisual.cs
@@ -0,0 +1,19 @@
+// ***********************************************************************
+// Assembly : Werner_Flaschbier_Base
+// Author : Mir
+// Created : 08-02-2022
+//
+// Last Modified By : Mir
+// Last Modified On : 09-09-2022
+// ***********************************************************************
+//
+// Copyright (c) JC-Soft. All rights reserved.
+//
+//
+// ***********************************************************************
+namespace Werner_Flaschbier.Console2.View;
+
+public interface IVisual
+{
+ bool CheckUserAction();
+}
\ No newline at end of file
diff --git a/CSharpBible/Games/Werner_Flaschbier.Console2/View/VTileDef.cs b/CSharpBible/Games/Werner_Flaschbier.Console2/View/VTileDef.cs
new file mode 100644
index 000000000..56f8560f7
--- /dev/null
+++ b/CSharpBible/Games/Werner_Flaschbier.Console2/View/VTileDef.cs
@@ -0,0 +1,106 @@
+// ***********************************************************************
+// Assembly : Werner_Flaschbier_Base
+// Author : Mir
+// Created : 08-02-2022
+//
+// Last Modified By : Mir
+// Last Modified On : 09-09-2022
+// ***********************************************************************
+//
+// Copyright (c) JC-Soft. All rights reserved.
+//
+//
+// ***********************************************************************
+using System;
+using System.Drawing;
+using ConsoleDisplay.View;
+
+namespace Werner_Flaschbier.Console2.View
+{
+
+ ///
+ /// Class VTileDef.
+ ///
+ public class VTileDef : TileDefBase, ITileDef {
+ ///
+ /// The v tile definition string
+ ///
+ private string[][] _vTileDefStr = [
+ [" ", " "],
+ ["=-=-", "-=-="],
+ ["─┴┬─", "─┬┴─"],
+ [" â•“â•– ", "â–“â–‘â–’â–“"],
+ ["âŒÂ°@)", " ⌡⌡‼"],
+ [@"/¯¯\", @"\__/"],
+ ["]°°[", "_!!_"],
+ ["◄°@[",@"_!!\"],
+ ["]oo[", "_!!_"],
+ ["]@°►", "/!!_"],
+ [@"/╨╨\", @"\__/"],
+ [" +*∩", "╘â•â—Š@"],
+ [" ", " "],
+ ["─┴┬┴", "─┬┴─"],
+ ["┬┴┬─", "┴┬┴─"],
+ ["┬┴┬┴", "┴┬┴─"],
+
+ ["┬┴┬─", "┴┬┴┬"],
+ ["┬┴┬┴", "┴┬┴┬"],
+ ["┬┴┬─", "┴┬┴┬"],
+ ["┬┴┬┴", "┴┬┴┬"],
+
+ ["─┴┬─", "─┬┴─"],
+ ["─┴┬┴", "─┬┴─"],
+ ["┬┴┬─", "┴┬┴─"],
+ ["┬┴┬┴", "┴┬┴─"],
+
+ ["┬┴┬─", "┴┬┴┬"],
+ ["┬┴┬┴", "┴┬┴┬"],
+ ["┬┴┬─", "┴┬┴┬"],
+ ["┬┴┬┴", "┴┬┴┬"]
+ ];
+
+ ///
+ /// The v tile colors
+ ///
+ private byte[][] _vTileColors =
+ [
+ [0x00],
+ [0x6E],
+ [0x4F],
+ [0x0E, 0x0E, 0x0E, 0x0E, 0x2A, 0x22, 0x02, 0x22],
+ [0x6F],
+ [0x6E],
+ [0x1A,0xA0,0xA0,0x1A,0x1A,0xA0,0xA0,0x1A],
+ [0x1A,0xA0,0xA0,0x1A,0x1A,0xA0,0xA0,0x1A],
+ [0x1A,0xA0,0xA0,0x1A,0x1A,0xA0,0xA0,0x1A],
+ [0x1A,0xA0,0xA0,0x1A,0x1A,0xA0,0xA0,0x1A],
+ [0x6E],
+ [0x6F],
+ [0x6E],
+ [0x4F],
+
+ ];
+
+ public new Size TileSize => new Size(4,2);
+
+ ///
+ /// Gets the tile colors.
+ ///
+ /// The tile.
+ /// FullColor[].
+ private (ConsoleColor fgr, ConsoleColor bgr)[] GetTileColors(Enum? tile)
+ {
+ var result = new (ConsoleColor fgr, ConsoleColor bgr)[8];
+ byte[] colDef = GetArrayElement(_vTileColors, tile);
+ for (var i =0;i> 4));
+ }
+ return result;
+ }
+
+ public override (string[] lines, (ConsoleColor fgr, ConsoleColor bgr)[] colors) GetTileDef(Enum? tile)
+ => (GetArrayElement(_vTileDefStr, tile), GetTileColors((Enum?)tile));
+ }
+}
diff --git a/CSharpBible/Games/Werner_Flaschbier.Console2/View/Visual.cs b/CSharpBible/Games/Werner_Flaschbier.Console2/View/Visual.cs
new file mode 100644
index 000000000..bcdcb6579
--- /dev/null
+++ b/CSharpBible/Games/Werner_Flaschbier.Console2/View/Visual.cs
@@ -0,0 +1,136 @@
+using BaseLib.Interfaces;
+using ConsoleDisplay.View;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using Werner_Flaschbier_Base.Model;
+using Werner_Flaschbier_Base.ViewModels;
+
+namespace Werner_Flaschbier.Console2.View
+{
+ public class Visual : IVisual
+ {
+ private readonly TileDisplay _display;
+ private readonly IWernerViewModel _viewModel;
+ private readonly IConsole _console;
+ private readonly List _actionBuffer = new List();
+
+ public static Dictionary keyAction = new Dictionary {
+ { 'I', UserAction.GoUp },
+ { 'J', UserAction.GoWest },
+ { 'K', UserAction.GoDown },
+ { 'L', UserAction.GoEast },
+ { '?', UserAction.Help },
+ { 'H', UserAction.Help },
+ { 'R', UserAction.Restart },
+ { 'Q', UserAction.Quit },
+#if DEBUG
+ { 'N', UserAction.NextLvl },
+ { 'V', UserAction.PrevLvl },
+#endif
+ { '\u001b', UserAction.Quit } };
+
+ public Visual(IWernerViewModel viewModel, IConsole console, ITileDef tileDef)
+ {
+ _viewModel = viewModel;
+ _console = console;
+ _console.CursorVisible = false;
+ _display = new TileDisplay(console, tileDef);
+ _display.FncGetTile = (p) => (Tiles)_viewModel.Tiles[p];
+ _display.FncOldPos = (p) => _viewModel.OldPos(p);
+ _display.SetDispSize(_viewModel.size);
+
+ _viewModel.PropertyChanged += OnPropertyChanged;
+ FullRedraw();
+ }
+
+ private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "Tiles")
+ {
+ _display.Update(_viewModel!.HalfStep);
+ _console.SetCursorPosition(0, 24);
+ _console.BackgroundColor = ConsoleColor.Black;
+ _console.ForegroundColor = ConsoleColor.Yellow;
+ }
+ else if (e.PropertyName == "Level")
+ FullRedraw();
+ }
+
+ public void FullRedraw(object? sender = null, EventArgs? e = null)
+ {
+ if (_viewModel == null) return;
+ _display.FullRedraw();
+ ShowStatistics();
+ }
+
+ private void ShowStatistics()
+ {
+ if (_viewModel == null) return;
+ _console.SetCursorPosition(0, 24);
+ _console.BackgroundColor = ConsoleColor.Black;
+ _console.ForegroundColor = ConsoleColor.Yellow;
+ _console.Write($"\t{_viewModel.Level + 1}\t\t{_viewModel.Score}\t\t{_viewModel.Lives}/{_viewModel.MaxLives} \t\t{Math.Floor(_viewModel.TimeLeft)}\t\x08");
+ }
+
+ public void WriteTile(PointF p, Tiles tile)
+ {
+ _display.WriteTile(p, tile);
+ }
+
+ public void Sound(GameSound gs)
+ {
+ switch (gs)
+ {
+ case GameSound.NoSound:
+ break;
+ case GameSound.Tick:
+ _console.Beep(1000, 10);
+ break;
+ case GameSound.DeepBoom:
+ _console.Beep(300, 20);
+ break;
+ default:
+ break;
+ }
+ }
+
+ public bool CheckUserAction()
+ {
+ while (_console.KeyAvailable)
+ {
+ var ch = char.ToUpper(_console.ReadKey()?.KeyChar ?? '\x00');
+ if (keyAction.TryGetValue(ch, out var action))
+ {
+ int sameCount = 0;
+ for (int i = _actionBuffer.Count - 1; i >= 0 && _actionBuffer[i] == action; i--)
+ {
+ sameCount++;
+ }
+
+ if (sameCount < 2)
+ {
+ _actionBuffer.Add(action);
+ }
+ if (_actionBuffer.Count > 2)
+ {
+ _actionBuffer.RemoveAt(0);
+ }
+ }
+ }
+ UserAction currentAction = UserAction.Nop;
+ bool result = _actionBuffer.Count > 0;
+
+ if (result)
+ {
+ currentAction = _actionBuffer[0];
+ _actionBuffer.RemoveAt(0);
+ }
+
+ _viewModel?.HandleUserAction(currentAction);
+ return result;
+ }
+ }
+}
diff --git a/CSharpBible/Games/Werner_Flaschbier.Console2/Werner_Flaschbier.Console2.csproj b/CSharpBible/Games/Werner_Flaschbier.Console2/Werner_Flaschbier.Console2.csproj
new file mode 100644
index 000000000..d2a6da173
--- /dev/null
+++ b/CSharpBible/Games/Werner_Flaschbier.Console2/Werner_Flaschbier.Console2.csproj
@@ -0,0 +1,30 @@
+
+
+
+ net462;net472;net48;net481;net6.0;net7.0;net8.0;net9.0
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CSharpBible/Games/Werner_Flaschbier/Model/WernerGame.cs b/CSharpBible/Games/Werner_Flaschbier/Model/WernerGame.cs
index b4dd809a1..ab4907147 100644
--- a/CSharpBible/Games/Werner_Flaschbier/Model/WernerGame.cs
+++ b/CSharpBible/Games/Werner_Flaschbier/Model/WernerGame.cs
@@ -163,7 +163,7 @@ public Tiles GetTile(Point p)
public Point OldPos(Point p)
{
var field = playfield[p];
- if (field is Space s && s.Item != null)
+ if (field is Space s && s.Item != null && !(s.Item is Dirt) )
return s.Item.OldPosition;
else
return p;
@@ -242,7 +242,11 @@ public int GameStep()
foreach (PlayObject po in playfield.ActiveObjects)
po.Handled = false;
foreach (Space sp in playfield.Spaces)
+ {
sp.OldItem = sp.Item;
+ if (sp.Item != null)
+ sp.Item.OldPosition = sp.Position;
+ }
playfield.player?.TryMove(actDir);
actDir = nextDir;
nextDir = nextDir2;
diff --git a/CSharpBible/Graphics/All_Graphics/Models/AllExampleModel.cs b/CSharpBible/Graphics/All_Graphics/Models/AllExampleModel.cs
index f8165ef18..f2521dc81 100644
--- a/CSharpBible/Graphics/All_Graphics/Models/AllExampleModel.cs
+++ b/CSharpBible/Graphics/All_Graphics/Models/AllExampleModel.cs
@@ -94,7 +94,7 @@ public AllExampleModel()
try
{
Debug.WriteLine($"{ex.Description} {ex.ExType}");
- var desc = new Dictionary();
+ var desc = new Dictionary();
Type? t = ex.ExType.Assembly.GetTypes().First((t) => t.Name.EndsWith(nameof(Resources)));
if (t != null)
{
@@ -102,7 +102,7 @@ public AllExampleModel()
if (prop.PropertyType == typeof(string))
{
Debug.WriteLine($" {prop.Name} {prop.PropertyType} ");
- desc[prop.Name] = (string)prop.GetValue(null);
+ desc[prop.Name] = (string?)prop.GetValue(null);
}
ex.Additionals = desc;
}
diff --git a/CSharpBible/Graphics/All_Graphics/ViewModels/AllExamplesViewModel.cs b/CSharpBible/Graphics/All_Graphics/ViewModels/AllExamplesViewModel.cs
index 0c6b0e692..92b0b08f4 100644
--- a/CSharpBible/Graphics/All_Graphics/ViewModels/AllExamplesViewModel.cs
+++ b/CSharpBible/Graphics/All_Graphics/ViewModels/AllExamplesViewModel.cs
@@ -38,7 +38,7 @@ public partial class AllExamplesViewModel : BaseViewModelCT
private ObservableCollection _examples = new();
[ObservableProperty]
- string _exFilter;
+ string? _exFilter;
#endregion
#region Methods
@@ -57,7 +57,7 @@ public AllExamplesViewModel(ITemplateModel model)
OnExFilterChanged(ExFilter);
}
- private void OnMPropertyChanged(object sender, PropertyChangedEventArgs e)
+ private void OnMPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e.PropertyName);
}
diff --git a/CSharpBible/Graphics/CanvasWPF/CanvasWPF.csproj b/CSharpBible/Graphics/CanvasWPF/CanvasWPF.csproj
index c1b0498ce..a5dbb0be1 100644
--- a/CSharpBible/Graphics/CanvasWPF/CanvasWPF.csproj
+++ b/CSharpBible/Graphics/CanvasWPF/CanvasWPF.csproj
@@ -2,12 +2,18 @@
WinExe
- net472;net48;net481;net6.0-windows;net7.0-windows;net8.0-windows
+ net472;net48;net481;net8.0-windows
true
AnyCPU;x64
+
+ $(TargetFrameworks);net9.0-windows
+
+
+ $(TargetFrameworks);net10.0-windows
+
CanvasWPF
true
diff --git a/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/CanvasWPF2_CTItemTemplateSelector.csproj b/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/CanvasWPF2_CTItemTemplateSelector.csproj
index 82b50447f..8192f8718 100644
--- a/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/CanvasWPF2_CTItemTemplateSelector.csproj
+++ b/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/CanvasWPF2_CTItemTemplateSelector.csproj
@@ -2,12 +2,18 @@
WinExe
- net472;net48;net481;net6.0-windows;net7.0-windows
+ net472;net48;net481;net8.0-windows
true
AnyCPU;x64
+
+ $(TargetFrameworks);net9.0-windows
+
+
+ $(TargetFrameworks);net10.0-windows
+
false
false
diff --git a/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/ViewModels/MainWindowViewmodel.cs b/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/ViewModels/MainWindowViewmodel.cs
index adcc3215b..81966eb58 100644
--- a/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/ViewModels/MainWindowViewmodel.cs
+++ b/CSharpBible/Graphics/CanvasWPF2_CTItemTemplateSelector/ViewModels/MainWindowViewmodel.cs
@@ -119,7 +119,7 @@ private void SelectShape(object? o)
private void CreateRectangle()
{
lock (Shapes)
- Shapes.Add(new ShapeData(_rnd.Next(0, 600), _rnd.Next(0, 400)) { Dx = _rnd.NextDouble() * 40 - 20, Dy = _rnd.NextDouble() * 40 - 20, SType = 0, MouseHover = new DelegateCommand
/// The mouse left button down.
- public DelegateCommand