diff --git a/Src/Giants.Core/Src/Commands/PrepareMatchCommand.cs b/Src/Giants.Core/Src/Commands/PrepareMatchCommand.cs index 995ddda..e789a62 100644 --- a/Src/Giants.Core/Src/Commands/PrepareMatchCommand.cs +++ b/Src/Giants.Core/Src/Commands/PrepareMatchCommand.cs @@ -1,41 +1,58 @@ -using System.Security.Claims; -using System.Security.Cryptography.X509Certificates; +using Giants.Core.Enums; +using Giants.Core.Exceptions; namespace Giants.Core.Commands; public class PrepareMatchCommand : BaseMatchCommand { - public required int NbPlayer { get; init; } + public required IList PlayerIDs { get; init; } protected override PrepareMatchResult LocalMatchExecute(Match match) { - if (NbPlayer < 3 || NbPlayer > 5) + if (PlayerIDs.Count < 3 || PlayerIDs.Count > 5 || null == match) return new PrepareMatchResult(); //Gestion des assets des joueurs - for (int i = 0; i < NbPlayer; i++) + for (int i = 0; i < PlayerIDs.Count; i++) { + match.SetPlayer(i, PlayerIDs[i]); //marqueurs tribaux - int nbMarker = NbMarkerPerPlayer(NbPlayer); - for (int t = 0; t < nbMarker; t++) + int nbMarker = NbMarkerPerPlayer(PlayerIDs.Count); + for (int t = 0; t < Match.MaxTribalMarker; t++) { + if (t < nbMarker) + { + match.AddTribalMarkerToPlayer(i); + } + else + { + var piece = match.GetPlayerTribalTokenFromBox(i); + match.AssignPiece(piece, PiecePosition.Urne); + } } } - return new PrepareMatchResult(); + return new PrepareMatchResult() + { + Success = true, + Match = match + }; } - private int NbMarkerPerPlayer(int nbTotalPlayer) + private static int NbMarkerPerPlayer(int nbTotalPlayer) { return nbTotalPlayer switch { 3 => 7, 4 => 6, 5 => 5, - _ => throw new Exception("Wrong player count for NbMarkerPerPlayer") + _ => throw new DataConversionException("Wrong player count for NbMarkerPerPlayer") }; } } -public class PrepareMatchResult : BaseCommandResult { } +public class PrepareMatchResult : BaseCommandResult +{ + public Match? Match { get; init; } +} diff --git a/Src/Giants.Core/Src/Entities/Match.cs b/Src/Giants.Core/Src/Entities/Match.cs index f888758..5f23610 100644 --- a/Src/Giants.Core/Src/Entities/Match.cs +++ b/Src/Giants.Core/Src/Entities/Match.cs @@ -1,3 +1,5 @@ +using System.Collections; +using System.Reflection.Metadata.Ecma335; using Giants.Core.Enums; namespace Giants.Core; @@ -41,11 +43,83 @@ public class Match #endregion - #region acessors for commands + #region Getters + public static int MaxTribalMarker { get => 6; } + + public int NbPlayer { get => players.Count(p => p != -1); } + + public Player? GetPlayer(int index) + { + if (index >= 0 && index < players.Length && players[index] != -1) + return new Player(this) + { + Index = index, + }; + + return null; + } + + public PieceIndex GetPlayerTribalTokenFromBox(int playerIndex) + { + PieceIndex firstMarker = playerIndex switch + { + 0 => PieceIndex.player1TribalMarker1, + 1 => PieceIndex.player1TribalMarker2, + 2 => PieceIndex.player1TribalMarker3, + 3 => PieceIndex.player1TribalMarker4, + 4 => PieceIndex.player1TribalMarker5, + _ => throw new ArgumentOutOfRangeException($"{playerIndex} is invalid player Index") + }; + for (int i = 0; i < MaxTribalMarker; i++) + { + PieceIndex piece = firstMarker + i; + if (GetPiece(piece) == PiecePosition.boite) + { + return piece; + } + } + + return PieceIndex.Unknown; + } + #endregion + + #region Setters for commands public void AssignPiece(PieceIndex piece, PiecePosition position) { pieces[(int)piece] = position; + } + public void SetPlayer(int index, int playerId) + { + players[index] = playerId; + } + + public PiecePosition GetPiece(PieceIndex PieceIndex) + { + return pieces[(int)PieceIndex]; + } + + public void AddTribalMarkerToPlayer(int playerId) + { + PieceIndex firstElem = PieceIndex.StartPlayer; + PiecePosition target = PiecePosition.boite; + + switch (playerId) + { + case 0: firstElem = PieceIndex.player1TribalMarker1; target = PiecePosition.player1Visible; break; + case 1: firstElem = PieceIndex.player2TribalMarker1; target = PiecePosition.player2Visible; break; + case 2: firstElem = PieceIndex.player3TribalMarker1; target = PiecePosition.player3Visible; break; + case 3: firstElem = PieceIndex.player4TribalMarker1; target = PiecePosition.player4Visible; break; + case 4: firstElem = PieceIndex.player5TribalMarker1; target = PiecePosition.player5Visible; break; + } + for (int i = 0; i < 6; i++) + { + if (GetPiece(firstElem + i) == PiecePosition.boite) + { + AssignPiece(firstElem + i, target); + break; + } + } } #endregion diff --git a/Src/Giants.Core/Src/Entities/Player.cs b/Src/Giants.Core/Src/Entities/Player.cs new file mode 100644 index 0000000..1dbf045 --- /dev/null +++ b/Src/Giants.Core/Src/Entities/Player.cs @@ -0,0 +1,77 @@ +using System.Reflection.Metadata.Ecma335; +using Giants.Core.Enums; + +namespace Giants.Core; + +/// +/// Structure pour agréger les getters liés aux informations d'un joueur +/// +public class Player +{ + private Match _match; + public required int Index { get; init; } + + public Player(Match match) + { + _match = match; + } + + public int NbVisibleTribalTokenCount + { + get + { + int result = 0; + var fisrtIndex = FirstTribalMarker; + for (int i = 0; i < Match.MaxTribalMarker; i++) + { + var pos = _match.GetPiece(fisrtIndex + i); + if (pos.ToString().Contains("Visible")) + { + result++; + } + } + return result; + } + } + + public int NbHiddenTribalTokenCount + { + get + { + { + int result = 0; + var fisrtIndex = FirstTribalMarker; + for (int i = 0; i < Match.MaxTribalMarker; i++) + { + var pos = _match.GetPiece(fisrtIndex + i); + if (pos.ToString().Contains("hidden")) + { + result++; + } + } + return result; + } + } + } + + public int NbUrnTribalTokenCount + { + get + { + int result = 0; + var fisrtIndex = FirstTribalMarker; + for (int i = 0; i < Match.MaxTribalMarker; i++) + { + var pos = _match.GetPiece(fisrtIndex + i); + if (pos == PiecePosition.Urne) + { + result++; + } + } + + return result; + } + } + + private PieceIndex FirstTribalMarker { get => (PieceIndex)Enum.Parse(typeof(PieceIndex), $"player1TribalMarker{Index + 1}"); } +} \ No newline at end of file diff --git a/Src/Giants.Core/Src/Enums/PieceIndex.cs b/Src/Giants.Core/Src/Enums/PieceIndex.cs index d28c373..bcef5fe 100644 --- a/Src/Giants.Core/Src/Enums/PieceIndex.cs +++ b/Src/Giants.Core/Src/Enums/PieceIndex.cs @@ -2,6 +2,7 @@ namespace Giants.Core.Enums; public enum PieceIndex { + Unknown, StartPlayer, player1Chief, player1Shaman, diff --git a/Src/Giants.Core/Src/Exceptions/DataConversionException.cs b/Src/Giants.Core/Src/Exceptions/DataConversionException.cs new file mode 100644 index 0000000..33a16fc --- /dev/null +++ b/Src/Giants.Core/Src/Exceptions/DataConversionException.cs @@ -0,0 +1,14 @@ +namespace Giants.Core.Exceptions; + +/// +/// Exception levée lors d'un probleme de conversion d'un objet du core +/// +public class DataConversionException : System.Exception +{ + /// > + public DataConversionException() { } + /// > + public DataConversionException(string message) : base(message) { } + /// > + public DataConversionException(string message, System.Exception inner) : base(message, inner) { } +} \ No newline at end of file diff --git a/Tests/Giants.Core.Tests/Commands/PrepareMatchCommandTest.cs b/Tests/Giants.Core.Tests/Commands/PrepareMatchCommandTest.cs new file mode 100644 index 0000000..135e61c --- /dev/null +++ b/Tests/Giants.Core.Tests/Commands/PrepareMatchCommandTest.cs @@ -0,0 +1,40 @@ +using Giants.Application; +using Giants.Core.Commands; +using Giants.Core.Interfaces; +using Giants.Infrastructure; + +namespace Giants.Core.Tests; + +public class PrepareMatchCommandTest +{ + private readonly IMatchRepository _repo; + + public PrepareMatchCommandTest() + { + IHexagonalGrid _grid = new HexagonalGridImpl(); + BoardLayout layout = new BoardLayout(_grid); + _repo = new MatchRepositoryMock(layout); + } + + [Fact] + void SimpleInit() + { + NewMatchCommand command = new NewMatchCommand(_repo); + NewMatchResult result = command.Execute(); + Match? m = result.Match; + Assert.NotNull(m); + + PrepareMatchCommand prepCommand = new PrepareMatchCommand() { InputMatch = m, PlayerIDs = new List() { 12, 15, 5, 14, 9 } }; + var resultPrep = prepCommand.Execute(); + Assert.True(resultPrep.Success); + Assert.NotNull(resultPrep?.Match); + + Player? p1 = resultPrep.Match.GetPlayer(0); + Assert.NotNull(p1); + + Assert.Equal(5, p1.NbVisibleTribalTokenCount); + Assert.Equal(0, p1.NbHiddenTribalTokenCount); + Assert.Equal(1, p1.NbUrnTribalTokenCount); + + } +} \ No newline at end of file