Refactor and clean up codebase:

- Introduced `IGameRepository` interface and its implementation.
- Transitioned namespaces to `file-scoped` for consistency.
- Simplified class definitions, e.g., `Game` and `SixDigitInt`.
- Restructured `GameField` logic for improved readability and functionality.
- Fixed formatting issues in `API.csproj` and added a `using` directive in `Program.cs`.
This commit is contained in:
2026-02-27 20:36:44 +01:00
committed by Jonas
parent 5db7ac1676
commit b967bd70eb
11 changed files with 153 additions and 157 deletions
+2 -6
View File
@@ -7,12 +7,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.12" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.12"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Repository\" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+5 -5
View File
@@ -4,18 +4,18 @@ namespace API.Controllers;
public class GameHubSocket : Hub public class GameHubSocket : Hub
{ {
public async Task CreateGame(string playerName, ) public async Task CreateGame(string playerName)
{ {
await Groups.AddToGroupAsync(Context.ConnectionId, gameId); // TODO: create
await Clients.Group(gameId).SendAsync("PlayerJoined", new await Groups.AddToGroupAsync(Context.ConnectionId, "gameId");
await Clients.Group("gameId").SendAsync("PlayerJoined", new
{ {
ConnectionId = Context.ConnectionId, Context.ConnectionId,
PlayerName = playerName PlayerName = playerName
}); });
} }
public async Task JoinGame(string gameId, string playerName) public async Task JoinGame(string gameId, string playerName)
{ {
} }
} }
+12 -7
View File
@@ -1,9 +1,7 @@
namespace API.Models.DataClasses namespace API.Models.DataClasses;
{
public readonly record struct SixDigitInt
{
public int Value { get; }
public readonly record struct SixDigitInt
{
public SixDigitInt(int value) public SixDigitInt(int value)
{ {
if (value < 0 || value > 999999) if (value < 0 || value > 999999)
@@ -13,8 +11,15 @@
Value = value; Value = value;
} }
public override string ToString() => Value.ToString("D6"); public int Value { get; }
public static implicit operator int(SixDigitInt v) => v.Value; public override string ToString()
{
return Value.ToString("D6");
}
public static implicit operator int(SixDigitInt v)
{
return v.Value;
} }
} }
+8 -15
View File
@@ -1,26 +1,19 @@
using API.Models.DataClasses; using API.Models.DataClasses;
namespace API.Models.Game namespace API.Models.Game;
public enum GameState
{ {
public enum GameState
{
Lobby, Lobby,
Running, Running,
Ended Ended
} }
public class Game public class Game(Coordinates gFs, SixDigitInt gameCode)
{ {
public string Id { get; init; } = Guid.NewGuid().ToString(); public string Id { get; init; } = Guid.NewGuid().ToString();
public SixDigitInt GameCode { get; } public SixDigitInt GameCode { get; } = gameCode;
public string?[] PlayerConnectionIds { get; set; } = new string?[2]; public string?[] PlayerConnectionIds { get; set; } = new string?[2];
public GameState State { get; private set; } = GameState.Lobby; public GameState State { get; private set; } = GameState.Lobby;
public GameField Field { get; } public GameField Field { get; } = new(gFs);
public Game(Coordinates gFs, SixDigitInt gameCode)
{
Field = new GameField(gFs);
GameCode = gameCode;
}
}
} }
+14 -21
View File
@@ -1,32 +1,32 @@
namespace API.Models.Game namespace API.Models.Game;
public class Coordinates
{ {
public class Coordinates
{
public int X; public int X;
public int Y; public int Y;
} }
public enum PlaceResult public enum PlaceResult
{ {
OutOfGameField, OutOfGameField,
NotAllowedPlayer, NotAllowedPlayer,
OccupiedRed, OccupiedRed,
OccupiedYellow, OccupiedYellow,
InvalidFieldValue, InvalidFieldValue,
Placed Placed
} }
public enum FieldState public enum FieldState
{ {
OutOfGameField, OutOfGameField,
Empty, Empty,
OccupiedRed, OccupiedRed,
OccupiedYellow, OccupiedYellow,
InvalidFieldValue InvalidFieldValue
} }
public class GameField(Coordinates gFs) public class GameField(Coordinates gFs)
{ {
public int[,] CurrentField { get; } = new int[gFs.Y, gFs.X]; public int[,] CurrentField { get; } = new int[gFs.Y, gFs.X];
public int[,] BackupField { get; } = new int[gFs.Y, gFs.X]; public int[,] BackupField { get; } = new int[gFs.Y, gFs.X];
@@ -34,24 +34,20 @@
{ {
if (coordinates.X < 0 || coordinates.X >= CurrentField.GetLength(1) || if (coordinates.X < 0 || coordinates.X >= CurrentField.GetLength(1) ||
coordinates.Y < 0 || coordinates.Y >= CurrentField.GetLength(0)) coordinates.Y < 0 || coordinates.Y >= CurrentField.GetLength(0))
{
return PlaceResult.OutOfGameField; return PlaceResult.OutOfGameField;
}
if (player != 1 && player != 2) if (player != 1 && player != 2)
return PlaceResult.NotAllowedPlayer; return PlaceResult.NotAllowedPlayer;
int currentValue = CurrentField[coordinates.Y, coordinates.X]; var currentValue = CurrentField[coordinates.Y, coordinates.X];
if (currentValue != 0) if (currentValue != 0)
{
return currentValue switch return currentValue switch
{ {
1 => PlaceResult.OccupiedRed, 1 => PlaceResult.OccupiedRed,
2 => PlaceResult.OccupiedYellow, 2 => PlaceResult.OccupiedYellow,
_ => PlaceResult.InvalidFieldValue _ => PlaceResult.InvalidFieldValue
}; };
}
CreateSave(); CreateSave();
CurrentField[coordinates.Y, coordinates.X] = player; CurrentField[coordinates.Y, coordinates.X] = player;
@@ -63,11 +59,9 @@
{ {
if (coordinates.X < 0 || coordinates.X >= CurrentField.GetLength(1) || if (coordinates.X < 0 || coordinates.X >= CurrentField.GetLength(1) ||
coordinates.Y < 0 || coordinates.Y >= CurrentField.GetLength(0)) coordinates.Y < 0 || coordinates.Y >= CurrentField.GetLength(0))
{
return FieldState.OutOfGameField; return FieldState.OutOfGameField;
}
int currentValue = CurrentField[coordinates.Y, coordinates.X]; var currentValue = CurrentField[coordinates.Y, coordinates.X];
return currentValue switch return currentValue switch
{ {
@@ -82,5 +76,4 @@
{ {
Array.Copy(CurrentField, BackupField, CurrentField.Length); Array.Copy(CurrentField, BackupField, CurrentField.Length);
} }
}
} }
+2 -1
View File
@@ -1,3 +1,4 @@
using API.Controllers;
using API.Services.GameManager; using API.Services.GameManager;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@@ -28,7 +29,7 @@ app.UseStaticFiles();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();
app.MapHub<API.Controllers.GameHubSocket>("/api/gamehub"); app.MapHub<GameHubSocket>("/api/gamehub");
app.MapFallbackToFile("index.html"); app.MapFallbackToFile("index.html");
+5
View File
@@ -0,0 +1,5 @@
namespace API.Repository.Game;
public class GameRepository : IGameRepository
{
}
+5
View File
@@ -0,0 +1,5 @@
namespace API.Repository.Game;
public interface IGameRepository
{
}
+3 -4
View File
@@ -1,7 +1,7 @@
namespace API.Services.GameManager namespace API.Services.GameManager;
public class GameManager : IGameManager
{ {
public class GameManager : IGameManager
{
public int CreateGame(string playerName) public int CreateGame(string playerName)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@@ -16,5 +16,4 @@
{ {
return 0; return 0;
} }
}
} }
+3 -4
View File
@@ -1,8 +1,7 @@
namespace API.Services.GameManager namespace API.Services.GameManager;
public interface IGameManager
{ {
public interface IGameManager
{
public int CreateGame(string playerName); public int CreateGame(string playerName);
public bool JoinGame(string playerName, int gameCode); public bool JoinGame(string playerName, int gameCode);
}
} }