/// <summary>
        /// Initializes a new instance of the <see cref="CooperationStrategyMatchupResult"/> class.
        /// </summary>
        /// <param name="strategyAResult">The result for strategy A.</param>
        /// <param name="strategyBResult">The result for strategy B.</param>
        public CooperationStrategyMatchupResult(
            CooperationStrategyResult strategyAResult, CooperationStrategyResult strategyBResult)
        {
            Requires.NotNull(strategyAResult, "strategyAResult");
            Requires.NotNull(strategyBResult, "strategyBResult");

            this.StrategyAResult = strategyAResult;
            this.StrategyBResult = strategyBResult;
        }
        public void ConstructorWithNullStrategyBChoiceThrowsArgumentNullException()
        {
            // Arrange
            var strategyAResult = new CooperationStrategyResult();
            CooperationStrategyResult nullStrategyBResult = null;

            // Act

            // Assert
            Assert.Throws<ArgumentNullException>(() => new CooperationStrategyMatchupResult(strategyAResult, nullStrategyBResult));
        }
        public void StrategyBChoiceReturnsStrategyAChoideASuppliedToConstructor()
        {
            var strategyAResult = new CooperationStrategyResult();
            var strategyBResult = new CooperationStrategyResult();

            // Act
            var matchupResult = new CooperationStrategyMatchupResult(strategyAResult, strategyBResult);

            // Assert
            Assert.Equal(strategyBResult, matchupResult.StrategyBResult);
        }
        public void EqualsWithEqualPayoffReturnsTrue()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { Payoff = CooperationChoicesPayoff.DefaultPayoffForDefectAndDefect };
            object equalCooperationStrategyResult = new CooperationStrategyResult { Payoff = CooperationChoicesPayoff.DefaultPayoffForDefectAndDefect };

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals(equalCooperationStrategyResult);

            // Assert
            Assert.True(objectsAreEqual);
        }
        public void EqualsWithEqualObjectReturnsTrue()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult();
            var equalCooperationStrategyResult = new CooperationStrategyResult();

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals((object)equalCooperationStrategyResult);

            // Assert
            Assert.True(objectsAreEqual);
        }
        public void EqualsWithEqualChoiceMadeReturnsTrue()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { ChoiceMade = CooperationChoice.Cooperate };
            object equalCooperationStrategyResult = new CooperationStrategyResult { ChoiceMade = CooperationChoice.Cooperate };

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals(equalCooperationStrategyResult);

            // Assert
            Assert.True(objectsAreEqual);
        }
        public void EqualsWithEqualStrategyReturnsTrue()
        {
            // Arrange
            var strategy = new NaiveCooperationStrategy();
            var cooperationStrategyResult = new CooperationStrategyResult { Strategy = strategy };
            object equalCooperationStrategyResult = new CooperationStrategyResult { Strategy = strategy };

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals(equalCooperationStrategyResult);

            // Assert
            Assert.True(objectsAreEqual);
        }
        public void GetHashCodeWithUnchangedNewInstancesReturnsEqualHashCodes()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult();
            var otherCooperationStrategyResult = new CooperationStrategyResult();

            // Act
            var hashCode = cooperationStrategyResult.GetHashCode();
            var otherHashCode = otherCooperationStrategyResult.GetHashCode();

            // Assert
            Assert.Equal(hashCode, otherHashCode);
        }
        public void PlayReturnsCorrectCooperationStrategyMatchupResultForStrategyB()
        {
            // Arrange
            var strategyA = new NaiveCooperationStrategy();
            var strategyB = new EvilCooperationStrategy();
            var cooperationChoicePayoff = new CooperationChoicesPayoff();
            var cooperationStrategyMatchup = new CooperationStrategyMatchup(strategyA, strategyB, cooperationChoicePayoff);

            // Act
            var cooperationStrategyMatchupResult = cooperationStrategyMatchup.Play();

            // Assert
            var correctCooperationStrategyResultForStrategyB = new CooperationStrategyResult
                                                                   {
                                                                       Strategy = strategyB,
                                                                       ChoiceMade = CooperationChoice.Defect,
                                                                       Payoff = CooperationChoicesPayoff.DefaultPayoffForDefectAndCooperate,
                                                                   };
            Assert.Equal(correctCooperationStrategyResultForStrategyB, cooperationStrategyMatchupResult.StrategyBResult);
        }
        public void GetHashCodeWithDifferentPayoffReturnsDifferentHashCodes()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { Payoff = CooperationChoicesPayoff.DefaultPayoffForCooperateAndDefect };
            var otherCooperationStrategyResult = new CooperationStrategyResult { Payoff = CooperationChoicesPayoff.DefaultPayoffForDefectAndCooperate };

            // Act
            var hashCode = cooperationStrategyResult.GetHashCode();
            var otherHashCode = otherCooperationStrategyResult.GetHashCode();

            // Assert
            Assert.NotEqual(hashCode, otherHashCode);
        }
        public void GetHashCodeWithDifferentCooperationStrategiesReturnsDifferentHashCodes()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { Strategy = new NaiveCooperationStrategy() };
            var otherCooperationStrategyResult = new CooperationStrategyResult { Strategy = new EvilCooperationStrategy() };

            // Act
            var hashCode = cooperationStrategyResult.GetHashCode();
            var otherHashCode = otherCooperationStrategyResult.GetHashCode();

            // Assert
            Assert.NotEqual(hashCode, otherHashCode);
        }
        public void GetHashCodeWithDifferentChoiceMadeReturnsDifferentHashCodes()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { ChoiceMade = CooperationChoice.Cooperate };
            var otherCooperationStrategyResult = new CooperationStrategyResult { ChoiceMade = CooperationChoice.Defect };

            // Act
            var hashCode = cooperationStrategyResult.GetHashCode();
            var otherHashCode = otherCooperationStrategyResult.GetHashCode();

            // Assert
            Assert.NotEqual(hashCode, otherHashCode);
        }
        public void EqualsWithUnequalCooperationStrategyResultInstancesReturnsFalse()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { Strategy = new NaiveCooperationStrategy() };
            var unequalCooperationStrategyResult = new CooperationStrategyResult { Strategy = new NaiveCooperationStrategy() };

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals(unequalCooperationStrategyResult);

            // Assert
            Assert.False(objectsAreEqual);
        }
        public void EqualsWithUnequalChoiceMadeReturnsFalse()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { ChoiceMade = CooperationChoice.Cooperate };
            var unequalCooperationStrategyResult = new CooperationStrategyResult { ChoiceMade = CooperationChoice.Defect };

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals(unequalCooperationStrategyResult);

            // Assert
            Assert.False(objectsAreEqual);
        }
        public void EqualsWithUnchangedNewObjectInstancesReturnsTrue()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult();
            var otherCooperationStrategyResult = new CooperationStrategyResult();

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals((object)otherCooperationStrategyResult);

            // Assert
            Assert.True(objectsAreEqual);
        }
        public void EqualsWithStrategyThatIsSameInstanceReturnsTrue()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult();

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals(cooperationStrategyResult);

            // Assert
            Assert.True(objectsAreEqual);
        }
        public void GetHashCodeWithEqualValuesReturnsEqualHashCodes()
        {
            // Arrange
            var strategy = new NaiveCooperationStrategy();
            var cooperationStrategyResult = new CooperationStrategyResult { Strategy = strategy, ChoiceMade = CooperationChoice.Defect, Payoff = CooperationChoicesPayoff.DefaultPayoffForDefectAndDefect };
            var otherCooperationStrategyResult = new CooperationStrategyResult { Strategy = strategy, ChoiceMade = CooperationChoice.Defect, Payoff = CooperationChoicesPayoff.DefaultPayoffForDefectAndDefect };

            // Act
            var hashCode = cooperationStrategyResult.GetHashCode();
            var otherHashCode = otherCooperationStrategyResult.GetHashCode();

            // Assert
            Assert.Equal(hashCode, otherHashCode);
        }
        public void GetHashCodeWithNullStrategyDoesNotThrowException()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult { Strategy = null };

            // Act
            cooperationStrategyResult.GetHashCode();

            // Assert
        }
        public void PlayWithLastMatchupResultReturnsCorrectCooperationStrategyMatchupResultForStrategyB()
        {
            // Arrange
            var strategyA = new TitForTatCooperationStrategy();
            var strategyB = new TitForTatCooperationStrategy();
            var cooperationChoicePayoff = new CooperationChoicesPayoff();
            var cooperationStrategyMatchup = new CooperationStrategyMatchup(strategyA, strategyB, cooperationChoicePayoff);
            var lastMatchupResult = new CooperationStrategyMatchupResult(
                new CooperationStrategyResult
                    {
                        Strategy = strategyA,
                        ChoiceMade = CooperationChoice.Cooperate,
                        Payoff =
                            cooperationChoicePayoff.Calculate(
                                CooperationChoice.Cooperate, CooperationChoice.Cooperate),
                    },
                new CooperationStrategyResult
                    {
                        Strategy = strategyB,
                        ChoiceMade = CooperationChoice.Cooperate,
                        Payoff =
                            cooperationChoicePayoff.Calculate(
                                CooperationChoice.Cooperate, CooperationChoice.Cooperate),
                    });

            // Act
            var cooperationStrategyMatchupResult = cooperationStrategyMatchup.Play(lastMatchupResult);

            // Assert
            var correctCooperationStrategyResultForStrategyB = new CooperationStrategyResult
                                                                   {
                                                                       Strategy = strategyB,
                                                                       ChoiceMade = CooperationChoice.Cooperate,
                                                                       Payoff = CooperationChoicesPayoff.DefaultPayoffForCooperateAndCooperate
                                                                   };
            Assert.Equal(correctCooperationStrategyResultForStrategyB, cooperationStrategyMatchupResult.StrategyBResult);
        }
        public void EqualsWithNullObjectReturnsFalse()
        {
            // Arrange
            var cooperationStrategyResult = new CooperationStrategyResult();
            CooperationStrategyResult comparisonCooperationStrategyResult = null;

            // Act
            var objectsAreEqual = cooperationStrategyResult.Equals((object)comparisonCooperationStrategyResult);

            // Assert
            Assert.False(objectsAreEqual);
        }