diff --git a/Sources/Model/Games/Game.cs b/Sources/Model/Games/Game.cs
index 96dfbbf..ba75d6a 100644
--- a/Sources/Model/Games/Game.cs
+++ b/Sources/Model/Games/Game.cs
@@ -1,209 +1,219 @@
-using Model.Dice;
-using Model.Dice.Faces;
-using Model.Players;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-using System.Text;
-
-namespace Model.Games
-{
- public class Game
- {
- ///
- /// the name of the game 😎
- ///
- public string Name
- {
- get
- {
- return name;
- }
- set // GameRunner will need to take care of forbidding
- // (or allowing) having two Games with the same name etc.
- {
- if (string.IsNullOrWhiteSpace(value))
- {
- throw new ArgumentException("param should not be null or blank", nameof(value));
- }
- name = value;
- }
- }
- private string name;
-
- ///
- /// references the position in list of the current player, for a given game.
- ///
- private int nextIndex;
-
- ///
- /// the turns that have been done so far
- ///
- private readonly List turns;
-
- ///
- /// get a READ ONLY enumerable of all turns belonging to this game
- ///
- /// a readonly enumerable of all this game's turns
- public IEnumerable GetHistory() => turns.AsEnumerable();
-
- ///
- /// the game's player manager, doing CRUD on players and switching whose turn it is
- ///
- private readonly IManager playerManager;
-
- ///
- /// the group of dice used for this game
- ///
- public IEnumerable> Dice => dice;
- private readonly IEnumerable> dice;
-
- ///
- /// constructs a Game with its own history of Turns.
- /// If is null, starts a new history
- ///
- /// the name of the game 😎
- /// the turns that have been done so far
- /// the game's player manager, doing CRUD on players and switching whose turn it is
- /// the group of dice used for this game
- public Game(string name, IManager playerManager, IEnumerable> dice, IEnumerable turns)
- {
- Name = name;
- this.turns = turns is null ? new List() : turns.ToList();
- this.playerManager = playerManager;
- this.dice = dice;
- this.nextIndex = 0;
- }
-
- ///
- /// constructs a Game with no history of turns.
- ///
- /// the name of the game 😎
- /// the game's player manager, doing CRUD on players and switching whose turn it is
- /// the group of dice used for this game
- public Game(string name, IManager playerManager, IEnumerable> dice)
- : this(name, playerManager, dice, null)
- { }
-
- ///
- /// performs a Turn, marks this Game as "started", and logs that Turn
- ///
- /// the player whose turn it is
- public void PerformTurn(Player player)
- {
- Turn turn = Turn.CreateWithDefaultTime(
- player,
- ThrowAll()
- );
- turns.Add(turn);
- }
-
- ///
- /// finds and returns the player whose turn it is
- ///
- ///
- ///
- public Player GetWhoPlaysNow()
- {
- if (!playerManager.GetAll().Any())
- {
- throw new MemberAccessException("you are exploring an empty collection\nthis should not have happened");
- }
- return playerManager.GetAll().ElementAt(nextIndex);
- }
-
- ///
- /// this feels very dirty
- ///
- /// the current player
- ///
- ///
- ///
- public void PrepareNextPlayer(Player current)
- {
- if (!playerManager.GetAll().Any())
- {
- throw new MemberAccessException("you are exploring an empty collection\nthis should not have happened");
- }
- if (current == null)
- {
- throw new ArgumentNullException(nameof(current), "param should not be null");
- }
- if (!playerManager.GetAll().Contains(current))
- {
- throw new ArgumentException("param could not be found in this collection\n did you forget to add it?", nameof(current));
- }
- if (playerManager.GetAll().Last() == current)
- {
- // if we've reached the last player, we need the index to loop back around
- nextIndex = 0;
- }
- else
- {
- // else we can just move up by one from the current index
- nextIndex++;
- }
- }
-
- ///
- /// throws all the Dice in FavGroup and returns a list of their Faces
- ///
- /// list of AbstractDieFaces after a throw
- private Dictionary, AbstractDieFace> ThrowAll()
- {
- Dictionary, AbstractDieFace> faces = new();
- foreach (AbstractDie die in dice)
- {
- faces.Add(die, die.GetRandomFace());
- }
- return faces;
- }
-
- public Player AddPlayerToGame(Player player)
- {
- return playerManager.Add(player);
- }
-
- public IEnumerable GetPlayersFromGame()
- {
- return playerManager.GetAll();
- }
-
- public Player UpdatePlayerInGame(Player oldPlayer, Player newPlayer)
- {
- return playerManager.Update(oldPlayer, newPlayer);
- }
-
- public void RemovePlayerFromGame(Player player)
- {
- playerManager.Remove(player);
- }
-
- ///
- /// represents a Game in string format
- ///
- /// a Game in string format
- public override string ToString()
- {
- StringBuilder sb = new();
- sb.Append($"Game: {Name}");
-
- sb.Append("\nPlayers:");
- foreach (Player player in GetPlayersFromGame())
- {
- sb.Append($" {player.ToString()}");
- }
-
- sb.Append($"\nNext: {GetWhoPlaysNow()}");
-
- sb.Append("\nLog:\n");
- foreach (Turn turn in this.turns)
- {
- sb.Append($"\t{turn.ToString()}\n");
- }
-
- return sb.ToString();
- }
- }
-}
+using Model.Dice;
+using Model.Dice.Faces;
+using Model.Players;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+
+namespace Model.Games
+{
+ public class Game
+ {
+ ///
+ /// the name of the game 😎
+ ///
+ public string Name
+ {
+ get
+ {
+ return name;
+ }
+ set // GameRunner will need to take care of forbidding
+ // (or allowing) having two Games with the same name etc.
+ {
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ throw new ArgumentException("param should not be null or blank", nameof(value));
+ }
+ name = value;
+ }
+ }
+ private string name;
+
+ ///
+ /// references the position in list of the current player, for a given game.
+ ///
+ private int nextIndex;
+
+ ///
+ /// the turns that have been done so far
+ ///
+ private readonly List turns;
+
+ ///
+ /// get a READ ONLY enumerable of all turns belonging to this game
+ ///
+ /// a readonly enumerable of all this game's turns
+ public IEnumerable GetHistory() => turns.AsEnumerable();
+
+ ///
+ /// the game's player manager, doing CRUD on players and switching whose turn it is
+ ///
+ private readonly IManager playerManager;
+
+ ///
+ /// the group of dice used for this game
+ ///
+ public IEnumerable> Dice => dice;
+ private readonly IEnumerable> dice;
+
+ ///
+ /// constructs a Game with its own history of Turns.
+ /// If is null, starts a new history
+ ///
+ /// the name of the game 😎
+ /// the turns that have been done so far
+ /// the game's player manager, doing CRUD on players and switching whose turn it is
+ /// the group of dice used for this game
+ public Game(string name, IManager playerManager, IEnumerable> dice, IEnumerable turns)
+ {
+ Name = name;
+ this.turns = turns is null ? new List() : turns.ToList();
+ this.playerManager = playerManager;
+ this.dice = dice;
+ this.nextIndex = 0;
+ }
+
+ ///
+ /// constructs a Game with no history of turns.
+ ///
+ /// the name of the game 😎
+ /// the game's player manager, doing CRUD on players and switching whose turn it is
+ /// the group of dice used for this game
+ public Game(string name, IManager playerManager, IEnumerable> dice)
+ : this(name, playerManager, dice, null)
+ { }
+
+ ///
+ /// performs a Turn, marks this Game as "started", and logs that Turn
+ ///
+ /// the player whose turn it is
+ public void PerformTurn(Player player)
+ {
+ Turn turn = Turn.CreateWithDefaultTime(
+ player,
+ ThrowAll()
+ );
+ AddTurn(turn);
+ }
+
+
+ private void AddTurn(Turn turn)
+ {
+ if (!(turns.Contains(turn)))
+ {
+ turns.Add(turn);
+ }
+ }
+
+ ///
+ /// finds and returns the player whose turn it is
+ ///
+ ///
+ ///
+ public Player GetWhoPlaysNow()
+ {
+ if (!playerManager.GetAll().Any())
+ {
+ throw new MemberAccessException("you are exploring an empty collection\nthis should not have happened");
+ }
+ return playerManager.GetAll().ElementAt(nextIndex);
+ }
+
+ ///
+ /// this feels very dirty
+ ///
+ /// the current player
+ ///
+ ///
+ ///
+ public void PrepareNextPlayer(Player current)
+ {
+ if (!playerManager.GetAll().Any())
+ {
+ throw new MemberAccessException("you are exploring an empty collection\nthis should not have happened");
+ }
+ if (current == null)
+ {
+ throw new ArgumentNullException(nameof(current), "param should not be null");
+ }
+ if (!playerManager.GetAll().Contains(current))
+ {
+ throw new ArgumentException("param could not be found in this collection\n did you forget to add it?", nameof(current));
+ }
+ if (playerManager.GetAll().Last() == current)
+ {
+ // if we've reached the last player, we need the index to loop back around
+ nextIndex = 0;
+ }
+ else
+ {
+ // else we can just move up by one from the current index
+ nextIndex++;
+ }
+ }
+
+ ///
+ /// throws all the Dice in FavGroup and returns a list of their Faces
+ ///
+ /// list of AbstractDieFaces after a throw
+ private Dictionary, AbstractDieFace> ThrowAll()
+ {
+ Dictionary, AbstractDieFace> faces = new();
+ foreach (AbstractDie die in dice)
+ {
+ faces.Add(die, die.GetRandomFace());
+ }
+ return faces;
+ }
+
+ public Player AddPlayerToGame(Player player)
+ {
+ return playerManager.Add(player);
+ }
+
+ public IEnumerable GetPlayersFromGame()
+ {
+ return playerManager.GetAll();
+ }
+
+ public Player UpdatePlayerInGame(Player oldPlayer, Player newPlayer)
+ {
+ return playerManager.Update(oldPlayer, newPlayer);
+ }
+
+ public void RemovePlayerFromGame(Player player)
+ {
+ playerManager.Remove(player);
+ }
+
+ ///
+ /// represents a Game in string format
+ ///
+ /// a Game in string format
+ public override string ToString()
+ {
+ StringBuilder sb = new();
+ sb.Append($"Game: {Name}");
+
+ sb.Append("\nPlayers:");
+ foreach (Player player in GetPlayersFromGame())
+ {
+ sb.Append($" {player.ToString()}");
+ }
+
+ sb.Append($"\nNext: {GetWhoPlaysNow()}");
+
+ sb.Append("\nLog:\n");
+ foreach (Turn turn in this.turns)
+ {
+ sb.Append($"\t{turn.ToString()}\n");
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/Sources/Model/Games/Turn.cs b/Sources/Model/Games/Turn.cs
index 49bf381..ea202d4 100644
--- a/Sources/Model/Games/Turn.cs
+++ b/Sources/Model/Games/Turn.cs
@@ -17,7 +17,7 @@ namespace Model.Games
/// Two turns are equal if they are litterally the same instance in RAM
/// (default behaviors Equals() and GetHashCode())
///
- public class Turn
+ public sealed class Turn : IEquatable
{
///
@@ -115,5 +115,27 @@ namespace Model.Games
return sb.ToString();
}
+
+ public bool Equals(Turn other)
+ {
+ return Player.Equals(other.Player)
+ && When.Equals(other.When)
+ && DiceNFaces.SequenceEqual(other.DiceNFaces);
+
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is not Turn)
+ {
+ return false;
+ }
+ return Equals(obj as Turn);
+ }
+
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(Player, When, DiceNFaces);
+ }
}
}
diff --git a/Sources/Tests/Model_UTs/GameTest.cs b/Sources/Tests/Model_UTs/GameTest.cs
index 5a18c07..db90cb6 100644
--- a/Sources/Tests/Model_UTs/GameTest.cs
+++ b/Sources/Tests/Model_UTs/GameTest.cs
@@ -149,9 +149,6 @@ namespace Tests.Model_UTs
int n = 5;
- IEnumerable players = game.GetPlayersFromGame();
- Debug.WriteLine(players);
-
Player currentPlayer;
for (int i = 0; i < n; i++)
{
diff --git a/Sources/Tests/Model_UTs/PlayerTest.cs b/Sources/Tests/Model_UTs/PlayerTest.cs
index baaf009..e0c14ee 100644
--- a/Sources/Tests/Model_UTs/PlayerTest.cs
+++ b/Sources/Tests/Model_UTs/PlayerTest.cs
@@ -79,16 +79,6 @@ namespace Tests.Model_UTs
Assert.Equal(expected, actual);
}
- class Point
- {
- public int X { get; set; }
- public int Y { get; set; }
- public Point(int x, int y)
- {
- X = x; Y = y;
- }
- }
-
[Fact]
public void TestEqualsFalseIfNotPlayer()
{
diff --git a/Sources/Tests/Model_UTs/Point.cs b/Sources/Tests/Model_UTs/Point.cs
new file mode 100644
index 0000000..a9274f7
--- /dev/null
+++ b/Sources/Tests/Model_UTs/Point.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tests.Model_UTs
+{
+ public class Point
+ {
+ public int X { get; private set; }
+ public int Y { get; private set; }
+ public Point(int x, int y)
+ {
+ X = x; Y = y;
+ }
+
+ }
+}
diff --git a/Sources/Tests/Model_UTs/TurnTest.cs b/Sources/Tests/Model_UTs/TurnTest.cs
index 7b3927f..b9e8310 100644
--- a/Sources/Tests/Model_UTs/TurnTest.cs
+++ b/Sources/Tests/Model_UTs/TurnTest.cs
@@ -13,7 +13,9 @@ namespace Tests.Model_UTs
public class TurnTest
{
- private readonly Dictionary, AbstractDieFace> DICE_N_FACES;
+ private readonly Dictionary, AbstractDieFace> DICE_N_FACES_1;
+ private readonly Dictionary, AbstractDieFace> DICE_N_FACES_2;
+
private static readonly AbstractDieFace FACE_ONE = new NumberDieFace(1);
private static readonly AbstractDieFace FACE_TWO = new NumberDieFace(12);
private static readonly AbstractDieFace FACE_THREE = new ImageDieFace(54);
@@ -57,13 +59,19 @@ namespace Tests.Model_UTs
public TurnTest()
{
- DICE_N_FACES = new()
+ DICE_N_FACES_1 = new()
{
{ NUM1, FACE_ONE },
{ NUM2, FACE_TWO },
{ IMG1, FACE_THREE },
{ CLR1, FACE_FOUR }
};
+ DICE_N_FACES_2 = new()
+ {
+ { NUM1, FACE_TWO },
+ { IMG1, FACE_THREE },
+ { CLR1, FACE_FOUR }
+ };
}
@@ -77,7 +85,7 @@ namespace Tests.Model_UTs
Assert.NotEqual(DateTimeKind.Utc, dateTime.Kind);
// Act
- Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES);
+ Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1);
// Assert
Assert.Equal(DateTimeKind.Utc, turn.When.Kind);
@@ -95,7 +103,7 @@ namespace Tests.Model_UTs
Assert.Equal(DateTimeKind.Utc, dateTime.Kind);
// Act
- Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES);
+ Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1);
// Assert
Assert.Equal(DateTimeKind.Utc, turn.When.Kind);
@@ -110,7 +118,7 @@ namespace Tests.Model_UTs
DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc);
// Act
- void action() => Turn.CreateWithSpecifiedTime(dateTime, null, DICE_N_FACES);
+ void action() => Turn.CreateWithSpecifiedTime(dateTime, null, DICE_N_FACES_1);
// Assert
Assert.Throws(action);
@@ -137,10 +145,10 @@ namespace Tests.Model_UTs
// Arrange
DateTime dateTime = new(year: 2018, month: 06, day: 15, hour: 16, minute: 30, second: 0, kind: DateTimeKind.Utc);
Player player = new("Chucky");
- DICE_N_FACES.Clear();
+ DICE_N_FACES_1.Clear();
// Act
- void action() => Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES);
+ void action() => Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1);
// Assert
Assert.Throws(action);
@@ -155,7 +163,7 @@ namespace Tests.Model_UTs
Player player = new("Chloe");
// Act
- Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES);
+ Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1);
// Assert
Assert.Equal(DateTimeKind.Utc, turn.When.Kind);
@@ -178,7 +186,7 @@ namespace Tests.Model_UTs
+ FACE_THREE.ToString() + " "
+ FACE_FOUR.ToString();
- Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES);
+ Turn turn = Turn.CreateWithSpecifiedTime(dateTime, player, DICE_N_FACES_1);
// Act
string actual = turn.ToString();
@@ -195,11 +203,120 @@ namespace Tests.Model_UTs
Player player = new("Erika");
// Act
- Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES);
- IEnumerable, AbstractDieFace>> expected = DICE_N_FACES.AsEnumerable();
+ Turn turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1);
+ IEnumerable, AbstractDieFace>> expected = DICE_N_FACES_1.AsEnumerable();
// Assert
Assert.Equal(expected, turn.DiceNFaces);
+ }
+
+ [Fact]
+ public void TestEqualsFalseIfNotTurn()
+ {
+ // Arrange
+ Point point;
+ Turn turn;
+ Player player = new("Freddie");
+
+ // Act
+ point = new(1, 2);
+ turn = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1);
+
+ // Assert
+ Assert.False(point.Equals(turn));
+ Assert.False(point.GetHashCode().Equals(turn.GetHashCode()));
+ Assert.False(turn.Equals(point));
+ Assert.False(turn.GetHashCode().Equals(point.GetHashCode()));
+ }
+
+ [Fact]
+ public void TestGoesThruToSecondMethodIfObjIsTypeTurn()
+ {
+ // Arrange
+ Object t1;
+ Turn t2;
+ Player player1 = new Player("Marvin");
+ Player player2 = new Player("Noah");
+
+ // Act
+ t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_1);
+ t2 = Turn.CreateWithDefaultTime(player2, DICE_N_FACES_2);
+
+ // Assert
+ Assert.False(t1.Equals(t2));
+ Assert.False(t1.GetHashCode().Equals(t2.GetHashCode()));
+ Assert.False(t2.Equals(t1));
+ Assert.False(t2.GetHashCode().Equals(t1.GetHashCode()));
+ }
+
+
+ [Fact]
+ public void TestEqualsFalseIfNotSamePlayer()
+ {
+ // Arrange
+ Player player1= new("Panama");
+ Player player2= new("Clyde");
+
+ // Act
+ Turn t1 = Turn.CreateWithDefaultTime(player1, DICE_N_FACES_2);
+ Turn t2 = Turn.CreateWithDefaultTime(player2, DICE_N_FACES_2);
+
+ // Assert
+ Assert.False(t1.Equals(t2));
+ Assert.False(t1.GetHashCode().Equals(t2.GetHashCode()));
+ Assert.False(t2.Equals(t1));
+ Assert.False(t2.GetHashCode().Equals(t1.GetHashCode()));
+ }
+
+ [Fact]
+ public void TestEqualsFalseIfNotSameTime()
+ {
+ // Arrange
+ Player player = new("Oscar");
+
+ // Act
+ Turn t1 = Turn.CreateWithSpecifiedTime(new DateTime(1994, 07, 10), player, DICE_N_FACES_1);
+ Turn t2 = Turn.CreateWithSpecifiedTime(new DateTime(1991, 08, 20), player, DICE_N_FACES_1);
+
+ // Assert
+ Assert.False(t1.Equals(t2));
+ Assert.False(t1.GetHashCode().Equals(t2.GetHashCode()));
+ Assert.False(t2.Equals(t1));
+ Assert.False(t2.GetHashCode().Equals(t1.GetHashCode()));
+ }
+
+ [Fact]
+ public void TestEqualsFalseIfNotSameDiceNFaces()
+ {
+ // Arrange
+ Player player = new("Django");
+
+ // Act
+ Turn t1 = Turn.CreateWithDefaultTime(player, DICE_N_FACES_1);
+ Turn t2 = Turn.CreateWithDefaultTime(player, DICE_N_FACES_2);
+
+ // Assert
+ Assert.False(t1.Equals(t2));
+ Assert.False(t1.GetHashCode().Equals(t2.GetHashCode()));
+ Assert.False(t2.Equals(t1));
+ Assert.False(t2.GetHashCode().Equals(t1.GetHashCode()));
+ }
+
+ [Fact]
+ public void TestEqualsTrueIfExactlySameProperties()
+ {
+ // Arrange
+ Player player = new("Elyse");
+
+ // Act
+ Turn t1 = Turn.CreateWithSpecifiedTime(new DateTime(1990, 04, 29), player, DICE_N_FACES_1);
+ Turn t2 = Turn.CreateWithSpecifiedTime(new DateTime(1990, 04, 29), player, DICE_N_FACES_1);
+
+ // Assert
+ Assert.True(t1.Equals(t2));
+ Assert.True(t1.GetHashCode().Equals(t2.GetHashCode()));
+ Assert.True(t2.Equals(t1));
+ Assert.True(t2.GetHashCode().Equals(t1.GetHashCode()));
}
}
}