diff --git a/src/LittleTown.Api/LittleTown.Api.csproj b/src/LittleTown.Api/LittleTown.Api.csproj new file mode 100644 index 0000000..7b8542a --- /dev/null +++ b/src/LittleTown.Api/LittleTown.Api.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + true + + + + + + + + diff --git a/src/LittleTown.Api/LittleTown.Api.http b/src/LittleTown.Api/LittleTown.Api.http new file mode 100644 index 0000000..c5d8e87 --- /dev/null +++ b/src/LittleTown.Api/LittleTown.Api.http @@ -0,0 +1,6 @@ +@LittleTown.Api_HostAddress = http://localhost:5166 + +GET {{LittleTown.Api_HostAddress}}/helloWorld/ +Accept: application/json + +### diff --git a/src/LittleTown.Api/Program.cs b/src/LittleTown.Api/Program.cs new file mode 100644 index 0000000..c9ad401 --- /dev/null +++ b/src/LittleTown.Api/Program.cs @@ -0,0 +1,26 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.MapGet("/helloWorld", () => +{ + return "Hello World"; +}) +.WithName("HelloWorld") +.WithOpenApi(); + +app.Run(); diff --git a/src/LittleTown.Api/Properties/launchSettings.json b/src/LittleTown.Api/Properties/launchSettings.json new file mode 100644 index 0000000..d6325d6 --- /dev/null +++ b/src/LittleTown.Api/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:12798", + "sslPort": 44325 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5166", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7114;http://localhost:5166", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/LittleTown.Api/appsettings.Development.json b/src/LittleTown.Api/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/LittleTown.Api/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/LittleTown.Api/appsettings.json b/src/LittleTown.Api/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/src/LittleTown.Api/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/LittleTown.Core.Tests/MatchTesting.cs b/src/LittleTown.Core.Tests/MatchTesting.cs index f7e7825..8a3698a 100644 --- a/src/LittleTown.Core.Tests/MatchTesting.cs +++ b/src/LittleTown.Core.Tests/MatchTesting.cs @@ -1,4 +1,5 @@ using LittleTown.Core.Enums; +using LittleTown.Core.Exceptions; using LittleTown.StaticDataAcces; namespace LittleTown.Core.Tests; @@ -9,25 +10,47 @@ public class MatchTesting public void EnforcePlayerCountInMatchCreation() { StaticDataGetter getter = new(); - Assert.Throws(() => { new Match(1, getter); }); + var match = new Match(getter); + match.AddPlayer("Player1"); + Assert.Throws(() => { match.Init(); }); - Match match2Player = new Match(2, getter); + Match match2 = new Match(getter); + match2.AddPlayer("Player1"); + match2.AddPlayer("Player2"); + match2.Init(); - Match match3Player = new Match(3, getter); + Match match3 = new Match(getter); + match3.AddPlayer("Player1"); + match3.AddPlayer("Player2"); + match3.AddPlayer("Player3"); + match3.Init(); - Match match4Player = new Match(4, getter); + Match match4 = new Match(getter); + match4.AddPlayer("Player1"); + match4.AddPlayer("Player2"); + match4.AddPlayer("Player3"); + match4.AddPlayer("Player4"); + match4.Init(); - Assert.Throws(() => { new Match(5, getter); }); + Match match5 = new Match(getter); + match5.AddPlayer("Player1"); + match5.AddPlayer("Player2"); + match5.AddPlayer("Player3"); + match5.AddPlayer("Player4"); + Assert.Throws(() => { match5.AddPlayer("Player5"); }); } [Fact] public void TwoPlayerInitMatchTest() { StaticDataGetter getter = new(); - Match match = new Match(2, getter); + Match match = new Match(getter); + match.AddPlayer("Player1"); + match.AddPlayer("Player2"); + match.Init(); - PlayerZone player1 = match.GetPlayerZone(0); - PlayerZone player1_3 = match.GetPlayerZone(0); + PlayerZone player1 = match.GetPlayerZone("Player1"); + PlayerZone player1_3 = match.GetPlayerZone("Player2"); Assert.Equal(3, player1.Ressources[Enums.ResourceType.Piece]); player1.AddRessources(ResourceType.Piece, 1); Assert.Equal(3, player1_3.Ressources[Enums.ResourceType.Piece]); diff --git a/src/LittleTown.Core/MatchAggregate/Match.cs b/src/LittleTown.Core/MatchAggregate/Match.cs index b411451..4ddbb74 100644 --- a/src/LittleTown.Core/MatchAggregate/Match.cs +++ b/src/LittleTown.Core/MatchAggregate/Match.cs @@ -20,7 +20,7 @@ public class Match private Random _random = new Random(); - private Dictionary _playersZones = new Dictionary(); + private Dictionary _players = new(); /// LE numero du tour en cours (Partant de 1) public int CurrentTurn { get; private set; } = 1; @@ -33,31 +33,52 @@ public class Match /// /// /// un objet permettant de récupérer les données statiques du jeu - public Match(int nbPlayer, IStaticDataGetter staticData) + public Match(IStaticDataGetter staticData) { ArgumentNullException.ThrowIfNull(staticData); - ArgumentOutOfRangeException.ThrowIfLessThan(nbPlayer, _minPlayerCount); - ArgumentOutOfRangeException.ThrowIfGreaterThan(nbPlayer, _maxPlayerCount); _board = staticData.GetBoard(1); _buildings = staticData.GetBuildings(); _objectives = staticData.GetObjectives(); + } + + /// Ajouter un nouveau joueur a la partie + /// le nom du joueur + public void AddPlayer(string playerName) + { + if (_players.Count < _maxPlayerCount) + { + if (_players.ContainsKey(playerName)) + { + throw new MatchConfigException("Un joueur existe déjà avec ce nom"); + } + _players.Add(playerName, new PlayerZone()); + } + else + { + throw new MatchConfigException("Impossible d'ajouter de nouveau joueur, la partie est pleine"); + } + } + + /// Initialiser la partie, il faut avoir ajouté les joueurs au préalable + /// + public void Init() + { + int nbPlayer = _players.Count; + + ArgumentOutOfRangeException.ThrowIfLessThan(nbPlayer, _minPlayerCount); + ArgumentOutOfRangeException.ThrowIfGreaterThan(nbPlayer, _maxPlayerCount); List freeObjectiveIndexs = Enumerable.Range(0, _objectives.Count).ToList(); - for (int i = 0; i < nbPlayer; i++) + foreach (PlayerZone zone in _players.Values) { - PlayerZone zone = new PlayerZone() + zone.AddObjectives(GetRandomObjectives(nbPlayer switch { - Objectives = GetRandomObjectives(nbPlayer switch - { - 2 => 4, - 3 => 3, - 4 => 2, - _ => throw new MatchConfigException("Mauvais nombre de joueurs lors des objectifs") - }, freeObjectiveIndexs) - }; + 2 => 4, + 3 => 3, + 4 => 2, + }, freeObjectiveIndexs)); zone.AddRessources(Enums.ResourceType.Piece, 3); - _playersZones.Add(i, zone); } _maxWorkerPerPlayer = nbPlayer switch @@ -84,17 +105,18 @@ public class Match if (index >= nbPlayer) index = 0; } + } /// Permet de récuperer une player zone(une copie) - /// + /// le nom ou ID du joueur /// - public PlayerZone GetPlayerZone(int playerId) + public PlayerZone GetPlayerZone(string playerName) { - ArgumentOutOfRangeException.ThrowIfLessThan(playerId, 0); - ArgumentOutOfRangeException.ThrowIfGreaterThan(playerId, _playersZones.Count - 1); + if (!_players.TryGetValue(playerName, out PlayerZone? value)) + throw new ArgumentException("playerID is out of bound"); - return _playersZones[playerId].Clone() as PlayerZone ?? throw new ArgumentException("playerID is out of bound"); + return value.Clone() as PlayerZone ?? throw new ArgumentException("Cast exception in GetPlayerZone"); ; } private List GetRandomObjectives(int number, List freeIndex) diff --git a/src/LittleTown.Core/PlayerZone/Objective.cs b/src/LittleTown.Core/PlayerZone/Objective.cs index 2288576..268110c 100644 --- a/src/LittleTown.Core/PlayerZone/Objective.cs +++ b/src/LittleTown.Core/PlayerZone/Objective.cs @@ -6,7 +6,7 @@ namespace LittleTown.Core; public class Objective { /// la description, une clé pour la traduction - public string Description { get; init; } + public required string Description { get; init; } /// la condition de l'objectif sous forme de formule public string Formula { get; init; } = string.Empty; diff --git a/src/LittleTown.Core/PlayerZone/PlayerZone.cs b/src/LittleTown.Core/PlayerZone/PlayerZone.cs index b8aac26..1598ad3 100644 --- a/src/LittleTown.Core/PlayerZone/PlayerZone.cs +++ b/src/LittleTown.Core/PlayerZone/PlayerZone.cs @@ -7,8 +7,11 @@ public class PlayerZone : ICloneable /// Les ressources que possede le joueur public IDictionary Ressources { get; init; } = new Dictionary(); + + /// La liste des objectifs que le joueur possede/// - public IReadOnlyCollection Objectives { get; init; } = new List(); + public IReadOnlyCollection Objectives { get => _objectives.AsReadOnly(); init => _objectives = new List(value); } + private List _objectives = new List(); /// Le marqueur de score pendant le match public int ScoreMarker { get; init; } @@ -29,6 +32,11 @@ public class PlayerZone : ICloneable } } + public void AddObjectives(ICollection objectives) + { + _objectives.AddRange(objectives); + } + /// Cloner ce playerZone /// Une copie de l'objet public object Clone() diff --git a/src/LittleTown.sln b/src/LittleTown.sln index 300dd8f..9a9743a 100644 --- a/src/LittleTown.sln +++ b/src/LittleTown.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LittleTown.Core.Tests", "Li EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LittleTown.StaticDataAccess", "LittleTown.StaticDataAccess\LittleTown.StaticDataAccess.csproj", "{FA0DE9D0-F788-4734-BDA3-F89F71D757BA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LittleTown.Api", "LittleTown.Api\LittleTown.Api.csproj", "{87327E52-A393-44C1-8247-EE51753F975F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -30,5 +32,9 @@ Global {FA0DE9D0-F788-4734-BDA3-F89F71D757BA}.Debug|Any CPU.Build.0 = Debug|Any CPU {FA0DE9D0-F788-4734-BDA3-F89F71D757BA}.Release|Any CPU.ActiveCfg = Release|Any CPU {FA0DE9D0-F788-4734-BDA3-F89F71D757BA}.Release|Any CPU.Build.0 = Release|Any CPU + {87327E52-A393-44C1-8247-EE51753F975F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87327E52-A393-44C1-8247-EE51753F975F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87327E52-A393-44C1-8247-EE51753F975F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87327E52-A393-44C1-8247-EE51753F975F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal